diff options
| -rw-r--r-- | native/src/renderer/null.rs | 3 | ||||
| -rw-r--r-- | native/src/widget/container.rs | 2 | ||||
| -rw-r--r-- | native/src/widget/text_input.rs | 33 | ||||
| -rw-r--r-- | src/native.rs | 10 | ||||
| -rw-r--r-- | style/src/container.rs | 10 | ||||
| -rw-r--r-- | style/src/lib.rs | 1 | ||||
| -rw-r--r-- | style/src/text_input.rs | 72 | ||||
| -rw-r--r-- | wgpu/src/renderer/widget/text_input.rs | 32 | ||||
| -rw-r--r-- | wgpu/src/widget.rs | 1 | ||||
| -rw-r--r-- | wgpu/src/widget/text_input.rs | 15 | 
10 files changed, 143 insertions, 36 deletions
diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index 56d7e472..96aa132c 100644 --- a/native/src/renderer/null.rs +++ b/native/src/renderer/null.rs @@ -97,6 +97,8 @@ impl scrollable::Renderer for Null {  }  impl text_input::Renderer for Null { +    type Style = (); +      fn default_size(&self) -> u16 {          20      } @@ -124,6 +126,7 @@ impl text_input::Renderer for Null {          _placeholder: &str,          _value: &text_input::Value,          _state: &text_input::State, +        _style: &Self::Style,      ) -> Self::Output {      }  } diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs index 75c2d6b3..abe83264 100644 --- a/native/src/widget/container.rs +++ b/native/src/widget/container.rs @@ -94,7 +94,7 @@ where          self      } -    /// Sets the style the [`Container`]. +    /// Sets the style of the [`Container`].      ///      /// [`Container`]: struct.Container.html      pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self { diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index e2114f00..9952a9bf 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -15,8 +15,9 @@ use unicode_segmentation::UnicodeSegmentation;  ///  /// # Example  /// ``` -/// # use iced_native::{text_input, TextInput}; +/// # use iced_native::{text_input, renderer::Null};  /// # +/// # pub type TextInput<'a, Message> = iced_native::TextInput<'a, Message, Null>;  /// #[derive(Debug, Clone)]  /// enum Message {  ///     TextInputChanged(String), @@ -35,7 +36,7 @@ use unicode_segmentation::UnicodeSegmentation;  /// ```  ///   #[allow(missing_debug_implementations)] -pub struct TextInput<'a, Message> { +pub struct TextInput<'a, Message, Renderer: self::Renderer> {      state: &'a mut State,      placeholder: String,      value: Value, @@ -46,9 +47,10 @@ pub struct TextInput<'a, Message> {      size: Option<u16>,      on_change: Box<dyn Fn(String) -> Message>,      on_submit: Option<Message>, +    style: Renderer::Style,  } -impl<'a, Message> TextInput<'a, Message> { +impl<'a, Message, Renderer: self::Renderer> TextInput<'a, Message, Renderer> {      /// Creates a new [`TextInput`].      ///      /// It expects: @@ -79,6 +81,7 @@ impl<'a, Message> TextInput<'a, Message> {              size: None,              on_change: Box::new(on_change),              on_submit: None, +            style: Renderer::Style::default(),          }      } @@ -130,11 +133,20 @@ impl<'a, Message> TextInput<'a, Message> {          self.on_submit = Some(message);          self      } + +    /// Sets the style of the [`TextInput`]. +    /// +    /// [`TextInput`]: struct.TextInput.html +    pub fn style(mut self, style: impl Into<Renderer::Style>) -> Self { +        self.style = style.into(); +        self +    }  } -impl<'a, Message, Renderer> Widget<Message, Renderer> for TextInput<'a, Message> +impl<'a, Message, Renderer> Widget<Message, Renderer> +    for TextInput<'a, Message, Renderer>  where -    Renderer: self::Renderer, +    Renderer: 'static + self::Renderer,      Message: Clone + std::fmt::Debug,  {      fn width(&self) -> Length { @@ -359,6 +371,7 @@ where                  &self.placeholder,                  &self.value.secure(),                  &self.state, +                &self.style,              )          } else {              renderer.draw( @@ -369,6 +382,7 @@ where                  &self.placeholder,                  &self.value,                  &self.state, +                &self.style,              )          }      } @@ -376,7 +390,7 @@ where      fn hash_layout(&self, state: &mut Hasher) {          use std::{any::TypeId, hash::Hash}; -        TypeId::of::<TextInput<'static, ()>>().hash(state); +        TypeId::of::<TextInput<'static, (), Renderer>>().hash(state);          self.width.hash(state);          self.max_width.hash(state); @@ -393,6 +407,8 @@ where  /// [`TextInput`]: struct.TextInput.html  /// [renderer]: ../../renderer/index.html  pub trait Renderer: crate::Renderer + Sized { +    type Style: Default; +      /// Returns the default size of the text of the [`TextInput`].      ///      /// [`TextInput`]: struct.TextInput.html @@ -441,17 +457,18 @@ pub trait Renderer: crate::Renderer + Sized {          placeholder: &str,          value: &Value,          state: &State, +        style: &Self::Style,      ) -> Self::Output;  } -impl<'a, Message, Renderer> From<TextInput<'a, Message>> +impl<'a, Message, Renderer> From<TextInput<'a, Message, Renderer>>      for Element<'a, Message, Renderer>  where      Renderer: 'static + self::Renderer,      Message: 'static + Clone + std::fmt::Debug,  {      fn from( -        text_input: TextInput<'a, Message>, +        text_input: TextInput<'a, Message, Renderer>,      ) -> Element<'a, Message, Renderer> {          Element::new(text_input)      } diff --git a/src/native.rs b/src/native.rs index 54afee4b..3535ab6a 100644 --- a/src/native.rs +++ b/src/native.rs @@ -38,16 +38,6 @@ pub mod widget {          pub use iced_winit::scrollable::State;      } -    pub mod text_input { -        //! Ask for information using text fields. -        //! -        //! A [`TextInput`] has some local [`State`]. -        //! -        //! [`TextInput`]: struct.TextInput.html -        //! [`State`]: struct.State.html -        pub use iced_winit::text_input::{State, TextInput}; -    } -      pub mod slider {          //! Display an interactive selector of a single value from a range of          //! values. diff --git a/style/src/container.rs b/style/src/container.rs index 756ea0f9..a9cd3ccc 100644 --- a/style/src/container.rs +++ b/style/src/container.rs @@ -12,6 +12,12 @@ pub struct Style {  /// A set of rules that dictate the style of a container.  pub trait StyleSheet {      /// Produces the style of a container. +    fn style(&self) -> Style; +} + +struct Default; + +impl StyleSheet for Default {      fn style(&self) -> Style {          Style {              text_color: None, @@ -21,10 +27,6 @@ pub trait StyleSheet {      }  } -struct Default; - -impl StyleSheet for Default {} -  impl std::default::Default for Box<dyn StyleSheet> {      fn default() -> Self {          Box::new(Default) diff --git a/style/src/lib.rs b/style/src/lib.rs index c6f34301..1d7e57c4 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -1,2 +1,3 @@  pub mod button;  pub mod container; +pub mod text_input; diff --git a/style/src/text_input.rs b/style/src/text_input.rs new file mode 100644 index 00000000..75f427a7 --- /dev/null +++ b/style/src/text_input.rs @@ -0,0 +1,72 @@ +//! Display fields that can be filled with text. +use iced_core::{Background, Color}; + +/// The appearance of a text input. +#[derive(Debug, Clone, Copy)] +pub struct Style { +    pub background: Background, +    pub border_radius: u16, +    pub border_width: u16, +    pub border_color: Color, +} + +/// A set of rules that dictate the style of a text input. +pub trait StyleSheet { +    /// Produces the style of an active text input. +    fn active(&self) -> Style; + +    /// Produces the style of a focused text input. +    fn focused(&self) -> Style; + +    /// Produces the style of an hovered text input. +    fn hovered(&self) -> Style { +        self.focused() +    } + +    fn placeholder_color(&self) -> Color; + +    fn value_color(&self) -> Color; +} + +struct Default; + +impl StyleSheet for Default { +    fn active(&self) -> Style { +        Style { +            background: Background::Color(Color::WHITE), +            border_radius: 5, +            border_width: 1, +            border_color: Color::from_rgb(0.7, 0.7, 0.7), +        } +    } + +    fn focused(&self) -> Style { +        Style { +            border_color: Color::from_rgb(0.5, 0.5, 0.5), +            ..self.active() +        } +    } + +    fn placeholder_color(&self) -> Color { +        Color::from_rgb(0.7, 0.7, 0.7) +    } + +    fn value_color(&self) -> Color { +        Color::from_rgb(0.3, 0.3, 0.3) +    } +} + +impl std::default::Default for Box<dyn StyleSheet> { +    fn default() -> Self { +        Box::new(Default) +    } +} + +impl<T> From<T> for Box<dyn StyleSheet> +where +    T: 'static + StyleSheet, +{ +    fn from(style: T) -> Self { +        Box::new(style) +    } +} diff --git a/wgpu/src/renderer/widget/text_input.rs b/wgpu/src/renderer/widget/text_input.rs index cf3a31ab..8b774a48 100644 --- a/wgpu/src/renderer/widget/text_input.rs +++ b/wgpu/src/renderer/widget/text_input.rs @@ -1,4 +1,4 @@ -use crate::{Primitive, Renderer}; +use crate::{text_input::StyleSheet, Primitive, Renderer};  use iced_native::{      text_input, Background, Color, Font, HorizontalAlignment, MouseCursor, @@ -7,6 +7,8 @@ use iced_native::{  use std::f32;  impl text_input::Renderer for Renderer { +    type Style = Box<dyn StyleSheet>; +      fn default_size(&self) -> u16 {          // TODO: Make this configurable          20 @@ -61,20 +63,24 @@ impl text_input::Renderer for Renderer {          placeholder: &str,          value: &text_input::Value,          state: &text_input::State, +        style_sheet: &Self::Style,      ) -> Self::Output {          let is_mouse_over = bounds.contains(cursor_position); +        let style = if state.is_focused() { +            style_sheet.focused() +        } else if is_mouse_over { +            style_sheet.hovered() +        } else { +            style_sheet.active() +        }; +          let input = Primitive::Quad {              bounds, -            background: Background::Color(Color::WHITE), -            border_radius: 5, -            border_width: 1, -            border_color: if is_mouse_over || state.is_focused() { -                [0.5, 0.5, 0.5] -            } else { -                [0.7, 0.7, 0.7] -            } -            .into(), +            background: style.background, +            border_radius: style.border_radius, +            border_width: style.border_width, +            border_color: style.border_color,          };          let text = value.to_string(); @@ -86,9 +92,9 @@ impl text_input::Renderer for Renderer {                  text.clone()              },              color: if text.is_empty() { -                [0.7, 0.7, 0.7] +                style_sheet.placeholder_color()              } else { -                [0.3, 0.3, 0.3] +                style_sheet.value_color()              }              .into(),              font: Font::Default, @@ -117,7 +123,7 @@ impl text_input::Renderer for Renderer {                      width: 1.0,                      height: text_bounds.height,                  }, -                background: Background::Color(Color::BLACK), +                background: Background::Color(style_sheet.value_color()),                  border_radius: 0,                  border_width: 0,                  border_color: Color::TRANSPARENT, diff --git a/wgpu/src/widget.rs b/wgpu/src/widget.rs index c6f34301..1d7e57c4 100644 --- a/wgpu/src/widget.rs +++ b/wgpu/src/widget.rs @@ -1,2 +1,3 @@  pub mod button;  pub mod container; +pub mod text_input; diff --git a/wgpu/src/widget/text_input.rs b/wgpu/src/widget/text_input.rs new file mode 100644 index 00000000..260fe3a6 --- /dev/null +++ b/wgpu/src/widget/text_input.rs @@ -0,0 +1,15 @@ +//! Display fields that can be filled with text. +//! +//! A [`TextInput`] has some local [`State`]. +//! +//! [`TextInput`]: struct.TextInput.html +//! [`State`]: struct.State.html +use crate::Renderer; + +pub use iced_native::text_input::State; +pub use iced_style::text_input::{Style, StyleSheet}; + +/// A field that can be filled with text. +/// +/// This is an alias of an `iced_native` text input with an `iced_wgpu::Renderer`. +pub type TextInput<'a, Message> = iced_native::TextInput<'a, Message, Renderer>;  | 
