Skip to content

Commit d36e4df

Browse files
hojjatabdollahijackpot51
authored andcommitted
feat: add Ellipsize to widgets
1 parent ecc29a8 commit d36e4df

14 files changed

Lines changed: 150 additions & 8 deletions

File tree

core/src/text.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ pub struct Text<Content = String, Font = crate::Font> {
4444

4545
/// The [`Wrapping`] strategy of the [`Text`].
4646
pub wrapping: Wrapping,
47+
48+
/// The [`Ellipsize`] strategy of the [`Text`].
49+
pub ellipsize: Ellipsize,
4750
}
4851

4952
/// The shaping strategy of some text.
@@ -86,6 +89,31 @@ pub enum Wrapping {
8689
WordOrGlyph,
8790
}
8891

92+
/// The ellipsizing strategy of some text.
93+
#[derive(Debug, Clone, Copy, PartialEq, Default)]
94+
pub enum Ellipsize {
95+
/// No ellipsizing.
96+
///
97+
/// This is the default.
98+
#[default]
99+
None,
100+
/// Ellipsize at the start of the text.
101+
Start(EllipsizeHeightLimit),
102+
/// Ellipsize in the middle of the text.
103+
Middle(EllipsizeHeightLimit),
104+
/// Ellipsize at the end of the text.
105+
End(EllipsizeHeightLimit),
106+
}
107+
108+
/// The ellipsizing strategy of some text when it exceeds a certain height.
109+
#[derive(Debug, Clone, Copy, PartialEq)]
110+
pub enum EllipsizeHeightLimit {
111+
/// The number of lines after which ellipsizing should occur.
112+
Lines(usize),
113+
/// The height limit in pixels
114+
Height(f32),
115+
}
116+
89117
/// The height of a line of text in a paragraph.
90118
#[derive(Debug, Clone, Copy, PartialEq)]
91119
pub enum LineHeight {

core/src/text/paragraph.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ impl<P: Paragraph> Plain<P> {
9696
vertical_alignment: text.vertical_alignment,
9797
shaping: text.shaping,
9898
wrapping: text.wrapping,
99+
ellipsize: text.ellipsize,
99100
}) {
100101
Difference::None => {}
101102
Difference::Bounds => {

core/src/widget/text.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::{
3232
Widget,
3333
};
3434

35-
pub use text::{LineHeight, Shaping, Wrapping};
35+
pub use text::{Ellipsize, LineHeight, Shaping, Wrapping};
3636

3737
/// A bunch of text.
3838
///
@@ -73,6 +73,7 @@ where
7373
font: Option<Renderer::Font>,
7474
shaping: Shaping,
7575
wrapping: Wrapping,
76+
ellipsize: Ellipsize,
7677
class: Theme::Class<'a>,
7778
}
7879

@@ -95,6 +96,7 @@ where
9596
vertical_alignment: alignment::Vertical::Top,
9697
shaping: Shaping::default(),
9798
wrapping: Wrapping::default(),
99+
ellipsize: Ellipsize::default(),
98100
class: Theme::default(),
99101
}
100102
}
@@ -167,6 +169,12 @@ where
167169
self
168170
}
169171

172+
// Sets the [`Ellipsize`] strategy of the [`Text`].
173+
pub fn ellipsize(mut self, ellipsize: Ellipsize) -> Self {
174+
self.ellipsize = ellipsize;
175+
self
176+
}
177+
170178
/// Sets the style of the [`Text`].
171179
#[must_use]
172180
pub fn style(mut self, style: impl Fn(&Theme) -> Style + 'a) -> Self
@@ -251,6 +259,7 @@ where
251259
self.vertical_alignment,
252260
self.shaping,
253261
self.wrapping,
262+
self.ellipsize,
254263
)
255264
}
256265

@@ -330,6 +339,7 @@ pub fn layout<Renderer>(
330339
vertical_alignment: alignment::Vertical,
331340
shaping: Shaping,
332341
wrapping: Wrapping,
342+
ellipsize: Ellipsize,
333343
) -> layout::Node
334344
where
335345
Renderer: text::Renderer,
@@ -352,6 +362,7 @@ where
352362
vertical_alignment,
353363
shaping,
354364
wrapping,
365+
ellipsize,
355366
});
356367

357368
paragraph.min_bounds()

graphics/src/text.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,37 @@ pub fn to_wrap(wrapping: Wrapping) -> cosmic_text::Wrap {
323323
}
324324
}
325325

