diff options
| author | 2024-03-06 15:20:10 +0100 | |
|---|---|---|
| committer | 2024-03-06 15:20:17 +0100 | |
| commit | 68c8f23f02a55373db728b115c3a4360669e2b80 (patch) | |
| tree | 381460c9e47ea94c9b9614c6f4f192df7ac5abe7 /widget | |
| parent | 69bc1df252382a662228c8b0da6f60358e90f376 (diff) | |
| download | iced-68c8f23f02a55373db728b115c3a4360669e2b80.tar.gz iced-68c8f23f02a55373db728b115c3a4360669e2b80.tar.bz2 iced-68c8f23f02a55373db728b115c3a4360669e2b80.zip | |
Simplify theming for `TextEditor` widget
Diffstat (limited to '')
| -rw-r--r-- | widget/src/helpers.rs | 2 | ||||
| -rw-r--r-- | widget/src/text_editor.rs | 123 | 
2 files changed, 105 insertions, 20 deletions
| diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 60e7d34f..8dc2e60f 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -224,7 +224,7 @@ pub fn text_editor<Message, Theme, Renderer>(  ) -> TextEditor<'_, core::text::highlighter::PlainText, Message, Theme, Renderer>  where      Message: Clone, -    Theme: text_editor::StyleSheet, +    Theme: text_editor::Style,      Renderer: core::text::Renderer,  {      TextEditor::new(content) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index bad3ef4d..91670228 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -11,15 +11,16 @@ use crate::core::text::highlighter::{self, Highlighter};  use crate::core::text::{self, LineHeight};  use crate::core::widget::{self, Widget};  use crate::core::{ -    Element, Length, Padding, Pixels, Rectangle, Shell, Size, Vector, +    Background, Border, Color, Element, Length, Padding, Pixels, Rectangle, +    Shell, Size, Vector,  }; +use crate::style::Theme;  use std::cell::RefCell;  use std::fmt;  use std::ops::DerefMut;  use std::sync::Arc; -pub use crate::style::text_editor::{Appearance, StyleSheet};  pub use text::editor::{Action, Edit, Motion};  /// A multi-line text input. @@ -32,7 +33,6 @@ pub struct TextEditor<      Renderer = crate::Renderer,  > where      Highlighter: text::Highlighter, -    Theme: StyleSheet,      Renderer: text::Renderer,  {      content: &'a Content<Renderer>, @@ -42,7 +42,7 @@ pub struct TextEditor<      width: Length,      height: Length,      padding: Padding, -    style: Theme::Style, +    style: fn(&Theme, Status) -> Appearance,      on_edit: Option<Box<dyn Fn(Action) -> Message + 'a>>,      highlighter_settings: Highlighter::Settings,      highlighter_format: fn( @@ -54,11 +54,13 @@ pub struct TextEditor<  impl<'a, Message, Theme, Renderer>      TextEditor<'a, highlighter::PlainText, Message, Theme, Renderer>  where -    Theme: StyleSheet,      Renderer: text::Renderer,  {      /// Creates new [`TextEditor`] with the given [`Content`]. -    pub fn new(content: &'a Content<Renderer>) -> Self { +    pub fn new(content: &'a Content<Renderer>) -> Self +    where +        Theme: Style, +    {          Self {              content,              font: None, @@ -67,7 +69,7 @@ where              width: Length::Fill,              height: Length::Shrink,              padding: Padding::new(5.0), -            style: Default::default(), +            style: Theme::style(),              on_edit: None,              highlighter_settings: (),              highlighter_format: |_highlight, _theme| { @@ -81,7 +83,6 @@ impl<'a, Highlighter, Message, Theme, Renderer>      TextEditor<'a, Highlighter, Message, Theme, Renderer>  where      Highlighter: text::Highlighter, -    Theme: StyleSheet,      Renderer: text::Renderer,  {      /// Sets the height of the [`TextEditor`]. @@ -142,8 +143,8 @@ where      }      /// Sets the style of the [`TextEditor`]. -    pub fn style(mut self, style: impl Into<Theme::Style>) -> Self { -        self.style = style.into(); +    pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self { +        self.style = style;          self      }  } @@ -306,7 +307,6 @@ impl<'a, Highlighter, Message, Theme, Renderer> Widget<Message, Theme, Renderer>      for TextEditor<'a, Highlighter, Message, Theme, Renderer>  where      Highlighter: text::Highlighter, -    Theme: StyleSheet,      Renderer: text::Renderer,  {      fn tag(&self) -> widget::tree::Tag { @@ -496,16 +496,18 @@ where          let is_disabled = self.on_edit.is_none();          let is_mouse_over = cursor.is_over(bounds); -        let appearance = if is_disabled { -            theme.disabled(&self.style) +        let status = if is_disabled { +            Status::Disabled          } else if state.is_focused { -            theme.focused(&self.style) +            Status::Focused          } else if is_mouse_over { -            theme.hovered(&self.style) +            Status::Hovered          } else { -            theme.active(&self.style) +            Status::Active          }; +        let appearance = (self.style)(theme, status); +          renderer.fill_quad(              renderer::Quad {                  bounds, @@ -551,7 +553,7 @@ where                                  },                                  ..renderer::Quad::default()                              }, -                            theme.value_color(&self.style), +                            appearance.value,                          );                      }                  } @@ -564,7 +566,7 @@ where                                  bounds: range,                                  ..renderer::Quad::default()                              }, -                            theme.selection_color(&self.style), +                            appearance.selection,                          );                      }                  } @@ -600,7 +602,7 @@ impl<'a, Highlighter, Message, Theme, Renderer>  where      Highlighter: text::Highlighter,      Message: 'a, -    Theme: StyleSheet + 'a, +    Theme: 'a,      Renderer: text::Renderer,  {      fn from( @@ -776,3 +778,86 @@ mod platform {          }      }  } + +/// The possible status of a [`TextInput`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Status { +    /// The [`TextInput`] can be interacted with. +    Active, +    /// The [`TextInput`] is being hovered. +    Hovered, +    /// The [`TextInput`] is focused. +    Focused, +    /// The [`TextInput`] cannot be interacted with. +    Disabled, +} + +/// The appearance of a text input. +#[derive(Debug, Clone, Copy)] +pub struct Appearance { +    /// The [`Background`] of the text input. +    pub background: Background, +    /// The [`Border`] of the text input. +    pub border: Border, +    /// The [`Color`] of the icon of the text input. +    pub icon: Color, +    /// The [`Color`] of the placeholder of the text input. +    pub placeholder: Color, +    /// The [`Color`] of the value of the text input. +    pub value: Color, +    /// The [`Color`] of the selection of the text input. +    pub selection: Color, +} + +/// The definiton of the default style of a [`TextInput`]. +pub trait Style { +    /// Returns the default style of a [`TextInput`]. +    fn style() -> fn(&Self, Status) -> Appearance; +} + +impl Style for Theme { +    fn style() -> fn(&Self, Status) -> Appearance { +        default +    } +} + +/// The default style of a [`TextInput`]. +pub fn default(theme: &Theme, status: Status) -> Appearance { +    let palette = theme.extended_palette(); + +    let active = Appearance { +        background: Background::Color(palette.background.base.color), +        border: Border { +            radius: 2.0.into(), +            width: 1.0, +            color: palette.background.strong.color, +        }, +        icon: palette.background.weak.text, +        placeholder: palette.background.strong.color, +        value: palette.background.base.text, +        selection: palette.primary.weak.color, +    }; + +    match status { +        Status::Active => active, +        Status::Hovered => Appearance { +            border: Border { +                color: palette.background.base.text, +                ..active.border +            }, +            ..active +        }, +        Status::Focused => Appearance { +            border: Border { +                color: palette.primary.strong.color, +                ..active.border +            }, +            ..active +        }, +        Status::Disabled => Appearance { +            background: Background::Color(palette.background.weak.color), +            value: active.placeholder, +            ..active +        }, +    } +} | 
