Support configurable LineHeight in text widgets
This commit is contained in:
parent
8e8808f0e1
commit
9499a8f9e6
24 changed files with 337 additions and 42 deletions
|
|
@ -46,6 +46,7 @@ where
|
|||
size: f32,
|
||||
spacing: f32,
|
||||
text_size: Option<f32>,
|
||||
text_line_height: text::LineHeight,
|
||||
text_shaping: text::Shaping,
|
||||
font: Option<Renderer::Font>,
|
||||
icon: Icon<Renderer::Font>,
|
||||
|
|
@ -83,6 +84,7 @@ where
|
|||
size: Self::DEFAULT_SIZE,
|
||||
spacing: Self::DEFAULT_SPACING,
|
||||
text_size: None,
|
||||
text_line_height: text::LineHeight::default(),
|
||||
text_shaping: text::Shaping::Basic,
|
||||
font: None,
|
||||
icon: Icon {
|
||||
|
|
@ -119,6 +121,15 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the text [`LineHeight`] of the [`Checkbox`].
|
||||
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 [`Checkbox`].
|
||||
pub fn text_shaping(mut self, shaping: text::Shaping) -> Self {
|
||||
self.text_shaping = shaping;
|
||||
|
|
@ -181,6 +192,7 @@ where
|
|||
self.text_size
|
||||
.unwrap_or_else(|| renderer.default_size()),
|
||||
)
|
||||
.line_height(self.text_line_height)
|
||||
.shaping(self.text_shaping),
|
||||
)
|
||||
.layout(renderer, limits)
|
||||
|
|
@ -276,6 +288,7 @@ where
|
|||
content: &code_point.to_string(),
|
||||
font: *font,
|
||||
size,
|
||||
line_height: text::LineHeight::default(),
|
||||
bounds: Rectangle {
|
||||
x: bounds.center_x(),
|
||||
y: bounds.center_y(),
|
||||
|
|
@ -298,6 +311,7 @@ where
|
|||
label_layout,
|
||||
&self.label,
|
||||
self.text_size,
|
||||
self.text_line_height,
|
||||
self.font,
|
||||
crate::text::Appearance {
|
||||
color: custom_style.text_color,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ where
|
|||
width: f32,
|
||||
padding: Padding,
|
||||
text_size: Option<f32>,
|
||||
text_line_height: text::LineHeight,
|
||||
text_shaping: text::Shaping,
|
||||
font: Option<Renderer::Font>,
|
||||
style: <Renderer::Theme as StyleSheet>::Style,
|
||||
|
|
@ -59,6 +60,7 @@ where
|
|||
width: 0.0,
|
||||
padding: Padding::ZERO,
|
||||
text_size: None,
|
||||
text_line_height: text::LineHeight::default(),
|
||||
text_shaping: text::Shaping::Basic,
|
||||
font: None,
|
||||
style: Default::default(),
|
||||
|
|
@ -83,6 +85,15 @@ 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;
|
||||
|
|
@ -176,6 +187,7 @@ where
|
|||
padding,
|
||||
font,
|
||||
text_size,
|
||||
text_line_height,
|
||||
text_shaping,
|
||||
style,
|
||||
} = menu;
|
||||
|
|
@ -186,6 +198,7 @@ where
|
|||
last_selection,
|
||||
font,
|
||||
text_size,
|
||||
text_line_height,
|
||||
text_shaping,
|
||||
padding,
|
||||
style: style.clone(),
|
||||
|
|
@ -321,6 +334,7 @@ where
|
|||
last_selection: &'a mut Option<T>,
|
||||
padding: Padding,
|
||||
text_size: Option<f32>,
|
||||
text_line_height: text::LineHeight,
|
||||
text_shaping: text::Shaping,
|
||||
font: Option<Renderer::Font>,
|
||||
style: <Renderer::Theme as StyleSheet>::Style,
|
||||
|
|
@ -352,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 * 1.2 + self.padding.vertical())
|
||||
(f32::from(text_line_height) + self.padding.vertical())
|
||||
* self.options.len() as f32,
|
||||
);
|
||||
|
||||
|
|
@ -395,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 * 1.2 + self.padding.vertical()))
|
||||
((cursor_position.y - bounds.y) / option_height)
|
||||
as usize,
|
||||
);
|
||||
}
|
||||
|
|
@ -410,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 * 1.2 + self.padding.vertical()))
|
||||
((cursor_position.y - bounds.y) / option_height)
|
||||
as usize,
|
||||
);
|
||||
|
||||
|
|
@ -462,12 +485,12 @@ where
|
|||
let text_size =
|
||||
self.text_size.unwrap_or_else(|| renderer.default_size());
|
||||
let option_height =
|
||||
(text_size * 1.2 + self.padding.vertical()) as usize;
|
||||
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())];
|
||||
|
||||
|
|
@ -477,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 * 1.2 + self.padding.vertical(),
|
||||
height: option_height,
|
||||
};
|
||||
|
||||
if is_selected {
|
||||
|
|
@ -503,6 +526,7 @@ where
|
|||
..bounds
|
||||
},
|
||||
size: text_size,
|
||||
line_height: self.text_line_height,
|
||||
font: self.font.unwrap_or_else(|| renderer.default_font()),
|
||||
color: if is_selected {
|
||||
appearance.selected_text_color
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ where
|
|||
width: Length,
|
||||
padding: Padding,
|
||||
text_size: Option<f32>,
|
||||
text_line_height: text::LineHeight,
|
||||
text_shaping: text::Shaping,
|
||||
font: Option<Renderer::Font>,
|
||||
handle: Handle<Renderer::Font>,
|
||||
|
|
@ -72,6 +73,7 @@ where
|
|||
width: Length::Shrink,
|
||||
padding: Self::DEFAULT_PADDING,
|
||||
text_size: None,
|
||||
text_line_height: text::LineHeight::default(),
|
||||
text_shaping: text::Shaping::Basic,
|
||||
font: None,
|
||||
handle: Default::default(),
|
||||
|
|
@ -103,6 +105,15 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the text [`LineHeight`] of the [`PickList`].
|
||||
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 [`PickList`].
|
||||
pub fn text_shaping(mut self, shaping: text::Shaping) -> Self {
|
||||
self.text_shaping = shaping;
|
||||
|
|
@ -172,6 +183,7 @@ where
|
|||
self.width,
|
||||
self.padding,
|
||||
self.text_size,
|
||||
self.text_line_height,
|
||||
self.text_shaping,
|
||||
self.font,
|
||||
self.placeholder.as_deref(),
|
||||
|
|
@ -230,6 +242,7 @@ where
|
|||
cursor_position,
|
||||
self.padding,
|
||||
self.text_size,
|
||||
self.text_line_height,
|
||||
self.text_shaping,
|
||||
font,
|
||||
self.placeholder.as_deref(),
|
||||
|
|
@ -358,6 +371,7 @@ pub fn layout<Renderer, T>(
|
|||
width: Length,
|
||||
padding: Padding,
|
||||
text_size: Option<f32>,
|
||||
text_line_height: text::LineHeight,
|
||||
text_shaping: text::Shaping,
|
||||
font: Option<Renderer::Font>,
|
||||
placeholder: Option<&str>,
|
||||
|
|
@ -375,11 +389,10 @@ where
|
|||
let max_width = match width {
|
||||
Length::Shrink => {
|
||||
let measure = |label: &str| -> f32 {
|
||||
let (width, _) = renderer.measure(
|
||||
let width = renderer.measure_width(
|
||||
label,
|
||||
text_size,
|
||||
font.unwrap_or_else(|| renderer.default_font()),
|
||||
Size::new(f32::INFINITY, f32::INFINITY),
|
||||
text_shaping,
|
||||
);
|
||||
|
||||
|
|
@ -400,8 +413,10 @@ where
|
|||
};
|
||||
|
||||
let size = {
|
||||
let intrinsic =
|
||||
Size::new(max_width + text_size + padding.left, text_size * 1.2);
|
||||
let intrinsic = Size::new(
|
||||
max_width + text_size + padding.left,
|
||||
f32::from(text_line_height.to_absolute(Pixels(text_size))),
|
||||
);
|
||||
|
||||
limits.resolve(intrinsic).pad(padding)
|
||||
};
|
||||
|
|
@ -579,6 +594,7 @@ pub fn draw<'a, T, Renderer>(
|
|||
cursor_position: Point,
|
||||
padding: Padding,
|
||||
text_size: Option<f32>,
|
||||
text_line_height: text::LineHeight,
|
||||
text_shaping: text::Shaping,
|
||||
font: Renderer::Font,
|
||||
placeholder: Option<&str>,
|
||||
|
|
@ -645,6 +661,7 @@ pub fn draw<'a, T, Renderer>(
|
|||
renderer.fill_text(Text {
|
||||
content: &code_point.to_string(),
|
||||
size,
|
||||
line_height: text::LineHeight::default(),
|
||||
font,
|
||||
color: style.handle_color,
|
||||
bounds: Rectangle {
|
||||
|
|
@ -667,6 +684,7 @@ pub fn draw<'a, T, Renderer>(
|
|||
renderer.fill_text(Text {
|
||||
content: label,
|
||||
size: text_size,
|
||||
line_height: text_line_height,
|
||||
font,
|
||||
color: if is_selected {
|
||||
style.text_color
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ where
|
|||
size: f32,
|
||||
spacing: f32,
|
||||
text_size: Option<f32>,
|
||||
text_line_height: text::LineHeight,
|
||||
text_shaping: text::Shaping,
|
||||
font: Option<Renderer::Font>,
|
||||
style: <Renderer::Theme as StyleSheet>::Style,
|
||||
|
|
@ -124,6 +125,7 @@ where
|
|||
size: Self::DEFAULT_SIZE,
|
||||
spacing: Self::DEFAULT_SPACING, //15
|
||||
text_size: None,
|
||||
text_line_height: text::LineHeight::default(),
|
||||
text_shaping: text::Shaping::Basic,
|
||||
font: None,
|
||||
style: Default::default(),
|
||||
|
|
@ -154,6 +156,15 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the text [`LineHeight`] of the [`Radio`] button.
|
||||
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 [`Radio`] button.
|
||||
pub fn text_shaping(mut self, shaping: text::Shaping) -> Self {
|
||||
self.text_shaping = shaping;
|
||||
|
|
@ -207,6 +218,7 @@ where
|
|||
self.text_size
|
||||
.unwrap_or_else(|| renderer.default_size()),
|
||||
)
|
||||
.line_height(self.text_line_height)
|
||||
.shaping(self.text_shaping),
|
||||
)
|
||||
.layout(renderer, limits)
|
||||
|
|
@ -317,6 +329,7 @@ where
|
|||
label_layout,
|
||||
&self.label,
|
||||
self.text_size,
|
||||
self.text_line_height,
|
||||
self.font,
|
||||
crate::text::Appearance {
|
||||
color: custom_style.text_color,
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ where
|
|||
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>,
|
||||
|
|
@ -96,6 +97,7 @@ where
|
|||
width: Length::Fill,
|
||||
padding: Padding::new(5.0),
|
||||
size: None,
|
||||
line_height: text::LineHeight::default(),
|
||||
on_input: None,
|
||||
on_paste: None,
|
||||
on_submit: None,
|
||||
|
|
@ -177,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,
|
||||
|
|
@ -208,6 +219,7 @@ where
|
|||
value.unwrap_or(&self.value),
|
||||
&self.placeholder,
|
||||
self.size,
|
||||
self.line_height,
|
||||
self.font,
|
||||
self.on_input.is_none(),
|
||||
self.is_secure,
|
||||
|
|
@ -263,6 +275,7 @@ where
|
|||
self.width,
|
||||
self.padding,
|
||||
self.size,
|
||||
self.line_height,
|
||||
self.icon.as_ref(),
|
||||
)
|
||||
}
|
||||
|
|
@ -299,6 +312,7 @@ where
|
|||
shell,
|
||||
&mut self.value,
|
||||
self.size,
|
||||
self.line_height,
|
||||
self.font,
|
||||
self.is_secure,
|
||||
self.on_input.as_deref(),
|
||||
|
|
@ -327,6 +341,7 @@ where
|
|||
&self.value,
|
||||
&self.placeholder,
|
||||
self.size,
|
||||
self.line_height,
|
||||
self.font,
|
||||
self.on_input.is_none(),
|
||||
self.is_secure,
|
||||
|
|
@ -447,6 +462,7 @@ pub fn layout<Renderer>(
|
|||
width: Length,
|
||||
padding: Padding,
|
||||
size: Option<f32>,
|
||||
line_height: text::LineHeight,
|
||||
icon: Option<&Icon<Renderer::Font>>,
|
||||
) -> layout::Node
|
||||
where
|
||||
|
|
@ -454,7 +470,10 @@ where
|
|||
{
|
||||
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 * 1.2);
|
||||
let limits = limits
|
||||
.width(width)
|
||||
.pad(padding)
|
||||
.height(line_height.to_absolute(Pixels(text_size)));
|
||||
|
||||
let text_bounds = limits.resolve(Size::ZERO);
|
||||
|
||||
|
|
@ -515,6 +534,7 @@ pub fn update<'a, Message, Renderer>(
|
|||
shell: &mut Shell<'_, Message>,
|
||||
value: &mut Value,
|
||||
size: Option<f32>,
|
||||
line_height: text::LineHeight,
|
||||
font: Option<Renderer::Font>,
|
||||
is_secure: bool,
|
||||
on_input: Option<&dyn Fn(String) -> Message>,
|
||||
|
|
@ -567,6 +587,7 @@ where
|
|||
text_layout.bounds(),
|
||||
font,
|
||||
size,
|
||||
line_height,
|
||||
&value,
|
||||
state,
|
||||
target,
|
||||
|
|
@ -595,6 +616,7 @@ where
|
|||
text_layout.bounds(),
|
||||
font,
|
||||
size,
|
||||
line_height,
|
||||
value,
|
||||
state,
|
||||
target,
|
||||
|
|
@ -644,6 +666,7 @@ where
|
|||
text_layout.bounds(),
|
||||
font,
|
||||
size,
|
||||
line_height,
|
||||
&value,
|
||||
state,
|
||||
target,
|
||||
|
|
@ -926,6 +949,7 @@ pub fn draw<Renderer>(
|
|||
value: &Value,
|
||||
placeholder: &str,
|
||||
size: Option<f32>,
|
||||
line_height: text::LineHeight,
|
||||
font: Option<Renderer::Font>,
|
||||
is_disabled: bool,
|
||||
is_secure: bool,
|
||||
|
|
@ -971,6 +995,7 @@ pub fn draw<Renderer>(
|
|||
renderer.fill_text(Text {
|
||||
content: &icon.code_point.to_string(),
|
||||
size: icon.size.unwrap_or_else(|| renderer.default_size()),
|
||||
line_height: text::LineHeight::default(),
|
||||
font: icon.font,
|
||||
color: appearance.icon_color,
|
||||
bounds: Rectangle {
|
||||
|
|
@ -1110,6 +1135,7 @@ pub fn draw<Renderer>(
|
|||
..text_bounds
|
||||
},
|
||||
size,
|
||||
line_height,
|
||||
horizontal_alignment: alignment::Horizontal::Left,
|
||||
vertical_alignment: alignment::Vertical::Center,
|
||||
shaping: text::Shaping::Advanced,
|
||||
|
|
@ -1336,6 +1362,7 @@ fn find_cursor_position<Renderer>(
|
|||
text_bounds: Rectangle,
|
||||
font: Option<Renderer::Font>,
|
||||
size: Option<f32>,
|
||||
line_height: text::LineHeight,
|
||||
value: &Value,
|
||||
state: &State,
|
||||
x: f32,
|
||||
|
|
@ -1353,6 +1380,7 @@ where
|
|||
.hit_test(
|
||||
&value,
|
||||
size,
|
||||
line_height,
|
||||
font,
|
||||
Size::INFINITY,
|
||||
text::Shaping::Advanced,
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ where
|
|||
width: Length,
|
||||
size: f32,
|
||||
text_size: Option<f32>,
|
||||
text_line_height: text::LineHeight,
|
||||
text_alignment: alignment::Horizontal,
|
||||
text_shaping: text::Shaping,
|
||||
spacing: f32,
|
||||
|
|
@ -80,6 +81,7 @@ where
|
|||
width: Length::Fill,
|
||||
size: Self::DEFAULT_SIZE,
|
||||
text_size: None,
|
||||
text_line_height: text::LineHeight::default(),
|
||||
text_alignment: alignment::Horizontal::Left,
|
||||
text_shaping: text::Shaping::Basic,
|
||||
spacing: 0.0,
|
||||
|
|
@ -106,6 +108,15 @@ where
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the text [`LineHeight`] of the [`Toggler`].
|
||||
pub fn text_line_height(
|
||||
mut self,
|
||||
line_height: impl Into<text::LineHeight>,
|
||||
) -> Self {
|
||||
self.text_line_height = line_height.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the horizontal alignment of the text of the [`Toggler`]
|
||||
pub fn text_alignment(mut self, alignment: alignment::Horizontal) -> Self {
|
||||
self.text_alignment = alignment;
|
||||
|
|
@ -176,6 +187,7 @@ where
|
|||
self.text_size
|
||||
.unwrap_or_else(|| renderer.default_size()),
|
||||
)
|
||||
.line_height(self.text_line_height)
|
||||
.shaping(self.text_shaping),
|
||||
);
|
||||
}
|
||||
|
|
@ -254,6 +266,7 @@ where
|
|||
label_layout,
|
||||
label,
|
||||
self.text_size,
|
||||
self.text_line_height,
|
||||
self.font,
|
||||
Default::default(),
|
||||
self.text_alignment,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue