diff options
| author | 2023-05-11 16:45:08 +0200 | |
|---|---|---|
| committer | 2023-05-11 16:45:08 +0200 | |
| commit | 669f7cc74b2e7918e86a8197916f503f2d3d9b93 (patch) | |
| tree | acb365358235be6ce115b50db9404d890b6e77a6 /widget/src/text_input | |
| parent | bc62013b6cde52174bf4c4286939cf170bfa7760 (diff) | |
| parent | 63d3fc6996b848e10e77e6924bfebdf6ba82852e (diff) | |
| download | iced-669f7cc74b2e7918e86a8197916f503f2d3d9b93.tar.gz iced-669f7cc74b2e7918e86a8197916f503f2d3d9b93.tar.bz2 iced-669f7cc74b2e7918e86a8197916f503f2d3d9b93.zip | |
Merge pull request #1830 from iced-rs/advanced-text
Advanced text
Diffstat (limited to '')
| -rw-r--r-- | widget/src/text_input.rs (renamed from native/src/widget/text_input.rs) | 145 | ||||
| -rw-r--r-- | widget/src/text_input/cursor.rs (renamed from native/src/widget/text_input/cursor.rs) | 2 | ||||
| -rw-r--r-- | widget/src/text_input/editor.rs (renamed from native/src/widget/text_input/editor.rs) | 2 | ||||
| -rw-r--r-- | widget/src/text_input/value.rs (renamed from native/src/widget/text_input/value.rs) | 0 | 
4 files changed, 100 insertions, 49 deletions
| diff --git a/native/src/widget/text_input.rs b/widget/src/text_input.rs index 6113cf94..bbc07dac 100644 --- a/native/src/widget/text_input.rs +++ b/widget/src/text_input.rs @@ -11,31 +11,34 @@ pub use value::Value;  use editor::Editor; -use crate::alignment; -use crate::event::{self, Event}; -use crate::keyboard; -use crate::layout; -use crate::mouse::{self, click}; -use crate::renderer; -use crate::text::{self, Text}; -use crate::time::{Duration, Instant}; -use crate::touch; -use crate::widget; -use crate::widget::operation::{self, Operation}; -use crate::widget::tree::{self, Tree}; -use crate::window; -use crate::{ -    Clipboard, Color, Command, Element, Layout, Length, Padding, Pixels, Point, +use crate::core::alignment; +use crate::core::event::{self, Event}; +use crate::core::keyboard; +use crate::core::layout; +use crate::core::mouse::{self, click}; +use crate::core::renderer; +use crate::core::text::{self, Text}; +use crate::core::time::{Duration, Instant}; +use crate::core::touch; +use crate::core::widget; +use crate::core::widget::operation::{self, Operation}; +use crate::core::widget::tree::{self, Tree}; +use crate::core::window; +use crate::core::{ +    Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point,      Rectangle, Shell, Size, Vector, Widget,  }; +use crate::runtime::Command;  pub use iced_style::text_input::{Appearance, StyleSheet};  /// A field that can be filled with text.  ///  /// # Example -/// ``` -/// # pub type TextInput<'a, Message> = iced_native::widget::TextInput<'a, Message, iced_native::renderer::Null>; +/// ```no_run +/// # pub type TextInput<'a, Message> = +/// #     iced_widget::TextInput<'a, Message, iced_widget::renderer::Renderer<iced_widget::style::Theme>>; +/// #  /// #[derive(Debug, Clone)]  /// enum Message {  ///     TextInputChanged(String), @@ -52,7 +55,7 @@ pub use iced_style::text_input::{Appearance, StyleSheet};  /// ```  ///   #[allow(missing_debug_implementations)] -pub struct TextInput<'a, Message, Renderer> +pub struct TextInput<'a, Message, Renderer = crate::Renderer>  where      Renderer: text::Renderer,      Renderer::Theme: StyleSheet, @@ -61,10 +64,11 @@ where      placeholder: String,      value: Value,      is_secure: bool, -    font: Renderer::Font, +    font: Option<Renderer::Font>,      width: Length,      padding: Padding,      size: Option<f32>, +    line_height: text::LineHeight,      on_input: Option<Box<dyn Fn(String) -> Message + 'a>>,      on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>,      on_submit: Option<Message>, @@ -89,10 +93,11 @@ where              placeholder: String::from(placeholder),              value: Value::new(value),              is_secure: false, -            font: Default::default(), +            font: None,              width: Length::Fill,              padding: Padding::new(5.0),              size: None, +            line_height: text::LineHeight::default(),              on_input: None,              on_paste: None,              on_submit: None, @@ -146,7 +151,7 @@ where      ///      /// [`Font`]: text::Renderer::Font      pub fn font(mut self, font: Renderer::Font) -> Self { -        self.font = font; +        self.font = Some(font);          self      } @@ -174,6 +179,15 @@ where          self      } +    /// Sets the [`LineHeight`] of the [`TextInput`]. +    pub fn line_height( +        mut self, +        line_height: impl Into<text::LineHeight>, +    ) -> Self { +        self.line_height = line_height.into(); +        self +    } +      /// Sets the style of the [`TextInput`].      pub fn style(          mut self, @@ -205,7 +219,8 @@ where              value.unwrap_or(&self.value),              &self.placeholder,              self.size, -            &self.font, +            self.line_height, +            self.font,              self.on_input.is_none(),              self.is_secure,              self.icon.as_ref(), @@ -260,6 +275,7 @@ where              self.width,              self.padding,              self.size, +            self.line_height,              self.icon.as_ref(),          )      } @@ -296,7 +312,8 @@ where              shell,              &mut self.value,              self.size, -            &self.font, +            self.line_height, +            self.font,              self.is_secure,              self.on_input.as_deref(),              self.on_paste.as_deref(), @@ -324,7 +341,8 @@ where              &self.value,              &self.placeholder,              self.size, -            &self.font, +            self.line_height, +            self.font,              self.on_input.is_none(),              self.is_secure,              self.icon.as_ref(), @@ -444,15 +462,18 @@ pub fn layout<Renderer>(      width: Length,      padding: Padding,      size: Option<f32>, +    line_height: text::LineHeight,      icon: Option<&Icon<Renderer::Font>>,  ) -> layout::Node  where      Renderer: text::Renderer,  {      let text_size = size.unwrap_or_else(|| renderer.default_size()); -      let padding = padding.fit(Size::ZERO, limits.max()); -    let limits = limits.width(width).pad(padding).height(text_size); +    let limits = limits +        .width(width) +        .pad(padding) +        .height(line_height.to_absolute(Pixels(text_size)));      let text_bounds = limits.resolve(Size::ZERO); @@ -460,7 +481,8 @@ where          let icon_width = renderer.measure_width(              &icon.code_point.to_string(),              icon.size.unwrap_or_else(|| renderer.default_size()), -            icon.font.clone(), +            icon.font, +            text::Shaping::Advanced,          );          let mut text_node = layout::Node::new( @@ -512,7 +534,8 @@ pub fn update<'a, Message, Renderer>(      shell: &mut Shell<'_, Message>,      value: &mut Value,      size: Option<f32>, -    font: &Renderer::Font, +    line_height: text::LineHeight, +    font: Option<Renderer::Font>,      is_secure: bool,      on_input: Option<&dyn Fn(String) -> Message>,      on_paste: Option<&dyn Fn(String) -> Message>, @@ -562,8 +585,9 @@ where                              find_cursor_position(                                  renderer,                                  text_layout.bounds(), -                                font.clone(), +                                font,                                  size, +                                line_height,                                  &value,                                  state,                                  target, @@ -590,8 +614,9 @@ where                              let position = find_cursor_position(                                  renderer,                                  text_layout.bounds(), -                                font.clone(), +                                font,                                  size, +                                line_height,                                  value,                                  state,                                  target, @@ -639,8 +664,9 @@ where                  let position = find_cursor_position(                      renderer,                      text_layout.bounds(), -                    font.clone(), +                    font,                      size, +                    line_height,                      &value,                      state,                      target, @@ -923,7 +949,8 @@ pub fn draw<Renderer>(      value: &Value,      placeholder: &str,      size: Option<f32>, -    font: &Renderer::Font, +    line_height: text::LineHeight, +    font: Option<Renderer::Font>,      is_disabled: bool,      is_secure: bool,      icon: Option<&Icon<Renderer::Font>>, @@ -968,7 +995,8 @@ pub fn draw<Renderer>(          renderer.fill_text(Text {              content: &icon.code_point.to_string(),              size: icon.size.unwrap_or_else(|| renderer.default_size()), -            font: icon.font.clone(), +            line_height: text::LineHeight::default(), +            font: icon.font,              color: appearance.icon_color,              bounds: Rectangle {                  y: text_bounds.center_y(), @@ -976,10 +1004,12 @@ pub fn draw<Renderer>(              },              horizontal_alignment: alignment::Horizontal::Left,              vertical_alignment: alignment::Vertical::Center, +            shaping: text::Shaping::Advanced,          });      }      let text = value.to_string(); +    let font = font.unwrap_or_else(|| renderer.default_font());      let size = size.unwrap_or_else(|| renderer.default_size());      let (cursor, offset) = if let Some(focus) = &state.is_focused { @@ -992,7 +1022,7 @@ pub fn draw<Renderer>(                          value,                          size,                          position, -                        font.clone(), +                        font,                      );                  let is_cursor_visible = ((focus.now - focus.updated_at) @@ -1033,7 +1063,7 @@ pub fn draw<Renderer>(                          value,                          size,                          left, -                        font.clone(), +                        font,                      );                  let (right_position, right_offset) = @@ -1043,7 +1073,7 @@ pub fn draw<Renderer>(                          value,                          size,                          right, -                        font.clone(), +                        font,                      );                  let width = right_position - left_position; @@ -1078,12 +1108,15 @@ pub fn draw<Renderer>(      let text_width = renderer.measure_width(          if text.is_empty() { placeholder } else { &text },          size, -        font.clone(), +        font, +        text::Shaping::Advanced,      );      let render = |renderer: &mut Renderer| {          if let Some((cursor, color)) = cursor {              renderer.fill_quad(cursor, color); +        } else { +            renderer.with_translation(Vector::ZERO, |_| {});          }          renderer.fill_text(Text { @@ -1095,15 +1128,17 @@ pub fn draw<Renderer>(              } else {                  theme.value_color(style)              }, -            font: font.clone(), +            font,              bounds: Rectangle {                  y: text_bounds.center_y(),                  width: f32::INFINITY,                  ..text_bounds              },              size, +            line_height,              horizontal_alignment: alignment::Horizontal::Left,              vertical_alignment: alignment::Vertical::Center, +            shaping: text::Shaping::Advanced,          });      }; @@ -1250,7 +1285,7 @@ impl operation::TextInput for State {  }  mod platform { -    use crate::keyboard; +    use crate::core::keyboard;      pub fn is_jump_modifier_pressed(modifiers: keyboard::Modifiers) -> bool {          if cfg!(target_os = "macos") { @@ -1308,8 +1343,12 @@ where  {      let text_before_cursor = value.until(cursor_index).to_string(); -    let text_value_width = -        renderer.measure_width(&text_before_cursor, size, font); +    let text_value_width = renderer.measure_width( +        &text_before_cursor, +        size, +        font, +        text::Shaping::Advanced, +    );      let offset = ((text_value_width + 5.0) - text_bounds.width).max(0.0); @@ -1321,8 +1360,9 @@ where  fn find_cursor_position<Renderer>(      renderer: &Renderer,      text_bounds: Rectangle, -    font: Renderer::Font, +    font: Option<Renderer::Font>,      size: Option<f32>, +    line_height: text::LineHeight,      value: &Value,      state: &State,      x: f32, @@ -1330,21 +1370,32 @@ fn find_cursor_position<Renderer>(  where      Renderer: text::Renderer,  { +    let font = font.unwrap_or_else(|| renderer.default_font());      let size = size.unwrap_or_else(|| renderer.default_size()); -    let offset = -        offset(renderer, text_bounds, font.clone(), size, value, state); +    let offset = offset(renderer, text_bounds, font, size, value, state); +    let value = value.to_string(); -    renderer +    let char_offset = renderer          .hit_test( -            &value.to_string(), +            &value,              size, +            line_height,              font,              Size::INFINITY, +            text::Shaping::Advanced,              Point::new(x + offset, text_bounds.height / 2.0),              true,          ) -        .map(text::Hit::cursor) +        .map(text::Hit::cursor)?; + +    Some( +        unicode_segmentation::UnicodeSegmentation::graphemes( +            &value[..char_offset], +            true, +        ) +        .count(), +    )  }  const CURSOR_BLINK_INTERVAL_MILLIS: u128 = 500; diff --git a/native/src/widget/text_input/cursor.rs b/widget/src/text_input/cursor.rs index 4f3b159b..9680dfd7 100644 --- a/native/src/widget/text_input/cursor.rs +++ b/widget/src/text_input/cursor.rs @@ -1,5 +1,5 @@  //! Track the cursor of a text input. -use crate::widget::text_input::Value; +use crate::text_input::Value;  /// The cursor of a text input.  #[derive(Debug, Copy, Clone)] diff --git a/native/src/widget/text_input/editor.rs b/widget/src/text_input/editor.rs index d53fa8d9..f1fd641f 100644 --- a/native/src/widget/text_input/editor.rs +++ b/widget/src/text_input/editor.rs @@ -1,4 +1,4 @@ -use crate::widget::text_input::{Cursor, Value}; +use crate::text_input::{Cursor, Value};  pub struct Editor<'a> {      value: &'a mut Value, diff --git a/native/src/widget/text_input/value.rs b/widget/src/text_input/value.rs index cf4da562..cf4da562 100644 --- a/native/src/widget/text_input/value.rs +++ b/widget/src/text_input/value.rs | 
