veloren_voxygen/ui/ice/widget/
fill_text.rs1use iced::{Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget, layout};
2use std::hash::Hash;
3
4const DEFAULT_FILL_FRACTION: f32 = 1.0;
5const DEFAULT_VERTICAL_ADJUSTMENT: f32 = 0.05;
6
7pub struct FillText<R>
12where
13 R: iced::text::Renderer,
14{
15 fill_fraction: f32,
18 vertical_adjustment: f32,
23 text: iced::Text<R>,
24}
25
26impl<R> FillText<R>
27where
28 R: iced::text::Renderer,
29{
30 pub fn new(label: impl Into<String>) -> Self {
31 Self {
32 fill_fraction: DEFAULT_FILL_FRACTION,
34 vertical_adjustment: DEFAULT_VERTICAL_ADJUSTMENT,
35 text: iced::Text::new(label),
36 }
37 }
38
39 #[must_use]
40 pub fn fill_fraction(mut self, fraction: f32) -> Self {
41 self.fill_fraction = fraction;
42 self
43 }
44
45 #[must_use]
46 pub fn vertical_adjustment(mut self, adjustment: f32) -> Self {
47 self.vertical_adjustment = adjustment;
48 self
49 }
50
51 #[must_use]
52 pub fn color(mut self, color: impl Into<iced::Color>) -> Self {
53 self.text = self.text.color(color);
54 self
55 }
56
57 #[must_use]
58 pub fn font(mut self, font: impl Into<R::Font>) -> Self {
59 self.text = self.text.font(font);
60 self
61 }
62}
63
64impl<M, R> Widget<M, R> for FillText<R>
65where
66 R: iced::text::Renderer,
67{
68 fn width(&self) -> Length { Length::Fill }
69
70 fn height(&self) -> Length { Length::Fill }
71
72 fn layout(&self, renderer: &R, limits: &layout::Limits) -> layout::Node {
73 let limits = limits.width(Length::Fill).height(Length::Fill);
74
75 let size = limits.max();
76
77 let font_size = (size.height * self.fill_fraction) as u16;
78
79 let mut text =
80 Widget::<M, _>::layout(&self.text.clone().size(font_size), renderer, &limits);
81
82 text.align(
84 iced::Align::Center,
85 iced::Align::Center,
86 Size::new(
87 size.width,
88 size.height - 2.0 * font_size as f32 * self.vertical_adjustment,
89 ),
90 );
91
92 layout::Node::with_children(size, vec![text])
93 }
94
95 fn draw(
96 &self,
97 renderer: &mut R,
98 defaults: &R::Defaults,
99 layout: Layout<'_>,
100 cursor_position: Point,
101 viewport: &Rectangle,
102 ) -> R::Output {
103 let font_size = (layout.bounds().height * self.fill_fraction) as u16;
105 Widget::<M, _>::draw(
106 &self.text.clone().size(font_size),
107 renderer,
108 defaults,
109 layout.children().next().unwrap(),
110 cursor_position,
111 viewport,
112 )
113 }
114
115 fn hash_layout(&self, state: &mut Hasher) {
116 struct Marker;
117 std::any::TypeId::of::<Marker>().hash(state);
118
119 self.fill_fraction.to_bits().hash(state);
120 self.vertical_adjustment.to_bits().hash(state);
121 Widget::<M, R>::hash_layout(&self.text, state);
122 }
123}
124
125impl<'a, M, R> From<FillText<R>> for Element<'a, M, R>
126where
127 R: 'a + iced::text::Renderer,
128{
129 fn from(fill_text: FillText<R>) -> Element<'a, M, R> { Element::new(fill_text) }
130}