326+
/// Converts some [`Ellipsize`] strategy to a [`cosmic_text::Ellipsize`] strategy.
327+
pub fn to_ellipsize(
328+
ellipsize: crate::core::text::Ellipsize,
329+
) -> cosmic_text::Ellipsize {
330+
match ellipsize {
331+
crate::core::text::Ellipsize::None => cosmic_text::Ellipsize::None,
332+
crate::core::text::Ellipsize::Start(limit) => {
333+
cosmic_text::Ellipsize::Start(to_ellipsize_height_limit(limit))
334+
}
335+
crate::core::text::Ellipsize::Middle(limit) => {
336+
cosmic_text::Ellipsize::Middle(to_ellipsize_height_limit(limit))
337+
}
338+
crate::core::text::Ellipsize::End(limit) => {
339+
cosmic_text::Ellipsize::End(to_ellipsize_height_limit(limit))
340+
}
341+
}
342+
}
343+
344+
pub fn to_ellipsize_height_limit(
345+
limit: crate::core::text::EllipsizeHeightLimit,
346+
) -> cosmic_text::EllipsizeHeightLimit {
347+
match limit {
348+
crate::core::text::EllipsizeHeightLimit::Lines(lines) => {
349+
cosmic_text::EllipsizeHeightLimit::Lines(lines)
350+
}
351+
crate::core::text::EllipsizeHeightLimit::Height(height) => {
352+
cosmic_text::EllipsizeHeightLimit::Height(height)
353+
}
354+
}
355+
}
356+
326357
/// Converts some [`Color`] to a [`cosmic_text::Color`].
327358
pub fn to_color(color: Color) -> cosmic_text::Color {
328359
let [r, g, b, a] = color.into_rgba8();

graphics/src/text/paragraph.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ impl core::text::Paragraph for Paragraph {
8181
);
8282

8383
buffer.set_wrap(font_system.raw(), text::to_wrap(text.wrapping));
84+
buffer.set_ellipsize(
85+
font_system.raw(),
86+
text::to_ellipsize(text.ellipsize),
87+
);
8488

8589
buffer.set_text(
8690
font_system.raw(),

wgpu/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ impl Renderer {
410410
vertical_alignment: alignment::Vertical::Top,
411411
shaping: core::text::Shaping::Advanced,
412412
wrapping: core::text::Wrapping::Word,
413+
ellipsize: core::text::Ellipsize::None,
413414
};
414415

415416
renderer.fill_text(

widget/src/checkbox.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ pub struct Checkbox<
108108
text_line_height: text::LineHeight,
109109
text_shaping: text::Shaping,
110110
text_wrapping: text::Wrapping,
111+
text_ellipsize: text::Ellipsize,
111112
font: Option<Renderer::Font>,
112113
icon: Icon<Renderer::Font>,
113114
class: Theme::Class<'a>,
@@ -147,6 +148,7 @@ where
147148
text_line_height: text::LineHeight::default(),
148149
text_shaping: text::Shaping::default(),
149150
text_wrapping: text::Wrapping::default(),
151+
text_ellipsize: text::Ellipsize::default(),
150152
font: None,
151153
icon: Icon {
152154
font: Renderer::ICON_FONT,
@@ -340,6 +342,7 @@ where
340342
alignment::Vertical::Top,
341343
self.text_shaping,
342344
self.text_wrapping,
345+
self.text_ellipsize,
343346
)
344347
},
345348
)
@@ -450,6 +453,7 @@ where
450453
vertical_alignment: alignment::Vertical::Center,
451454
shaping: *shaping,
452455
wrapping: text::Wrapping::default(),
456+
ellipsize: text::Ellipsize::default(),
453457
},
454458
bounds.center(),
455459
style.icon_color,

widget/src/overlay/menu.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ where
544544
vertical_alignment: alignment::Vertical::Center,
545545
shaping: self.text_shaping,
546546
wrapping: text::Wrapping::default(),
547+
ellipsize: text::Ellipsize::default(),
547548
},
548549
Point::new(bounds.x + self.padding.left, bounds.center_y()),
549550
if is_selected {

widget/src/pick_list.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ pub struct PickList<
172172
text_line_height: text::LineHeight,
173173
text_shaping: text::Shaping,
174174
text_wrap: text::Wrapping,
175+
text_ellipsize: text::Ellipsize,
175176
font: Option<Renderer::Font>,
176177
handle: Handle<Renderer::Font>,
177178
class: <Theme as Catalog>::Class<'a>,
@@ -208,6 +209,7 @@ where
208209
text_line_height: text::LineHeight::default(),
209210
text_shaping: text::Shaping::Advanced,
210211
text_wrap: text::Wrapping::default(),
212+
text_ellipsize: text::Ellipsize::default(),
211213
font: None,
212214
handle: Handle::default(),
213215
class: <Theme as Catalog>::default(),
@@ -383,6 +385,7 @@ where
383385
vertical_alignment: alignment::Vertical::Center,
384386
shaping: self.text_shaping,
385387
wrapping: self.text_wrap,
388+
ellipsize: self.text_ellipsize,
386389
};
387390

