diff options
Diffstat (limited to 'widget/src')
-rw-r--r-- | widget/src/checkbox.rs | 2 | ||||
-rw-r--r-- | widget/src/column.rs | 9 | ||||
-rw-r--r-- | widget/src/combo_box.rs | 65 | ||||
-rw-r--r-- | widget/src/helpers.rs | 17 | ||||
-rw-r--r-- | widget/src/keyed/column.rs | 46 | ||||
-rw-r--r-- | widget/src/lazy.rs | 21 | ||||
-rw-r--r-- | widget/src/overlay/menu.rs | 2 | ||||
-rw-r--r-- | widget/src/pane_grid/state.rs | 8 | ||||
-rw-r--r-- | widget/src/pick_list.rs | 4 | ||||
-rw-r--r-- | widget/src/row.rs | 9 | ||||
-rw-r--r-- | widget/src/text_input.rs | 6 |
11 files changed, 134 insertions, 55 deletions
diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 48f6abf6..225c316d 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -340,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, diff --git a/widget/src/column.rs b/widget/src/column.rs index d37ef695..df7829b3 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -33,11 +33,18 @@ where Self::from_vec(Vec::new()) } + /// Creates a [`Column`] with the given capacity. + pub fn with_capacity(capacity: usize) -> Self { + Self::from_vec(Vec::with_capacity(capacity)) + } + /// Creates a [`Column`] with the given elements. pub fn with_children( children: impl IntoIterator<Item = Element<'a, Message, Theme, Renderer>>, ) -> Self { - Self::new().extend(children) + let iterator = children.into_iter(); + + Self::with_capacity(iterator.size_hint().0).extend(iterator) } /// Creates a [`Column`] from an already allocated [`Vec`]. diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index e4f4a41f..253850df 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -700,38 +700,47 @@ where .. } = tree.state.downcast_mut::<Menu<T>>(); - let bounds = layout.bounds(); - self.state.sync_filtered_options(filtered_options); - let mut menu = menu::Menu::new( - menu, - &filtered_options.options, - hovered_option, - |x| { - tree.children[0] - .state - .downcast_mut::<text_input::State<Renderer::Paragraph>>( - ) - .unfocus(); - - (self.on_selected)(x) - }, - self.on_option_hovered.as_deref(), - &self.menu_class, - ) - .width(bounds.width) - .padding(self.padding); - - if let Some(font) = self.font { - menu = menu.font(font); - } + if filtered_options.options.is_empty() { + None + } else { + let bounds = layout.bounds(); + + let mut menu = menu::Menu::new( + menu, + &filtered_options.options, + hovered_option, + |x| { + tree.children[0] + .state + .downcast_mut::<text_input::State<Renderer::Paragraph>>( + ) + .unfocus(); + + (self.on_selected)(x) + }, + self.on_option_hovered.as_deref(), + &self.menu_class, + ) + .width(bounds.width) + .padding(self.padding); + + if let Some(font) = self.font { + menu = menu.font(font); + } - if let Some(size) = self.size { - menu = menu.text_size(size); - } + if let Some(size) = self.size { + menu = menu.text_size(size); + } - Some(menu.overlay(layout.position() + translation, bounds.height)) + Some( + menu.overlay( + layout.position() + translation, + bounds.height, + ), + ) + } } else { None } diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 77b30882..61789c19 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -145,13 +145,26 @@ where /// /// [`Text`]: core::widget::Text pub fn text<'a, Theme, Renderer>( - text: impl ToString, + text: impl text::IntoFragment<'a>, ) -> Text<'a, Theme, Renderer> where Theme: text::Catalog + 'a, Renderer: core::text::Renderer, { - Text::new(text.to_string()) + Text::new(text) +} + +/// Creates a new [`Text`] widget that displays the provided value. +/// +/// [`Text`]: core::widget::Text +pub fn value<'a, Theme, Renderer>( + value: impl ToString, +) -> Text<'a, Theme, Renderer> +where + Theme: text::Catalog + 'a, + Renderer: core::text::Renderer, +{ + Text::new(value.to_string()) } /// Creates a new [`Checkbox`]. diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index 8a8d5fe7..a34ce9e6 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -40,27 +40,49 @@ where { /// Creates an empty [`Column`]. pub fn new() -> Self { - Column { + Self::from_vecs(Vec::new(), Vec::new()) + } + + /// Creates a [`Column`] from already allocated [`Vec`]s. + /// + /// Keep in mind that the [`Column`] will not inspect the [`Vec`]s, which means + /// it won't automatically adapt to the sizing strategy of its contents. + /// + /// If any of the children have a [`Length::Fill`] strategy, you will need to + /// call [`Column::width`] or [`Column::height`] accordingly. + pub fn from_vecs( + keys: Vec<Key>, + children: Vec<Element<'a, Message, Theme, Renderer>>, + ) -> Self { + Self { spacing: 0.0, padding: Padding::ZERO, width: Length::Shrink, height: Length::Shrink, max_width: f32::INFINITY, align_items: Alignment::Start, - keys: Vec::new(), - children: Vec::new(), + keys, + children, } } + /// Creates a [`Column`] with the given capacity. + pub fn with_capacity(capacity: usize) -> Self { + Self::from_vecs( + Vec::with_capacity(capacity), + Vec::with_capacity(capacity), + ) + } + /// Creates a [`Column`] with the given elements. pub fn with_children( children: impl IntoIterator< Item = (Key, Element<'a, Message, Theme, Renderer>), >, ) -> Self { - children - .into_iter() - .fold(Self::new(), |column, (key, child)| column.push(key, child)) + let iterator = children.into_iter(); + + Self::with_capacity(iterator.size_hint().0).extend(iterator) } /// Sets the vertical spacing _between_ elements. @@ -132,6 +154,18 @@ where self } } + + /// Extends the [`Column`] with the given children. + pub fn extend( + self, + children: impl IntoIterator< + Item = (Key, Element<'a, Message, Theme, Renderer>), + >, + ) -> Self { + children + .into_iter() + .fold(self, |column, (key, child)| column.push(key, child)) + } } impl<'a, Key, Message, Renderer> Default for Column<'a, Key, Message, Renderer> diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index eb663ea5..04783dbe 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -18,11 +18,12 @@ use crate::core::widget::tree::{self, Tree}; use crate::core::widget::{self, Widget}; use crate::core::Element; use crate::core::{ - self, Clipboard, Hasher, Length, Point, Rectangle, Shell, Size, Vector, + self, Clipboard, Length, Point, Rectangle, Shell, Size, Vector, }; use crate::runtime::overlay::Nested; use ouroboros::self_referencing; +use rustc_hash::FxHasher; use std::cell::RefCell; use std::hash::{Hash, Hasher as H}; use std::rc::Rc; @@ -106,9 +107,12 @@ where } fn state(&self) -> tree::State { - let mut hasher = Hasher::default(); - self.dependency.hash(&mut hasher); - let hash = hasher.finish(); + let hash = { + let mut hasher = FxHasher::default(); + self.dependency.hash(&mut hasher); + + hasher.finish() + }; let element = Rc::new(RefCell::new(Some((self.view)(&self.dependency).into()))); @@ -127,9 +131,12 @@ where .state .downcast_mut::<Internal<Message, Theme, Renderer>>(); - let mut hasher = Hasher::default(); - self.dependency.hash(&mut hasher); - let new_hash = hasher.finish(); + let new_hash = { + let mut hasher = FxHasher::default(); + self.dependency.hash(&mut hasher); + + hasher.finish() + }; if current.hash != new_hash { current.hash = new_hash; diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index d76caa8a..98efe305 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -526,7 +526,7 @@ where renderer.fill_text( Text { - content: &option.to_string(), + content: option.to_string(), bounds: Size::new(f32::INFINITY, bounds.height), size: text_size, line_height: self.text_line_height, diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index 481cd770..c20c3b9c 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -6,7 +6,7 @@ use crate::pane_grid::{ Axis, Configuration, Direction, Edge, Node, Pane, Region, Split, Target, }; -use std::collections::HashMap; +use rustc_hash::FxHashMap; /// The state of a [`PaneGrid`]. /// @@ -25,7 +25,7 @@ pub struct State<T> { /// The panes of the [`PaneGrid`]. /// /// [`PaneGrid`]: super::PaneGrid - pub panes: HashMap<Pane, T>, + pub panes: FxHashMap<Pane, T>, /// The internal state of the [`PaneGrid`]. /// @@ -52,7 +52,7 @@ impl<T> State<T> { /// Creates a new [`State`] with the given [`Configuration`]. pub fn with_configuration(config: impl Into<Configuration<T>>) -> Self { - let mut panes = HashMap::new(); + let mut panes = FxHashMap::default(); let internal = Internal::from_configuration(&mut panes, config.into(), 0); @@ -353,7 +353,7 @@ impl Internal { /// /// [`PaneGrid`]: super::PaneGrid pub fn from_configuration<T>( - panes: &mut HashMap<Pane, T>, + panes: &mut FxHashMap<Pane, T>, content: Configuration<T>, next_id: usize, ) -> Self { diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 801e792b..edccfdaa 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -479,7 +479,7 @@ where renderer.fill_text( Text { - content: &code_point.to_string(), + content: code_point.to_string(), size, line_height, font, @@ -502,7 +502,7 @@ where let label = selected.map(ToString::to_string); - if let Some(label) = label.as_deref().or(self.placeholder.as_deref()) { + if let Some(label) = label.or_else(|| self.placeholder.clone()) { let text_size = self.text_size.unwrap_or_else(|| renderer.default_size()); diff --git a/widget/src/row.rs b/widget/src/row.rs index 47feff9c..fa352171 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -31,11 +31,18 @@ where Self::from_vec(Vec::new()) } + /// Creates a [`Row`] with the given capacity. + pub fn with_capacity(capacity: usize) -> Self { + Self::from_vec(Vec::with_capacity(capacity)) + } + /// Creates a [`Row`] with the given elements. pub fn with_children( children: impl IntoIterator<Item = Element<'a, Message, Theme, Renderer>>, ) -> Self { - Self::new().extend(children) + let iterator = children.into_iter(); + + Self::with_capacity(iterator.size_hint().0).extend(iterator) } /// Creates a [`Row`] from an already allocated [`Vec`]. diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index dafe2fca..8cfb0408 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -232,7 +232,7 @@ where let placeholder_text = Text { font, line_height: self.line_height, - content: &self.placeholder, + content: self.placeholder.as_str(), bounds: Size::new(f32::INFINITY, text_bounds.height), size: text_size, horizontal_alignment: alignment::Horizontal::Left, @@ -251,9 +251,11 @@ where }); if let Some(icon) = &self.icon { + let mut content = [0; 4]; + let icon_text = Text { line_height: self.line_height, - content: &icon.code_point.to_string(), + content: icon.code_point.encode_utf8(&mut content) as &_, font: icon.font, size: icon.size.unwrap_or_else(|| renderer.default_size()), bounds: Size::new(f32::INFINITY, text_bounds.height), |