summaryrefslogtreecommitdiffstats
path: root/widget/src
diff options
context:
space:
mode:
Diffstat (limited to 'widget/src')
-rw-r--r--widget/src/checkbox.rs2
-rw-r--r--widget/src/column.rs9
-rw-r--r--widget/src/combo_box.rs65
-rw-r--r--widget/src/helpers.rs17
-rw-r--r--widget/src/keyed/column.rs46
-rw-r--r--widget/src/lazy.rs21
-rw-r--r--widget/src/overlay/menu.rs2
-rw-r--r--widget/src/pane_grid/state.rs8
-rw-r--r--widget/src/pick_list.rs4
-rw-r--r--widget/src/row.rs9
-rw-r--r--widget/src/text_input.rs6
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),