summaryrefslogtreecommitdiffstats
path: root/widget/src/overlay/menu.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/src/overlay/menu.rs (renamed from native/src/overlay/menu.rs)105
1 files changed, 71 insertions, 34 deletions
diff --git a/native/src/overlay/menu.rs b/widget/src/overlay/menu.rs
index d93a3b56..0acc6f79 100644
--- a/native/src/overlay/menu.rs
+++ b/widget/src/overlay/menu.rs
@@ -1,25 +1,25 @@
//! Build and show dropdown menus.
-use crate::alignment;
-use crate::event::{self, Event};
-use crate::layout;
-use crate::mouse;
-use crate::overlay;
-use crate::renderer;
-use crate::text::{self, Text};
-use crate::touch;
-use crate::widget::container::{self, Container};
-use crate::widget::scrollable::{self, Scrollable};
-use crate::widget::Tree;
-use crate::{
- Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point,
- Rectangle, Shell, Size, Vector, Widget,
+use crate::container::{self, Container};
+use crate::core::alignment;
+use crate::core::event::{self, Event};
+use crate::core::layout::{self, Layout};
+use crate::core::mouse;
+use crate::core::overlay;
+use crate::core::renderer;
+use crate::core::text::{self, Text};
+use crate::core::touch;
+use crate::core::widget::Tree;
+use crate::core::{
+ Clipboard, Color, Length, Padding, Pixels, Point, Rectangle, Size, Vector,
};
+use crate::core::{Element, Shell, Widget};
+use crate::scrollable::{self, Scrollable};
pub use iced_style::menu::{Appearance, StyleSheet};
/// A list of selectable options.
#[allow(missing_debug_implementations)]
-pub struct Menu<'a, T, Renderer>
+pub struct Menu<'a, T, Renderer = crate::Renderer>
where
Renderer: text::Renderer,
Renderer::Theme: StyleSheet,
@@ -31,7 +31,9 @@ where
width: f32,
padding: Padding,
text_size: Option<f32>,
- font: Renderer::Font,
+ text_line_height: text::LineHeight,
+ text_shaping: text::Shaping,
+ font: Option<Renderer::Font>,
style: <Renderer::Theme as StyleSheet>::Style,
}
@@ -58,7 +60,9 @@ where
width: 0.0,
padding: Padding::ZERO,
text_size: None,
- font: Default::default(),
+ text_line_height: text::LineHeight::default(),
+ text_shaping: text::Shaping::Basic,
+ font: None,
style: Default::default(),
}
}
@@ -81,9 +85,24 @@ where
self
}
+ /// Sets the text [`LineHeight`] of the [`Menu`].
+ pub fn text_line_height(
+ mut self,
+ line_height: impl Into<text::LineHeight>,
+ ) -> Self {
+ self.text_line_height = line_height.into();
+ self
+ }
+
+ /// Sets the [`text::Shaping`] strategy of the [`Menu`].
+ pub fn text_shaping(mut self, shaping: text::Shaping) -> Self {
+ self.text_shaping = shaping;
+ self
+ }
+
/// Sets the font of the [`Menu`].
- pub fn font(mut self, font: Renderer::Font) -> Self {
- self.font = font;
+ pub fn font(mut self, font: impl Into<Renderer::Font>) -> Self {
+ self.font = Some(font.into());
self
}
@@ -137,7 +156,7 @@ impl Default for State {
struct Overlay<'a, Message, Renderer>
where
- Renderer: crate::Renderer,
+ Renderer: crate::core::Renderer,
Renderer::Theme: StyleSheet + container::StyleSheet,
{
state: &'a mut Tree,
@@ -168,6 +187,8 @@ where
padding,
font,
text_size,
+ text_line_height,
+ text_shaping,
style,
} = menu;
@@ -177,6 +198,8 @@ where
last_selection,
font,
text_size,
+ text_line_height,
+ text_shaping,
padding,
style: style.clone(),
}));
@@ -193,7 +216,7 @@ where
}
}
-impl<'a, Message, Renderer> crate::Overlay<Message, Renderer>
+impl<'a, Message, Renderer> crate::core::Overlay<Message, Renderer>
for Overlay<'a, Message, Renderer>
where
Renderer: text::Renderer,
@@ -311,7 +334,9 @@ where
last_selection: &'a mut Option<T>,
padding: Padding,
text_size: Option<f32>,
- font: Renderer::Font,
+ text_line_height: text::LineHeight,
+ text_shaping: text::Shaping,
+ font: Option<Renderer::Font>,
style: <Renderer::Theme as StyleSheet>::Style,
}
@@ -341,10 +366,13 @@ where
let text_size =
self.text_size.unwrap_or_else(|| renderer.default_size());
+ let text_line_height =
+ self.text_line_height.to_absolute(Pixels(text_size));
+
let size = {
let intrinsic = Size::new(
0.0,
- (text_size + self.padding.vertical())
+ (f32::from(text_line_height) + self.padding.vertical())
* self.options.len() as f32,
);
@@ -384,9 +412,12 @@ where
.text_size
.unwrap_or_else(|| renderer.default_size());
+ let option_height = f32::from(
+ self.text_line_height.to_absolute(Pixels(text_size)),
+ ) + self.padding.vertical();
+
*self.hovered_option = Some(
- ((cursor_position.y - bounds.y)
- / (text_size + self.padding.vertical()))
+ ((cursor_position.y - bounds.y) / option_height)
as usize,
);
}
@@ -399,9 +430,12 @@ where
.text_size
.unwrap_or_else(|| renderer.default_size());
+ let option_height = f32::from(
+ self.text_line_height.to_absolute(Pixels(text_size)),
+ ) + self.padding.vertical();
+
*self.hovered_option = Some(
- ((cursor_position.y - bounds.y)
- / (text_size + self.padding.vertical()))
+ ((cursor_position.y - bounds.y) / option_height)
as usize,
);
@@ -450,12 +484,13 @@ where
let text_size =
self.text_size.unwrap_or_else(|| renderer.default_size());
- let option_height = (text_size + self.padding.vertical()) as usize;
+ let option_height =
+ f32::from(self.text_line_height.to_absolute(Pixels(text_size)))
+ + self.padding.vertical();
let offset = viewport.y - bounds.y;
- let start = (offset / option_height as f32) as usize;
- let end =
- ((offset + viewport.height) / option_height as f32).ceil() as usize;
+ let start = (offset / option_height) as usize;
+ let end = ((offset + viewport.height) / option_height).ceil() as usize;
let visible_options = &self.options[start..end.min(self.options.len())];
@@ -465,9 +500,9 @@ where
let bounds = Rectangle {
x: bounds.x,
- y: bounds.y + (option_height * i) as f32,
+ y: bounds.y + (option_height * i as f32),
width: bounds.width,
- height: text_size + self.padding.vertical(),
+ height: option_height,
};
if is_selected {
@@ -495,7 +530,8 @@ where
..bounds
},
size: text_size,
- font: self.font.clone(),
+ line_height: self.text_line_height,
+ font: self.font.unwrap_or_else(|| renderer.default_font()),
color: if is_selected {
appearance.selected_text_color
} else {
@@ -503,6 +539,7 @@ where
},
horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Center,
+ shaping: self.text_shaping,
});
}
}