@effindomv2/fui-rs 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +1 -1
- package/package.json +1 -1
- package/src/bridge_callbacks.rs +1 -0
- package/src/controls/appearance.rs +200 -0
- package/src/controls/button.rs +48 -122
- package/src/controls/checkbox.rs +27 -3
- package/src/controls/combobox.rs +61 -23
- package/src/controls/context_menu.rs +156 -256
- package/src/controls/control_template_set.rs +2 -3
- package/src/controls/control_tokens.rs +76 -0
- package/src/controls/dialog.rs +80 -78
- package/src/controls/dropdown.rs +46 -5
- package/src/controls/form.rs +6 -0
- package/src/controls/internal/button_presenter.rs +21 -20
- package/src/controls/internal/pressable_labeled_control.rs +11 -11
- package/src/controls/internal/text_input_core.rs +40 -22
- package/src/controls/internal/text_input_presenter.rs +29 -23
- package/src/controls/mod.rs +7 -2
- package/src/controls/nav_link.rs +15 -11
- package/src/controls/popup.rs +24 -40
- package/src/controls/progress_bar.rs +80 -109
- package/src/controls/radio_button.rs +27 -3
- package/src/controls/radio_group.rs +6 -0
- package/src/controls/slider.rs +38 -14
- package/src/controls/switch.rs +27 -3
- package/src/controls/tests.rs +796 -56
- package/src/controls/text_area.rs +12 -2
- package/src/controls/text_input.rs +19 -3
- package/src/lib.rs +44 -38
- package/src/node/core.rs +2 -0
- package/src/node/flex_box.rs +245 -2
- package/src/node/grid.rs +5 -0
- package/src/node/mod.rs +48 -0
- package/src/node/presenter_host_style.rs +177 -0
- package/src/node/text_node.rs +35 -0
- package/src/popup_presenter.rs +32 -0
package/src/node/mod.rs
CHANGED
|
@@ -24,6 +24,7 @@ mod flex_box;
|
|
|
24
24
|
mod grid;
|
|
25
25
|
mod helpers;
|
|
26
26
|
mod image;
|
|
27
|
+
mod presenter_host_style;
|
|
27
28
|
mod scroll_bar;
|
|
28
29
|
mod scroll_box;
|
|
29
30
|
mod scroll_state;
|
|
@@ -45,6 +46,8 @@ pub use helpers::{
|
|
|
45
46
|
scroll_view, svg, text, viewport_height, viewport_width, virtual_list, Length,
|
|
46
47
|
};
|
|
47
48
|
pub use image::ImageNode;
|
|
49
|
+
pub(crate) use presenter_host_style::HostStyleLayers;
|
|
50
|
+
pub use presenter_host_style::{Corners, EdgeInsets, PresenterHostStyle, Shadow};
|
|
48
51
|
pub use scroll_bar::{ScrollBar, ScrollBarVisibility};
|
|
49
52
|
pub use scroll_box::ScrollBox;
|
|
50
53
|
pub use scroll_state::ScrollState;
|
|
@@ -170,6 +173,11 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
|
|
|
170
173
|
self
|
|
171
174
|
}
|
|
172
175
|
|
|
176
|
+
fn clear_padding(&self) -> &Self {
|
|
177
|
+
self.flex_box_root().clear_padding();
|
|
178
|
+
self
|
|
179
|
+
}
|
|
180
|
+
|
|
173
181
|
fn margin(&self, left: f32, top: f32, right: f32, bottom: f32) -> &Self {
|
|
174
182
|
self.flex_box_root().margin(left, top, right, bottom);
|
|
175
183
|
self
|
|
@@ -180,6 +188,11 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
|
|
|
180
188
|
self
|
|
181
189
|
}
|
|
182
190
|
|
|
191
|
+
fn clear_corners(&self) -> &Self {
|
|
192
|
+
self.flex_box_root().clear_corners();
|
|
193
|
+
self
|
|
194
|
+
}
|
|
195
|
+
|
|
183
196
|
fn corners(&self, tl: f32, tr: f32, br: f32, bl: f32) -> &Self {
|
|
184
197
|
self.flex_box_root().corners(tl, tr, br, bl);
|
|
185
198
|
self
|
|
@@ -195,16 +208,31 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
|
|
|
195
208
|
self
|
|
196
209
|
}
|
|
197
210
|
|
|
211
|
+
fn clear_border(&self) -> &Self {
|
|
212
|
+
self.flex_box_root().clear_border();
|
|
213
|
+
self
|
|
214
|
+
}
|
|
215
|
+
|
|
198
216
|
fn bg_color(&self, color: u32) -> &Self {
|
|
199
217
|
self.flex_box_root().bg_color(color);
|
|
200
218
|
self
|
|
201
219
|
}
|
|
202
220
|
|
|
221
|
+
fn clear_bg_color(&self) -> &Self {
|
|
222
|
+
self.flex_box_root().clear_bg_color();
|
|
223
|
+
self
|
|
224
|
+
}
|
|
225
|
+
|
|
203
226
|
fn opacity(&self, value: f32) -> &Self {
|
|
204
227
|
self.flex_box_root().opacity(value);
|
|
205
228
|
self
|
|
206
229
|
}
|
|
207
230
|
|
|
231
|
+
fn clear_opacity(&self) -> &Self {
|
|
232
|
+
self.flex_box_root().clear_opacity();
|
|
233
|
+
self
|
|
234
|
+
}
|
|
235
|
+
|
|
208
236
|
fn blur(&self, sigma: f32) -> &Self {
|
|
209
237
|
self.flex_box_root().blur(sigma);
|
|
210
238
|
self
|
|
@@ -223,6 +251,11 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
|
|
|
223
251
|
self
|
|
224
252
|
}
|
|
225
253
|
|
|
254
|
+
fn clear_drop_shadow(&self) -> &Self {
|
|
255
|
+
self.flex_box_root().clear_drop_shadow();
|
|
256
|
+
self
|
|
257
|
+
}
|
|
258
|
+
|
|
226
259
|
fn background_blur(&self, sigma: f32) -> &Self {
|
|
227
260
|
self.flex_box_root().background_blur(sigma);
|
|
228
261
|
self
|
|
@@ -270,11 +303,21 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
|
|
|
270
303
|
self
|
|
271
304
|
}
|
|
272
305
|
|
|
306
|
+
fn clear_justify_content(&self) -> &Self {
|
|
307
|
+
self.flex_box_root().clear_justify_content();
|
|
308
|
+
self
|
|
309
|
+
}
|
|
310
|
+
|
|
273
311
|
fn align_items(&self, align: AlignItems) -> &Self {
|
|
274
312
|
self.flex_box_root().align_items(align);
|
|
275
313
|
self
|
|
276
314
|
}
|
|
277
315
|
|
|
316
|
+
fn clear_align_items(&self) -> &Self {
|
|
317
|
+
self.flex_box_root().clear_align_items();
|
|
318
|
+
self
|
|
319
|
+
}
|
|
320
|
+
|
|
278
321
|
fn align_self(&self, align: AlignSelf) -> &Self {
|
|
279
322
|
self.flex_box_root().align_self(align);
|
|
280
323
|
self
|
|
@@ -305,6 +348,11 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
|
|
|
305
348
|
self
|
|
306
349
|
}
|
|
307
350
|
|
|
351
|
+
fn clear_cursor(&self) -> &Self {
|
|
352
|
+
self.flex_box_root().clear_cursor();
|
|
353
|
+
self
|
|
354
|
+
}
|
|
355
|
+
|
|
308
356
|
fn visibility(&self, visibility: Visibility) -> &Self {
|
|
309
357
|
self.flex_box_root().visibility(visibility);
|
|
310
358
|
self
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
use crate::ffi::{AlignItems, CursorStyle, FlexDirection, JustifyContent};
|
|
2
|
+
use crate::node::Border;
|
|
3
|
+
|
|
4
|
+
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
5
|
+
pub struct EdgeInsets {
|
|
6
|
+
pub left: f32,
|
|
7
|
+
pub top: f32,
|
|
8
|
+
pub right: f32,
|
|
9
|
+
pub bottom: f32,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
impl EdgeInsets {
|
|
13
|
+
pub const fn new(left: f32, top: f32, right: f32, bottom: f32) -> Self {
|
|
14
|
+
Self {
|
|
15
|
+
left,
|
|
16
|
+
top,
|
|
17
|
+
right,
|
|
18
|
+
bottom,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub const fn all(value: f32) -> Self {
|
|
23
|
+
Self::new(value, value, value, value)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
28
|
+
pub struct Corners {
|
|
29
|
+
pub top_left: f32,
|
|
30
|
+
pub top_right: f32,
|
|
31
|
+
pub bottom_right: f32,
|
|
32
|
+
pub bottom_left: f32,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
impl Corners {
|
|
36
|
+
pub const fn new(top_left: f32, top_right: f32, bottom_right: f32, bottom_left: f32) -> Self {
|
|
37
|
+
Self {
|
|
38
|
+
top_left,
|
|
39
|
+
top_right,
|
|
40
|
+
bottom_right,
|
|
41
|
+
bottom_left,
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
pub const fn all(value: f32) -> Self {
|
|
46
|
+
Self::new(value, value, value, value)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
51
|
+
pub struct Shadow {
|
|
52
|
+
pub color: u32,
|
|
53
|
+
pub offset_x: f32,
|
|
54
|
+
pub offset_y: f32,
|
|
55
|
+
pub blur_sigma: f32,
|
|
56
|
+
pub spread: f32,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
impl Shadow {
|
|
60
|
+
pub fn new(color: u32, offset_x: f32, offset_y: f32, blur_sigma: f32, spread: f32) -> Self {
|
|
61
|
+
Self {
|
|
62
|
+
color,
|
|
63
|
+
offset_x,
|
|
64
|
+
offset_y,
|
|
65
|
+
blur_sigma: blur_sigma.max(0.0),
|
|
66
|
+
spread,
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
|
72
|
+
pub struct PresenterHostStyle {
|
|
73
|
+
pub flex_direction: Option<FlexDirection>,
|
|
74
|
+
pub justify_content: Option<JustifyContent>,
|
|
75
|
+
pub align_items: Option<AlignItems>,
|
|
76
|
+
pub background: Option<u32>,
|
|
77
|
+
pub padding: Option<EdgeInsets>,
|
|
78
|
+
pub corners: Option<Corners>,
|
|
79
|
+
pub border: Option<Border>,
|
|
80
|
+
pub shadow: Option<Shadow>,
|
|
81
|
+
pub cursor: Option<CursorStyle>,
|
|
82
|
+
pub opacity: Option<f32>,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
impl PresenterHostStyle {
|
|
86
|
+
pub const fn new() -> Self {
|
|
87
|
+
Self {
|
|
88
|
+
flex_direction: None,
|
|
89
|
+
justify_content: None,
|
|
90
|
+
align_items: None,
|
|
91
|
+
background: None,
|
|
92
|
+
padding: None,
|
|
93
|
+
corners: None,
|
|
94
|
+
border: None,
|
|
95
|
+
shadow: None,
|
|
96
|
+
cursor: None,
|
|
97
|
+
opacity: None,
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
pub fn flex_direction(mut self, value: FlexDirection) -> Self {
|
|
102
|
+
self.flex_direction = Some(value);
|
|
103
|
+
self
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
pub fn justify_content(mut self, value: JustifyContent) -> Self {
|
|
107
|
+
self.justify_content = Some(value);
|
|
108
|
+
self
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
pub fn align_items(mut self, value: AlignItems) -> Self {
|
|
112
|
+
self.align_items = Some(value);
|
|
113
|
+
self
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
pub fn background(mut self, value: u32) -> Self {
|
|
117
|
+
self.background = Some(value);
|
|
118
|
+
self
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
pub fn padding(mut self, value: EdgeInsets) -> Self {
|
|
122
|
+
self.padding = Some(value);
|
|
123
|
+
self
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
pub fn corners(mut self, value: Corners) -> Self {
|
|
127
|
+
self.corners = Some(value);
|
|
128
|
+
self
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
pub fn border(mut self, value: Border) -> Self {
|
|
132
|
+
self.border = Some(value);
|
|
133
|
+
self
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
pub fn shadow(mut self, value: Shadow) -> Self {
|
|
137
|
+
self.shadow = Some(value);
|
|
138
|
+
self
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
pub fn cursor(mut self, value: CursorStyle) -> Self {
|
|
142
|
+
self.cursor = Some(value);
|
|
143
|
+
self
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
pub fn opacity(mut self, value: f32) -> Self {
|
|
147
|
+
self.opacity = Some(value.clamp(0.0, 1.0));
|
|
148
|
+
self
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
pub(crate) fn overlay(self, fallback: Self) -> Self {
|
|
152
|
+
Self {
|
|
153
|
+
flex_direction: self.flex_direction.or(fallback.flex_direction),
|
|
154
|
+
justify_content: self.justify_content.or(fallback.justify_content),
|
|
155
|
+
align_items: self.align_items.or(fallback.align_items),
|
|
156
|
+
background: self.background.or(fallback.background),
|
|
157
|
+
padding: self.padding.or(fallback.padding),
|
|
158
|
+
corners: self.corners.or(fallback.corners),
|
|
159
|
+
border: self.border.or(fallback.border),
|
|
160
|
+
shadow: self.shadow.or(fallback.shadow),
|
|
161
|
+
cursor: self.cursor.or(fallback.cursor),
|
|
162
|
+
opacity: self.opacity.or(fallback.opacity),
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
#[derive(Clone, Copy, Debug, Default)]
|
|
168
|
+
pub(crate) struct HostStyleLayers {
|
|
169
|
+
pub local: PresenterHostStyle,
|
|
170
|
+
pub presenter: PresenterHostStyle,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
impl HostStyleLayers {
|
|
174
|
+
pub fn resolved(self) -> PresenterHostStyle {
|
|
175
|
+
self.local.overlay(self.presenter)
|
|
176
|
+
}
|
|
177
|
+
}
|
package/src/node/text_node.rs
CHANGED
|
@@ -648,6 +648,9 @@ impl Node for TextNode {
|
|
|
648
648
|
}
|
|
649
649
|
|
|
650
650
|
fn build_self(&self) {
|
|
651
|
+
if self.props.borrow().has_font {
|
|
652
|
+
self.resolve_font_id();
|
|
653
|
+
}
|
|
651
654
|
apply_text_props(
|
|
652
655
|
self.handle(),
|
|
653
656
|
&self.props.borrow(),
|
|
@@ -655,3 +658,35 @@ impl Node for TextNode {
|
|
|
655
658
|
);
|
|
656
659
|
}
|
|
657
660
|
}
|
|
661
|
+
|
|
662
|
+
#[cfg(test)]
|
|
663
|
+
mod tests {
|
|
664
|
+
use super::*;
|
|
665
|
+
use crate::ffi::{self, Call};
|
|
666
|
+
use crate::Application;
|
|
667
|
+
|
|
668
|
+
#[test]
|
|
669
|
+
fn prebuild_font_family_weight_and_style_are_resolved_during_build() {
|
|
670
|
+
ffi::test::reset();
|
|
671
|
+
let theme = theme::current_theme();
|
|
672
|
+
let label = TextCore::new("Bold before build");
|
|
673
|
+
label
|
|
674
|
+
.font_family(theme.fonts.body_family)
|
|
675
|
+
.font_weight(FontWeight::Bold)
|
|
676
|
+
.font_style(FontStyle::Normal)
|
|
677
|
+
.font_size(17.0);
|
|
678
|
+
|
|
679
|
+
Application::mount(label.clone());
|
|
680
|
+
let handle = label.handle().raw();
|
|
681
|
+
let calls = ffi::test::take_calls();
|
|
682
|
+
assert!(calls.iter().any(|call| matches!(
|
|
683
|
+
call,
|
|
684
|
+
Call::SetFont {
|
|
685
|
+
handle: call_handle,
|
|
686
|
+
font_id: 2,
|
|
687
|
+
size,
|
|
688
|
+
} if *call_handle == handle && (*size - 17.0).abs() < f32::EPSILON
|
|
689
|
+
)));
|
|
690
|
+
Application::unmount();
|
|
691
|
+
}
|
|
692
|
+
}
|
package/src/popup_presenter.rs
CHANGED
|
@@ -322,6 +322,38 @@ impl PopupPresenter {
|
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
impl PopupPresenterEventTarget {
|
|
325
|
+
pub(crate) fn is_open(&self) -> bool {
|
|
326
|
+
self.state.borrow().open
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
pub(crate) fn surface_x(&self) -> f32 {
|
|
330
|
+
self.state.borrow().surface_x
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
pub(crate) fn surface_y(&self) -> f32 {
|
|
334
|
+
self.state.borrow().surface_y
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
pub(crate) fn backdrop_color(&self, color: u32) {
|
|
338
|
+
self.state.borrow_mut().backdrop_color = color;
|
|
339
|
+
self.apply_backdrop_style();
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
pub(crate) fn background_blur(&self, sigma: f32) {
|
|
343
|
+
self.state.borrow_mut().background_blur_sigma = sigma.max(0.0);
|
|
344
|
+
self.apply_backdrop_style();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
fn apply_backdrop_style(&self) {
|
|
348
|
+
let Some(overlay) = self.overlay_node.upgrade() else {
|
|
349
|
+
return;
|
|
350
|
+
};
|
|
351
|
+
let state = *self.state.borrow();
|
|
352
|
+
overlay
|
|
353
|
+
.bg_color(state.backdrop_color)
|
|
354
|
+
.background_blur(state.background_blur_sigma);
|
|
355
|
+
}
|
|
356
|
+
|
|
325
357
|
pub(crate) fn hide(&self) {
|
|
326
358
|
let Some(root) = self.root.upgrade() else {
|
|
327
359
|
return;
|