diff options
Diffstat (limited to 'widget/src/checkbox.rs')
| -rw-r--r-- | widget/src/checkbox.rs | 101 | 
1 files changed, 59 insertions, 42 deletions
| diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 15fb8f58..225c316d 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -39,6 +39,7 @@ pub struct Checkbox<      Renderer = crate::Renderer,  > where      Renderer: text::Renderer, +    Theme: Catalog,  {      is_checked: bool,      on_toggle: Option<Box<dyn Fn(bool) -> Message + 'a>>, @@ -51,12 +52,13 @@ pub struct Checkbox<      text_shaping: text::Shaping,      font: Option<Renderer::Font>,      icon: Icon<Renderer::Font>, -    style: Style<'a, Theme>, +    class: Theme::Class<'a>,  }  impl<'a, Message, Theme, Renderer> Checkbox<'a, Message, Theme, Renderer>  where      Renderer: text::Renderer, +    Theme: Catalog,  {      /// The default size of a [`Checkbox`].      const DEFAULT_SIZE: f32 = 16.0; @@ -69,10 +71,7 @@ where      /// It expects:      ///   * the label of the [`Checkbox`]      ///   * a boolean describing whether the [`Checkbox`] is checked or not -    pub fn new(label: impl Into<String>, is_checked: bool) -> Self -    where -        Theme: DefaultStyle + 'a, -    { +    pub fn new(label: impl Into<String>, is_checked: bool) -> Self {          Checkbox {              is_checked,              on_toggle: None, @@ -91,7 +90,7 @@ where                  line_height: text::LineHeight::default(),                  shaping: text::Shaping::Basic,              }, -            style: Box::new(Theme::default_style), +            class: Theme::default(),          }      } @@ -174,11 +173,20 @@ where      }      /// Sets the style of the [`Checkbox`]. -    pub fn style( -        mut self, -        style: impl Fn(&Theme, Status) -> Appearance + 'a, -    ) -> Self { -        self.style = Box::new(style); +    #[must_use] +    pub fn style(mut self, style: impl Fn(&Theme, Status) -> Style + 'a) -> Self +    where +        Theme::Class<'a>: From<StyleFn<'a, Theme>>, +    { +        self.class = (Box::new(style) as StyleFn<'a, Theme>).into(); +        self +    } + +    /// Sets the style class of the [`Checkbox`]. +    #[cfg(feature = "advanced")] +    #[must_use] +    pub fn class(mut self, class: impl Into<Theme::Class<'a>>) -> Self { +        self.class = class.into();          self      }  } @@ -187,6 +195,7 @@ impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>      for Checkbox<'a, Message, Theme, Renderer>  where      Renderer: text::Renderer, +    Theme: Catalog,  {      fn tag(&self) -> tree::Tag {          tree::Tag::of::<widget::text::State<Renderer::Paragraph>>() @@ -285,7 +294,7 @@ where          tree: &Tree,          renderer: &mut Renderer,          theme: &Theme, -        style: &renderer::Style, +        defaults: &renderer::Style,          layout: Layout<'_>,          cursor: mouse::Cursor,          viewport: &Rectangle, @@ -304,7 +313,7 @@ where              Status::Active { is_checked }          }; -        let appearance = (self.style)(theme, status); +        let style = theme.style(&self.class, status);          {              let layout = children.next().unwrap(); @@ -313,10 +322,10 @@ where              renderer.fill_quad(                  renderer::Quad {                      bounds, -                    border: appearance.border, +                    border: style.border,                      ..renderer::Quad::default()                  }, -                appearance.background, +                style.background,              );              let Icon { @@ -331,7 +340,7 @@ where              if self.is_checked {                  renderer.fill_text(                      text::Text { -                        content: &code_point.to_string(), +                        content: code_point.to_string(),                          font: *font,                          size,                          line_height: *line_height, @@ -341,7 +350,7 @@ where                          shaping: *shaping,                      },                      bounds.center(), -                    appearance.icon_color, +                    style.icon_color,                      *viewport,                  );              } @@ -352,11 +361,11 @@ where              crate::text::draw(                  renderer, -                style, +                defaults,                  label_layout,                  tree.state.downcast_ref(), -                crate::text::Appearance { -                    color: appearance.text_color, +                crate::text::Style { +                    color: style.text_color,                  },                  viewport,              ); @@ -368,7 +377,7 @@ impl<'a, Message, Theme, Renderer> From<Checkbox<'a, Message, Theme, Renderer>>      for Element<'a, Message, Theme, Renderer>  where      Message: 'a, -    Theme: 'a, +    Theme: 'a + Catalog,      Renderer: 'a + text::Renderer,  {      fn from( @@ -413,9 +422,9 @@ pub enum Status {      },  } -/// The appearance of a checkbox. +/// The style of a checkbox.  #[derive(Debug, Clone, Copy)] -pub struct Appearance { +pub struct Style {      /// The [`Background`] of the checkbox.      pub background: Background,      /// The icon [`Color`] of the checkbox. @@ -426,29 +435,37 @@ pub struct Appearance {      pub text_color: Option<Color>,  } -/// The style of a [`Checkbox`]. -pub type Style<'a, Theme> = Box<dyn Fn(&Theme, Status) -> Appearance + 'a>; +/// The theme catalog of a [`Checkbox`]. +pub trait Catalog: Sized { +    /// The item class of the [`Catalog`]. +    type Class<'a>; -/// The default style of a [`Checkbox`]. -pub trait DefaultStyle { -    /// Returns the default style of a [`Checkbox`]. -    fn default_style(&self, status: Status) -> Appearance; +    /// The default class produced by the [`Catalog`]. +    fn default<'a>() -> Self::Class<'a>; + +    /// The [`Style`] of a class with the given status. +    fn style(&self, class: &Self::Class<'_>, status: Status) -> Style;  } -impl DefaultStyle for Theme { -    fn default_style(&self, status: Status) -> Appearance { -        primary(self, status) +/// A styling function for a [`Checkbox`]. +/// +/// This is just a boxed closure: `Fn(&Theme, Status) -> Style`. +pub type StyleFn<'a, Theme> = Box<dyn Fn(&Theme, Status) -> Style + 'a>; + +impl Catalog for Theme { +    type Class<'a> = StyleFn<'a, Self>; + +    fn default<'a>() -> Self::Class<'a> { +        Box::new(primary)      } -} -impl DefaultStyle for Appearance { -    fn default_style(&self, _status: Status) -> Appearance { -        *self +    fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { +        class(self, status)      }  }  /// A primary checkbox; denoting a main toggle. -pub fn primary(theme: &Theme, status: Status) -> Appearance { +pub fn primary(theme: &Theme, status: Status) -> Style {      let palette = theme.extended_palette();      match status { @@ -474,7 +491,7 @@ pub fn primary(theme: &Theme, status: Status) -> Appearance {  }  /// A secondary checkbox; denoting a complementary toggle. -pub fn secondary(theme: &Theme, status: Status) -> Appearance { +pub fn secondary(theme: &Theme, status: Status) -> Style {      let palette = theme.extended_palette();      match status { @@ -500,7 +517,7 @@ pub fn secondary(theme: &Theme, status: Status) -> Appearance {  }  /// A success checkbox; denoting a positive toggle. -pub fn success(theme: &Theme, status: Status) -> Appearance { +pub fn success(theme: &Theme, status: Status) -> Style {      let palette = theme.extended_palette();      match status { @@ -526,7 +543,7 @@ pub fn success(theme: &Theme, status: Status) -> Appearance {  }  /// A danger checkbox; denoting a negaive toggle. -pub fn danger(theme: &Theme, status: Status) -> Appearance { +pub fn danger(theme: &Theme, status: Status) -> Style {      let palette = theme.extended_palette();      match status { @@ -556,8 +573,8 @@ fn styled(      base: palette::Pair,      accent: palette::Pair,      is_checked: bool, -) -> Appearance { -    Appearance { +) -> Style { +    Style {          background: Background::Color(if is_checked {              accent.color          } else { | 