388391
for (option, paragraph) in options.iter().zip(state.options.iter_mut())
@@ -603,6 +606,7 @@ where
603606
text::LineHeight::default(),
604607
text::Shaping::Basic,
605608
text::Wrapping::default(),
609+
text::Ellipsize::default(),
606610
)),
607611
Handle::Static(Icon {
608612
font,
@@ -611,9 +615,16 @@ where
611615
line_height,
612616
shaping,
613617
wrap,
614-
}) => {
615-
Some((*font, *code_point, *size, *line_height, *shaping, *wrap))
616-
}
618+
ellipsize,
619+
}) => Some((
620+
*font,
621+
*code_point,
622+
*size,
623+
*line_height,
624+
*shaping,
625+
*wrap,
626+
*ellipsize,
627+
)),
617628
Handle::Dynamic { open, closed } => {
618629
if state.is_open {
619630
Some((
@@ -623,6 +634,7 @@ where
623634
open.line_height,
624635
open.shaping,
625636
open.wrap,
637+
open.ellipsize,
626638
))
627639
} else {
628640
Some((
@@ -632,14 +644,22 @@ where
632644
closed.line_height,
633645
closed.shaping,
634646
closed.wrap,
647+
closed.ellipsize,
635648
))
636649
}
637650
}
638651
Handle::None => None,
639652
};
640653

641-
if let Some((font, code_point, size, line_height, shaping, wrap)) =
642-
handle
654+
if let Some((
655+
font,
656+
code_point,
657+
size,
658+
line_height,
659+
shaping,
660+
wrap,
661+
ellipsize,
662+
)) = handle
643663
{
644664
let size = size.unwrap_or_else(|| renderer.default_size());
645665

@@ -657,6 +677,7 @@ where
657677
vertical_alignment: alignment::Vertical::Center,
658678
shaping,
659679
wrapping: wrap,
680+
ellipsize: ellipsize,
660681
},
661682
Point::new(
662683
bounds.x + bounds.width - self.padding.right,
@@ -687,6 +708,7 @@ where
687708
vertical_alignment: alignment::Vertical::Center,
688709
shaping: self.text_shaping,
689710
wrapping: self.text_wrap,
711+
ellipsize: self.text_ellipsize,
690712
},
691713
Point::new(bounds.x + self.padding.left, bounds.center_y()),
692714
if is_selected {
@@ -834,6 +856,8 @@ pub struct Icon<Font> {
834856
pub shaping: text::Shaping,
835857
/// The wrap mode of the icon.
836858
pub wrap: text::Wrapping,
859+
/// The ellipsize mode of the icon.
860+
pub ellipsize: text::Ellipsize,
837861
}
838862

839863
/// The possible status of a [`PickList`].

widget/src/radio.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ where
145145
text_line_height: text::LineHeight,
146146
text_shaping: text::Shaping,
147147
text_wrapping: text::Wrapping,
148+
text_ellipsize: text::Ellipsize,
148149
font: Option<Renderer::Font>,
149150
class: Theme::Class<'a>,
150151
}
@@ -190,6 +191,7 @@ where
190191
text_line_height: text::LineHeight::default(),
191192
text_shaping: text::Shaping::Advanced,
192193
text_wrapping: text::Wrapping::default(),
194+
text_ellipsize: text::Ellipsize::default(),
193195
font: None,
194196
class: Theme::default(),
195197
}
@@ -240,6 +242,12 @@ where
240242
self
241243
}
242244

245+
/// Sets the [`text::Ellipsize`] strategy of the [`Radio`] button.
246+
pub fn text_ellipsize(mut self, ellipsize: text::Ellipsize) -> Self {
247+
self.text_ellipsize = ellipsize;
248+
self
249+
}
250+
243251
/// Sets the text font of the [`Radio`] button.
244252
pub fn font(mut self, font: impl Into<Renderer::Font>) -> Self {
245253
self.font = Some(font.into());
@@ -316,6 +324,7 @@ where
316324
alignment::Vertical::Top,
317325
self.text_shaping,
318326
self.text_wrapping,
327+
self.text_ellipsize,
319328
)
320329
},
321330
)

0 commit comments

Comments
 (0)