1#![forbid(unsafe_code)]
7#![forbid(missing_docs)]
8#![deny(clippy::pedantic)]
9
10use egui::{
11 CornerRadius, FontId, Frame, Margin, Stroke, Style, Vec2, Visuals,
12 epaint::Shadow,
13 style::{Interaction, ScrollStyle, Spacing, TextCursorStyle, WidgetVisuals, Widgets},
14};
15
16pub trait EguiScale {
18 fn scale(&mut self, scale: f32);
20
21 #[inline]
23 #[must_use]
24 fn scaled(mut self, scale: f32) -> Self
25 where
26 Self: Sized,
27 {
28 self.scale(scale);
29 self
30 }
31}
32
33impl EguiScale for f32 {
34 #[inline]
35 fn scale(&mut self, scale: f32) {
36 *self *= scale;
37 }
38}
39
40impl EguiScale for u8 {
41 #[inline]
42 fn scale(&mut self, scale: f32) {
43 #![allow(clippy::cast_possible_truncation)]
44 #![allow(clippy::cast_sign_loss)]
45
46 *self = (f32::from(*self) * scale) as u8;
47 }
48}
49
50impl EguiScale for i8 {
51 #[inline]
52 fn scale(&mut self, scale: f32) {
53 #![allow(clippy::cast_possible_truncation)]
54
55 *self = (f32::from(*self) * scale) as i8;
56 }
57}
58
59impl EguiScale for Vec2 {
60 #[inline]
61 fn scale(&mut self, scale: f32) {
62 *self *= scale;
63 }
64}
65
66impl EguiScale for CornerRadius {
67 #[inline]
68 fn scale(&mut self, scale: f32) {
69 self.nw.scale(scale);
70 self.ne.scale(scale);
71 self.se.scale(scale);
72 self.sw.scale(scale);
73 }
74}
75
76impl EguiScale for Margin {
77 #[inline]
78 fn scale(&mut self, scale: f32) {
79 self.left.scale(scale);
80 self.right.scale(scale);
81 self.top.scale(scale);
82 self.bottom.scale(scale);
83 }
84}
85
86impl<T: EguiScale> EguiScale for [T] {
87 #[inline]
88 fn scale(&mut self, scale: f32) {
89 for value in self.iter_mut() {
90 value.scale(scale);
91 }
92 }
93}
94
95impl EguiScale for Shadow {
96 #[inline]
97 fn scale(&mut self, scale: f32) {
98 self.offset.scale(scale);
99 self.blur.scale(scale);
100 self.spread.scale(scale);
101 }
102}
103
104impl EguiScale for Stroke {
105 #[inline]
106 fn scale(&mut self, scale: f32) {
107 self.width *= scale;
108 if self.width < 1.0 {
109 self.color.gamma_multiply(self.width);
110 self.width = 1.0;
111 }
112 }
113}
114
115impl EguiScale for WidgetVisuals {
116 #[inline]
117 fn scale(&mut self, scale: f32) {
118 self.bg_stroke.scale(scale);
119 self.corner_radius.scale(scale);
120 self.fg_stroke.scale(scale);
121 self.expansion.scale(scale);
122 }
123}
124
125impl EguiScale for Interaction {
126 #[inline]
127 fn scale(&mut self, scale: f32) {
128 self.resize_grab_radius_corner.scale(scale);
129 self.resize_grab_radius_side.scale(scale);
130 }
131}
132
133impl EguiScale for Widgets {
134 #[inline]
135 fn scale(&mut self, scale: f32) {
136 self.noninteractive.scale(scale);
137 self.inactive.scale(scale);
138 self.hovered.scale(scale);
139 self.active.scale(scale);
140 self.open.scale(scale);
141 }
142}
143
144impl EguiScale for TextCursorStyle {
145 #[inline]
146 fn scale(&mut self, scale: f32) {
147 self.stroke.scale(scale);
148 }
149}
150
151impl EguiScale for Visuals {
152 #[inline]
153 fn scale(&mut self, scale: f32) {
154 self.clip_rect_margin.scale(scale);
155 self.menu_corner_radius.scale(scale);
156 self.popup_shadow.scale(scale);
157 self.resize_corner_size.scale(scale);
158 self.selection.stroke.scale(scale);
159 self.text_cursor.scale(scale);
160 self.widgets.scale(scale);
161 self.window_corner_radius.scale(scale);
162 self.window_shadow.scale(scale);
163 self.window_stroke.scale(scale);
164 }
165}
166
167impl EguiScale for ScrollStyle {
168 #[inline]
169 fn scale(&mut self, scale: f32) {
170 self.bar_inner_margin.scale(scale);
171 self.bar_outer_margin.scale(scale);
172 self.bar_width.scale(scale);
173 self.floating_allocated_width.scale(scale);
174 self.floating_width.scale(scale);
175 self.handle_min_length.scale(scale);
176 }
177}
178
179impl EguiScale for Spacing {
180 #[inline]
181 fn scale(&mut self, scale: f32) {
182 self.button_padding.scale(scale);
183 self.combo_height.scale(scale);
184 self.combo_width.scale(scale);
185 self.icon_spacing.scale(scale);
186 self.icon_width.scale(scale);
187 self.icon_width_inner.scale(scale);
188 self.indent.scale(scale);
189 self.interact_size.scale(scale);
190 self.item_spacing.scale(scale);
191 self.menu_margin.scale(scale);
192 self.scroll.scale(scale);
193 self.slider_width.scale(scale);
194 self.text_edit_width.scale(scale);
195 self.tooltip_width.scale(scale);
196 self.window_margin.scale(scale);
197 }
198}
199
200impl EguiScale for FontId {
201 fn scale(&mut self, scale: f32) {
202 self.size.scale(scale);
203 }
204}
205
206impl EguiScale for Style {
207 #[inline]
208 fn scale(&mut self, scale: f32) {
209 if let Some(font_id) = &mut self.override_font_id {
210 font_id.scale(scale);
211 }
212 for font_id in self.text_styles.values_mut() {
213 font_id.scale(scale);
214 }
215 self.interaction.scale(scale);
216 self.spacing.scale(scale);
217 self.visuals.scale(scale);
218 }
219}
220
221impl<T> EguiScale for Option<T>
222where
223 T: EguiScale,
224{
225 #[inline]
226 fn scale(&mut self, scale: f32) {
227 if let Some(value) = self {
228 value.scale(scale);
229 }
230 }
231}
232
233impl EguiScale for Frame {
234 #[inline]
235 fn scale(&mut self, scale: f32) {
236 self.inner_margin.scale(scale);
237 self.outer_margin.scale(scale);
238 self.corner_radius.scale(scale);
239 self.shadow.scale(scale);
240 self.stroke.scale(scale);
241 }
242}