Wire up styling to Button in iced_native

This commit is contained in:
Héctor Ramón Jiménez 2021-10-18 16:02:30 +07:00
parent 95acc1deb8
commit 3140cdc4ba
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
12 changed files with 55 additions and 96 deletions

View file

@ -834,12 +834,12 @@ impl Controls {
Text::new(if is_playing { "Pause" } else { "Play" }), Text::new(if is_playing { "Pause" } else { "Play" }),
) )
.on_press(Message::TogglePlayback) .on_press(Message::TogglePlayback)
.style(style::Button), .style(&style::Button),
) )
.push( .push(
Button::new(&mut self.next_button, Text::new("Next")) Button::new(&mut self.next_button, Text::new("Next"))
.on_press(Message::Next) .on_press(Message::Next)
.style(style::Button), .style(&style::Button),
); );
let speed_controls = Row::new() let speed_controls = Row::new()
@ -883,7 +883,7 @@ impl Controls {
.push( .push(
Button::new(&mut self.clear_button, Text::new("Clear")) Button::new(&mut self.clear_button, Text::new("Clear"))
.on_press(Message::Clear) .on_press(Message::Clear)
.style(style::Clear), .style(&style::Clear),
) )
.into() .into()
} }

View file

@ -158,7 +158,7 @@ impl Application for Example {
let pin_button = let pin_button =
Button::new(&mut pane.pin_button, Text::new(text).size(14)) Button::new(&mut pane.pin_button, Text::new(text).size(14))
.on_press(Message::TogglePin(id)) .on_press(Message::TogglePin(id))
.style(style::Button::Pin) .style(&style::Button::Pin)
.padding(3); .padding(3);
let title = Row::with_children(vec![ let title = Row::with_children(vec![
@ -316,13 +316,13 @@ impl Content {
split_horizontally, split_horizontally,
"Split horizontally", "Split horizontally",
Message::Split(pane_grid::Axis::Horizontal, pane), Message::Split(pane_grid::Axis::Horizontal, pane),
style::Button::Primary, &style::Button::Primary,
)) ))
.push(button( .push(button(
split_vertically, split_vertically,
"Split vertically", "Split vertically",
Message::Split(pane_grid::Axis::Vertical, pane), Message::Split(pane_grid::Axis::Vertical, pane),
style::Button::Primary, &style::Button::Primary,
)); ));
if total_panes > 1 && !is_pinned { if total_panes > 1 && !is_pinned {
@ -330,7 +330,7 @@ impl Content {
close, close,
"Close", "Close",
Message::Close(pane), Message::Close(pane),
style::Button::Destructive, &style::Button::Destructive,
)); ));
} }
@ -364,7 +364,7 @@ impl Controls {
) -> Element<Message> { ) -> Element<Message> {
let mut button = let mut button =
Button::new(&mut self.close, Text::new("Close").size(14)) Button::new(&mut self.close, Text::new("Close").size(14))
.style(style::Button::Control) .style(&style::Button::Control)
.padding(3); .padding(3);
if total_panes > 1 && !is_pinned { if total_panes > 1 && !is_pinned {
button = button.on_press(Message::Close(pane)); button = button.on_press(Message::Close(pane));

View file

@ -243,7 +243,7 @@ impl From<reqwest::Error> for Error {
fn button<'a>(state: &'a mut button::State, text: &str) -> Button<'a, Message> { fn button<'a>(state: &'a mut button::State, text: &str) -> Button<'a, Message> {
Button::new(state, Text::new(text)) Button::new(state, Text::new(text))
.padding(10) .padding(10)
.style(style::Button::Primary) .style(&style::Button::Primary)
} }
mod style { mod style {

View file

@ -112,15 +112,15 @@ impl Application for Stopwatch {
let toggle_button = { let toggle_button = {
let (label, color) = match self.state { let (label, color) = match self.state {
State::Idle => ("Start", style::Button::Primary), State::Idle => ("Start", &style::Button::Primary),
State::Ticking { .. } => ("Stop", style::Button::Destructive), State::Ticking { .. } => ("Stop", &style::Button::Destructive),
}; };
button(&mut self.toggle, label, color).on_press(Message::Toggle) button(&mut self.toggle, label, color).on_press(Message::Toggle)
}; };
let reset_button = let reset_button =
button(&mut self.reset, "Reset", style::Button::Secondary) button(&mut self.reset, "Reset", &style::Button::Secondary)
.on_press(Message::Reset); .on_press(Message::Reset);
let controls = Row::new() let controls = Row::new()

View file

@ -82,7 +82,7 @@ impl Sandbox for Styling {
let button = Button::new(&mut self.button, Text::new("Submit")) let button = Button::new(&mut self.button, Text::new("Submit"))
.padding(10) .padding(10)
.on_press(Message::ButtonPressed) .on_press(Message::ButtonPressed)
.style(self.theme); .style(self.theme.into());
let slider = Slider::new( let slider = Slider::new(
&mut self.slider, &mut self.slider,
@ -203,11 +203,11 @@ mod style {
} }
} }
impl From<Theme> for Box<dyn button::StyleSheet> { impl From<Theme> for &'static dyn button::StyleSheet {
fn from(theme: Theme) -> Self { fn from(theme: Theme) -> Self {
match theme { match theme {
Theme::Light => light::Button.into(), Theme::Light => &light::Button,
Theme::Dark => dark::Button.into(), Theme::Dark => &dark::Button,
} }
} }
} }

View file

@ -304,7 +304,7 @@ impl Task {
Button::new(edit_button, edit_icon()) Button::new(edit_button, edit_icon())
.on_press(TaskMessage::Edit) .on_press(TaskMessage::Edit)
.padding(10) .padding(10)
.style(style::Button::Icon), .style(&style::Button::Icon),
) )
.into() .into()
} }
@ -335,7 +335,7 @@ impl Task {
) )
.on_press(TaskMessage::Delete) .on_press(TaskMessage::Delete)
.padding(10) .padding(10)
.style(style::Button::Destructive), .style(&style::Button::Destructive),
) )
.into() .into()
} }
@ -363,8 +363,10 @@ impl Controls {
let filter_button = |state, label, filter, current_filter| { let filter_button = |state, label, filter, current_filter| {
let label = Text::new(label).size(16); let label = Text::new(label).size(16);
let button = let button =
Button::new(state, label).style(style::Button::Filter { Button::new(state, label).style(if filter == current_filter {
selected: filter == current_filter, &style::Button::FilterSelected
} else {
&style::Button::FilterActive
}); });
button.on_press(Message::FilterChanged(filter)).padding(8) button.on_press(Message::FilterChanged(filter)).padding(8)
@ -602,7 +604,8 @@ mod style {
use iced::{button, Background, Color, Vector}; use iced::{button, Background, Color, Vector};
pub enum Button { pub enum Button {
Filter { selected: bool }, FilterActive,
FilterSelected,
Icon, Icon,
Destructive, Destructive,
} }
@ -610,20 +613,15 @@ mod style {
impl button::StyleSheet for Button { impl button::StyleSheet for Button {
fn active(&self) -> button::Style { fn active(&self) -> button::Style {
match self { match self {
Button::Filter { selected } => { Button::FilterActive => button::Style::default(),
if *selected { Button::FilterSelected => button::Style {
button::Style { background: Some(Background::Color(Color::from_rgb(
background: Some(Background::Color( 0.2, 0.2, 0.7,
Color::from_rgb(0.2, 0.2, 0.7), ))),
)), border_radius: 10.0,
border_radius: 10.0, text_color: Color::WHITE,
text_color: Color::WHITE, ..button::Style::default()
..button::Style::default() },
}
} else {
button::Style::default()
}
}
Button::Icon => button::Style { Button::Icon => button::Style {
text_color: Color::from_rgb(0.5, 0.5, 0.5), text_color: Color::from_rgb(0.5, 0.5, 0.5),
..button::Style::default() ..button::Style::default()
@ -646,9 +644,7 @@ mod style {
button::Style { button::Style {
text_color: match self { text_color: match self {
Button::Icon => Color::from_rgb(0.2, 0.2, 0.7), Button::Icon => Color::from_rgb(0.2, 0.2, 0.7),
Button::Filter { selected } if !selected => { Button::FilterActive => Color::from_rgb(0.2, 0.2, 0.7),
Color::from_rgb(0.2, 0.2, 0.7)
}
_ => active.text_color, _ => active.text_color,
}, },
shadow_offset: active.shadow_offset + Vector::new(0.0, 1.0), shadow_offset: active.shadow_offset + Vector::new(0.0, 1.0),

View file

@ -64,7 +64,7 @@ impl Sandbox for Tour {
controls = controls.push( controls = controls.push(
button(back_button, "Back") button(back_button, "Back")
.on_press(Message::BackPressed) .on_press(Message::BackPressed)
.style(style::Button::Secondary), .style(&style::Button::Secondary),
); );
} }
@ -74,7 +74,7 @@ impl Sandbox for Tour {
controls = controls.push( controls = controls.push(
button(next_button, "Next") button(next_button, "Next")
.on_press(Message::NextPressed) .on_press(Message::NextPressed)
.style(style::Button::Primary), .style(&style::Button::Primary),
); );
} }

View file

@ -1,23 +1,12 @@
//! Allow your users to perform actions by pressing a button. //! Allow your users to perform actions by pressing a button.
//! //!
//! A [`Button`] has some local [`State`]. //! A [`Button`] has some local [`State`].
use crate::{Backend, Renderer}; use crate::Renderer;
use iced_native::Padding;
pub use iced_native::button::State; pub use iced_native::button::{State, Style, StyleSheet};
pub use iced_style::button::{Style, StyleSheet};
/// A widget that produces a message when clicked. /// A widget that produces a message when clicked.
/// ///
/// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`. /// This is an alias of an `iced_native` button with an `iced_wgpu::Renderer`.
pub type Button<'a, Message, Backend> = pub type Button<'a, Message, Backend> =
iced_native::Button<'a, Message, Renderer<Backend>>; iced_native::Button<'a, Message, Renderer<Backend>>;
impl<B> iced_native::button::Renderer for Renderer<B>
where
B: Backend,
{
const DEFAULT_PADDING: Padding = Padding::new(5);
type Style = Box<dyn StyleSheet>;
}

View file

@ -90,12 +90,6 @@ impl text_input::Renderer for Null {
} }
} }
impl button::Renderer for Null {
const DEFAULT_PADDING: Padding = Padding::ZERO;
type Style = ();
}
impl radio::Renderer for Null { impl radio::Renderer for Null {
type Style = (); type Style = ();

View file

@ -11,8 +11,11 @@ use crate::{
Clipboard, Element, Hasher, Layout, Length, Padding, Point, Rectangle, Clipboard, Element, Hasher, Layout, Length, Padding, Point, Rectangle,
Widget, Widget,
}; };
use std::hash::Hash; use std::hash::Hash;
pub use iced_style::button::{Style, StyleSheet};
/// A generic widget that produces a message when pressed. /// A generic widget that produces a message when pressed.
/// ///
/// ``` /// ```
@ -54,7 +57,7 @@ use std::hash::Hash;
/// } /// }
/// ``` /// ```
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
pub struct Button<'a, Message, Renderer: self::Renderer> { pub struct Button<'a, Message, Renderer> {
state: &'a mut State, state: &'a mut State,
content: Element<'a, Message, Renderer>, content: Element<'a, Message, Renderer>,
on_press: Option<Message>, on_press: Option<Message>,
@ -63,13 +66,13 @@ pub struct Button<'a, Message, Renderer: self::Renderer> {
min_width: u32, min_width: u32,
min_height: u32, min_height: u32,
padding: Padding, padding: Padding,
style: Renderer::Style, style: &'a dyn StyleSheet,
} }
impl<'a, Message, Renderer> Button<'a, Message, Renderer> impl<'a, Message, Renderer> Button<'a, Message, Renderer>
where where
Message: Clone, Message: Clone,
Renderer: self::Renderer, Renderer: crate::Renderer,
{ {
/// Creates a new [`Button`] with some local [`State`] and the given /// Creates a new [`Button`] with some local [`State`] and the given
/// content. /// content.
@ -85,8 +88,8 @@ where
height: Length::Shrink, height: Length::Shrink,
min_width: 0, min_width: 0,
min_height: 0, min_height: 0,
padding: Renderer::DEFAULT_PADDING, padding: Padding::new(5),
style: Renderer::Style::default(), style: Default::default(),
} }
} }
@ -128,8 +131,8 @@ where
} }
/// Sets the style of the [`Button`]. /// Sets the style of the [`Button`].
pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self { pub fn style(mut self, style: &'a dyn StyleSheet) -> Self {
self.style = style.into(); self.style = style;
self self
} }
} }
@ -151,7 +154,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
for Button<'a, Message, Renderer> for Button<'a, Message, Renderer>
where where
Message: Clone, Message: Clone,
Renderer: self::Renderer, Renderer: crate::Renderer,
{ {
fn width(&self) -> Length { fn width(&self) -> Length {
self.width self.width
@ -268,25 +271,11 @@ where
} }
} }
/// The renderer of a [`Button`].
///
/// Your [renderer] will need to implement this trait before being
/// able to use a [`Button`] in your user interface.
///
/// [renderer]: crate::renderer
pub trait Renderer: crate::Renderer + Sized {
/// The default padding of a [`Button`].
const DEFAULT_PADDING: Padding;
/// The style supported by this renderer.
type Style: Default;
}
impl<'a, Message, Renderer> From<Button<'a, Message, Renderer>> impl<'a, Message, Renderer> From<Button<'a, Message, Renderer>>
for Element<'a, Message, Renderer> for Element<'a, Message, Renderer>
where where
Message: 'a + Clone, Message: 'a + Clone,
Renderer: 'a + self::Renderer, Renderer: 'a + crate::Renderer,
{ {
fn from( fn from(
button: Button<'a, Message, Renderer>, button: Button<'a, Message, Renderer>,

View file

@ -80,17 +80,8 @@ impl StyleSheet for Default {
} }
} }
impl std::default::Default for Box<dyn StyleSheet> { impl std::default::Default for &'static dyn StyleSheet {
fn default() -> Self { fn default() -> Self {
Box::new(Default) &Default
}
}
impl<T> From<T> for Box<dyn StyleSheet>
where
T: 'static + StyleSheet,
{
fn from(style: T) -> Self {
Box::new(style)
} }
} }

View file

@ -51,7 +51,7 @@ pub struct Button<'a, Message> {
#[allow(dead_code)] #[allow(dead_code)]
min_height: u32, min_height: u32,
padding: Padding, padding: Padding,
style: Box<dyn StyleSheet>, style: &'a dyn StyleSheet,
} }
impl<'a, Message> Button<'a, Message> { impl<'a, Message> Button<'a, Message> {
@ -104,8 +104,8 @@ impl<'a, Message> Button<'a, Message> {
} }
/// Sets the style of the [`Button`]. /// Sets the style of the [`Button`].
pub fn style(mut self, style: impl Into<Box<dyn StyleSheet>>) -> Self { pub fn style(mut self, style: &'a dyn StyleSheet) -> Self {
self.style = style.into(); self.style = style;
self self
} }