@effindomv2/fui-rs 0.1.8 → 0.1.10

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.
Files changed (37) hide show
  1. package/Cargo.toml +1 -1
  2. package/package.json +1 -1
  3. package/src/bridge_callbacks.rs +1 -0
  4. package/src/controls/appearance.rs +200 -0
  5. package/src/controls/button.rs +48 -122
  6. package/src/controls/checkbox.rs +27 -3
  7. package/src/controls/combobox.rs +61 -23
  8. package/src/controls/context_menu.rs +156 -256
  9. package/src/controls/control_template_set.rs +2 -3
  10. package/src/controls/control_tokens.rs +76 -0
  11. package/src/controls/dialog.rs +80 -78
  12. package/src/controls/dropdown.rs +46 -5
  13. package/src/controls/form.rs +6 -0
  14. package/src/controls/internal/button_presenter.rs +21 -20
  15. package/src/controls/internal/pressable_labeled_control.rs +11 -11
  16. package/src/controls/internal/text_input_core.rs +40 -22
  17. package/src/controls/internal/text_input_presenter.rs +29 -23
  18. package/src/controls/mod.rs +7 -2
  19. package/src/controls/nav_link.rs +25 -19
  20. package/src/controls/popup.rs +24 -40
  21. package/src/controls/progress_bar.rs +80 -109
  22. package/src/controls/radio_button.rs +27 -3
  23. package/src/controls/radio_group.rs +6 -0
  24. package/src/controls/slider.rs +38 -14
  25. package/src/controls/switch.rs +27 -3
  26. package/src/controls/tests.rs +796 -56
  27. package/src/controls/text_area.rs +12 -2
  28. package/src/controls/text_input.rs +19 -3
  29. package/src/lib.rs +44 -38
  30. package/src/node/core.rs +5 -0
  31. package/src/node/flex_box.rs +248 -2
  32. package/src/node/grid.rs +5 -0
  33. package/src/node/mod.rs +48 -0
  34. package/src/node/presenter_host_style.rs +177 -0
  35. package/src/node/scroll_view.rs +3 -0
  36. package/src/node/text_node.rs +42 -0
  37. package/src/popup_presenter.rs +32 -0
@@ -85,16 +85,26 @@ impl TextArea {
85
85
  self
86
86
  }
87
87
 
88
- pub fn colors(&self, colors: Option<TextInputColors>) -> &Self {
88
+ pub fn colors(&self, colors: TextInputColors) -> &Self {
89
89
  self.core.colors(colors);
90
90
  self
91
91
  }
92
92
 
93
- pub fn template(&self, template: Option<Rc<dyn TextInputTemplate>>) -> &Self {
93
+ pub fn clear_colors(&self) -> &Self {
94
+ self.core.clear_colors();
95
+ self
96
+ }
97
+
98
+ pub fn template(&self, template: Rc<dyn TextInputTemplate>) -> &Self {
94
99
  self.core.template(template);
95
100
  self
96
101
  }
97
102
 
103
+ pub fn clear_template(&self) -> &Self {
104
+ self.core.clear_template();
105
+ self
106
+ }
107
+
98
108
  pub fn enabled(&self, enabled: bool) -> &Self {
99
109
  self.core.enabled(enabled);
100
110
  self
@@ -7,11 +7,17 @@ use crate::FontFamily;
7
7
  use std::any::Any;
8
8
  use std::rc::Rc;
9
9
 
10
- #[derive(Clone, Default)]
10
+ #[derive(Clone)]
11
11
  pub struct TextInput {
12
12
  core: Rc<TextInputCore>,
13
13
  }
14
14
 
15
+ impl Default for TextInput {
16
+ fn default() -> Self {
17
+ Self::new()
18
+ }
19
+ }
20
+
15
21
  impl TextInput {
16
22
  pub fn new() -> Self {
17
23
  let core = Rc::new(TextInputCore::new());
@@ -94,16 +100,26 @@ impl TextInput {
94
100
  self
95
101
  }
96
102
 
97
- pub fn colors(&self, colors: Option<TextInputColors>) -> &Self {
103
+ pub fn colors(&self, colors: TextInputColors) -> &Self {
98
104
  self.core.colors(colors);
99
105
  self
100
106
  }
101
107
 
102
- pub fn template(&self, template: Option<Rc<dyn TextInputTemplate>>) -> &Self {
108
+ pub fn clear_colors(&self) -> &Self {
109
+ self.core.clear_colors();
110
+ self
111
+ }
112
+
113
+ pub fn template(&self, template: Rc<dyn TextInputTemplate>) -> &Self {
103
114
  self.core.template(template);
104
115
  self
105
116
  }
106
117
 
118
+ pub fn clear_template(&self) -> &Self {
119
+ self.core.clear_template();
120
+ self
121
+ }
122
+
107
123
  pub fn enabled(&self, enabled: bool) -> &Self {
108
124
  self.core.enabled(enabled);
109
125
  self
package/src/lib.rs CHANGED
@@ -361,28 +361,31 @@ pub mod prelude {
361
361
  CheckboxChangedEventArgs, CheckboxIndicatorPresenter, CheckboxIndicatorTemplate,
362
362
  CheckboxIndicatorVisualState, ClickEventArgs, ComboBox, ComboBoxChangedEventArgs,
363
363
  ComboBoxCommitMode, ComboBoxFilterMode, ComboBoxItem, ContextMenu, ContextMenuAction,
364
- ContextMenuVisibilityChangedEventArgs, ControlTemplateSet, DefaultButtonTemplate,
365
- DefaultCheckboxIndicatorTemplate, DefaultDropdownChevronTemplate,
366
- DefaultDropdownFieldTemplate, DefaultDropdownOptionRowTemplate,
367
- DefaultRadioIndicatorTemplate, DefaultSliderTemplate, DefaultSwitchIndicatorTemplate,
368
- DefaultTextInputTemplate, Dialog, DialogShownEventArgs, Dropdown, DropdownChangedEventArgs,
369
- DropdownChevronMetrics, DropdownChevronPresenter, DropdownChevronTemplate,
370
- DropdownChevronVisualState, DropdownColors, DropdownFieldMetrics, DropdownFieldPresenter,
371
- DropdownFieldTemplate, DropdownFieldVisualState, DropdownItem, DropdownOptionRowMetrics,
364
+ ContextMenuAppearance, ContextMenuItemAppearance, ContextMenuVisibilityChangedEventArgs,
365
+ ControlTemplateSet, DefaultButtonTemplate, DefaultCheckboxIndicatorTemplate,
366
+ DefaultDropdownChevronTemplate, DefaultDropdownFieldTemplate,
367
+ DefaultDropdownOptionRowTemplate, DefaultRadioIndicatorTemplate, DefaultSliderTemplate,
368
+ DefaultSwitchIndicatorTemplate, DefaultTextInputTemplate, Dialog, DialogAppearance,
369
+ DialogShownEventArgs, Dropdown, DropdownChangedEventArgs, DropdownChevronMetrics,
370
+ DropdownChevronPresenter, DropdownChevronTemplate, DropdownChevronVisualState,
371
+ DropdownColors, DropdownFieldMetrics, DropdownFieldPresenter, DropdownFieldTemplate,
372
+ DropdownFieldVisualState, DropdownItem, DropdownOptionRowMetrics,
372
373
  DropdownOptionRowPresenter, DropdownOptionRowTemplate, DropdownOptionRowVisualState,
373
374
  DropdownSizing, Form, LabeledControlColors, LabeledControlSizing, LabeledControlTextStyle,
374
- MenuItem, NavLink, NavigateEventArgs, Popup, PressableIndicatorMetrics,
375
- PressableIndicatorPresenter, PressableIndicatorVisualState, ProgressBar, RadioButton,
375
+ MenuItem, NavLink, NavigateEventArgs, OverlayBackdropAppearance, Popup, PopupAppearance,
376
+ PressableIndicatorMetrics, PressableIndicatorPresenter, PressableIndicatorVisualState,
377
+ ProgressBar, ProgressBarColors, ProgressBarSizing, RadioButton,
376
378
  RadioButtonChangedEventArgs, RadioGroup, RadioGroupChangedEventArgs,
377
379
  RadioIndicatorPresenter, RadioIndicatorTemplate, RadioIndicatorVisualState, SelectionArea,
378
380
  Slider, SliderChangedEventArgs, SliderColors, SliderPresenter, SliderPresenterMetrics,
379
- SliderSizing, SliderTemplate, SliderVisualState, Switch, SwitchChangedEventArgs,
380
- SwitchIndicatorPresenter, SwitchIndicatorTemplate, SwitchIndicatorVisualState, TextArea,
381
- TextInput, TextInputColors, TextInputPresenter, TextInputTemplate, TextInputVisualState,
382
- DEFAULT_BUTTON_TEMPLATE, DEFAULT_CHECKBOX_INDICATOR_TEMPLATE,
383
- DEFAULT_DROPDOWN_CHEVRON_TEMPLATE, DEFAULT_DROPDOWN_FIELD_TEMPLATE,
384
- DEFAULT_DROPDOWN_OPTION_ROW_TEMPLATE, DEFAULT_RADIO_INDICATOR_TEMPLATE,
385
- DEFAULT_SLIDER_TEMPLATE, DEFAULT_SWITCH_INDICATOR_TEMPLATE, DEFAULT_TEXT_INPUT_TEMPLATE,
381
+ SliderSizing, SliderTemplate, SliderVisualState, SurfaceAppearance, Switch,
382
+ SwitchChangedEventArgs, SwitchIndicatorPresenter, SwitchIndicatorTemplate,
383
+ SwitchIndicatorVisualState, TextArea, TextInput, TextInputColors, TextInputPresenter,
384
+ TextInputTemplate, TextInputVisualState, DEFAULT_BUTTON_TEMPLATE,
385
+ DEFAULT_CHECKBOX_INDICATOR_TEMPLATE, DEFAULT_DROPDOWN_CHEVRON_TEMPLATE,
386
+ DEFAULT_DROPDOWN_FIELD_TEMPLATE, DEFAULT_DROPDOWN_OPTION_ROW_TEMPLATE,
387
+ DEFAULT_RADIO_INDICATOR_TEMPLATE, DEFAULT_SLIDER_TEMPLATE,
388
+ DEFAULT_SWITCH_INDICATOR_TEMPLATE, DEFAULT_TEXT_INPUT_TEMPLATE,
386
389
  };
387
390
  pub use crate::drag_drop::{
388
391
  DragCompletedEventArgs, DragDataObject, DragDropEffects, DragEventArgs, DragSession,
@@ -418,9 +421,10 @@ pub mod prelude {
418
421
  pub use crate::node::{
419
422
  auto, column, custom_drawable, fill, flex_box, grid, image, pct, portal, px, row,
420
423
  scroll_box, scroll_view, svg, text, viewport_height, viewport_width, virtual_list, Border,
421
- Child, ContextMenuEventArgs, CustomDrawable, FlexBox, FlexBoxSurface, GradientStop, Grid,
422
- GridTrack, HasFlexBoxRoot, Image, ImageNode, Length, Node, ScrollBar, ScrollBarVisibility,
423
- ScrollBox, ScrollState, ScrollView, Svg, SvgNode, Text, TextCore, TextNode, VirtualList,
424
+ Child, ContextMenuEventArgs, Corners, CustomDrawable, EdgeInsets, FlexBox, FlexBoxSurface,
425
+ GradientStop, Grid, GridTrack, HasFlexBoxRoot, Image, ImageNode, Length, Node,
426
+ PresenterHostStyle, ScrollBar, ScrollBarVisibility, ScrollBox, ScrollState, ScrollView,
427
+ Shadow, Svg, SvgNode, Text, TextCore, TextNode, VirtualList,
424
428
  };
425
429
  pub use crate::persisted;
426
430
  pub use crate::platform;
@@ -477,24 +481,25 @@ pub use controls::{
477
481
  ButtonTemplate, ButtonVisualState, CheckState, Checkbox, CheckboxChangedEventArgs,
478
482
  CheckboxIndicatorPresenter, CheckboxIndicatorTemplate, CheckboxIndicatorVisualState,
479
483
  ClickEventArgs, ComboBox, ComboBoxChangedEventArgs, ComboBoxCommitMode, ComboBoxFilterMode,
480
- ComboBoxItem, ContextMenu, ContextMenuAction, ContextMenuVisibilityChangedEventArgs,
481
- ControlTemplateSet, DefaultButtonTemplate, DefaultCheckboxIndicatorTemplate,
482
- DefaultDropdownChevronTemplate, DefaultDropdownFieldTemplate, DefaultDropdownOptionRowTemplate,
483
- DefaultRadioIndicatorTemplate, DefaultSliderTemplate, DefaultSwitchIndicatorTemplate,
484
- DefaultTextInputTemplate, Dialog, DialogShownEventArgs, Dropdown, DropdownChangedEventArgs,
485
- DropdownChevronMetrics, DropdownChevronPresenter, DropdownChevronTemplate,
486
- DropdownChevronVisualState, DropdownColors, DropdownFieldMetrics, DropdownFieldPresenter,
487
- DropdownFieldTemplate, DropdownFieldVisualState, DropdownItem, DropdownOptionRowMetrics,
488
- DropdownOptionRowPresenter, DropdownOptionRowTemplate, DropdownOptionRowVisualState,
489
- DropdownSizing, Form, LabeledControlColors, LabeledControlSizing, MenuItem, NavLink,
490
- NavigateEventArgs, Popup, PressableIndicatorMetrics, PressableIndicatorPresenter,
491
- PressableIndicatorVisualState, ProgressBar, RadioButton, RadioButtonChangedEventArgs,
484
+ ComboBoxItem, ContextMenu, ContextMenuAction, ContextMenuAppearance, ContextMenuItemAppearance,
485
+ ContextMenuVisibilityChangedEventArgs, ControlTemplateSet, DefaultButtonTemplate,
486
+ DefaultCheckboxIndicatorTemplate, DefaultDropdownChevronTemplate, DefaultDropdownFieldTemplate,
487
+ DefaultDropdownOptionRowTemplate, DefaultRadioIndicatorTemplate, DefaultSliderTemplate,
488
+ DefaultSwitchIndicatorTemplate, DefaultTextInputTemplate, Dialog, DialogAppearance,
489
+ DialogShownEventArgs, Dropdown, DropdownChangedEventArgs, DropdownChevronMetrics,
490
+ DropdownChevronPresenter, DropdownChevronTemplate, DropdownChevronVisualState, DropdownColors,
491
+ DropdownFieldMetrics, DropdownFieldPresenter, DropdownFieldTemplate, DropdownFieldVisualState,
492
+ DropdownItem, DropdownOptionRowMetrics, DropdownOptionRowPresenter, DropdownOptionRowTemplate,
493
+ DropdownOptionRowVisualState, DropdownSizing, Form, LabeledControlColors, LabeledControlSizing,
494
+ MenuItem, NavLink, NavigateEventArgs, OverlayBackdropAppearance, Popup, PopupAppearance,
495
+ PressableIndicatorMetrics, PressableIndicatorPresenter, PressableIndicatorVisualState,
496
+ ProgressBar, ProgressBarColors, ProgressBarSizing, RadioButton, RadioButtonChangedEventArgs,
492
497
  RadioGroup, RadioGroupChangedEventArgs, RadioIndicatorPresenter, RadioIndicatorTemplate,
493
498
  RadioIndicatorVisualState, SelectionArea, Slider, SliderChangedEventArgs, SliderColors,
494
499
  SliderPresenter, SliderPresenterMetrics, SliderSizing, SliderTemplate, SliderVisualState,
495
- Switch, SwitchChangedEventArgs, SwitchIndicatorPresenter, SwitchIndicatorTemplate,
496
- SwitchIndicatorVisualState, TextArea, TextInput, TextInputColors, TextInputPresenter,
497
- TextInputTemplate, TextInputVisualState, DEFAULT_BUTTON_TEMPLATE,
500
+ SurfaceAppearance, Switch, SwitchChangedEventArgs, SwitchIndicatorPresenter,
501
+ SwitchIndicatorTemplate, SwitchIndicatorVisualState, TextArea, TextInput, TextInputColors,
502
+ TextInputPresenter, TextInputTemplate, TextInputVisualState, DEFAULT_BUTTON_TEMPLATE,
498
503
  DEFAULT_CHECKBOX_INDICATOR_TEMPLATE, DEFAULT_DROPDOWN_CHEVRON_TEMPLATE,
499
504
  DEFAULT_DROPDOWN_FIELD_TEMPLATE, DEFAULT_DROPDOWN_OPTION_ROW_TEMPLATE,
500
505
  DEFAULT_RADIO_INDICATOR_TEMPLATE, DEFAULT_SLIDER_TEMPLATE, DEFAULT_SWITCH_INDICATOR_TEMPLATE,
@@ -534,9 +539,10 @@ pub use navigation::*;
534
539
  pub use node::{
535
540
  auto, column, custom_drawable, fill, flex_box, grid, image, pct, portal, px, row, scroll_box,
536
541
  scroll_view, svg, text, viewport_height, viewport_width, virtual_list, Border, Child,
537
- ContextMenuEventArgs, CustomDrawable, FlexBox, FlexBoxSurface, GradientStop, Grid, GridTrack,
538
- HasFlexBoxRoot, Image, ImageNode, Length, Node, ScrollBar, ScrollBarVisibility, ScrollBox,
539
- ScrollState, ScrollView, Svg, SvgNode, Text, TextCore, TextNode, VirtualList,
542
+ ContextMenuEventArgs, Corners, CustomDrawable, EdgeInsets, FlexBox, FlexBoxSurface,
543
+ GradientStop, Grid, GridTrack, HasFlexBoxRoot, Image, ImageNode, Length, Node,
544
+ PresenterHostStyle, ScrollBar, ScrollBarVisibility, ScrollBox, ScrollState, ScrollView, Shadow,
545
+ Svg, SvgNode, Text, TextCore, TextNode, VirtualList,
540
546
  };
541
547
  pub use persisted::*;
542
548
  pub use platform::*;
package/src/node/core.rs CHANGED
@@ -494,6 +494,7 @@ pub(crate) struct WeakFlexBox {
494
494
  pub(crate) core: Weak<RefCell<NodeCore>>,
495
495
  pub(crate) props: Weak<RefCell<FlexBoxProps>>,
496
496
  pub(crate) active_animations: Weak<RefCell<crate::node::flex_box::FlexBoxAnimations>>,
497
+ pub(crate) host_style_layers: Weak<RefCell<crate::node::HostStyleLayers>>,
497
498
  }
498
499
 
499
500
  impl WeakFlexBox {
@@ -502,6 +503,7 @@ impl WeakFlexBox {
502
503
  core: self.core.upgrade()?,
503
504
  props: self.props.upgrade()?,
504
505
  active_animations: self.active_animations.upgrade()?,
506
+ host_style_layers: self.host_style_layers.upgrade()?,
505
507
  })
506
508
  }
507
509
  }
@@ -1789,6 +1791,9 @@ pub trait Node: Clone {
1789
1791
  Self: Sized,
1790
1792
  {
1791
1793
  let node_ref = self.node_ref();
1794
+ if enabled {
1795
+ node_ref.require_interactive();
1796
+ }
1792
1797
  let mut core = node_ref.inner.borrow_mut();
1793
1798
  core.behavior.focusable = Some((enabled, tab_index));
1794
1799
  let interactive = core.behavior.enabled && core.behavior.inherited_enabled;
@@ -14,6 +14,7 @@ pub struct FlexBox {
14
14
  pub(crate) core: Rc<RefCell<NodeCore>>,
15
15
  pub(crate) props: Rc<RefCell<FlexBoxProps>>,
16
16
  pub(crate) active_animations: Rc<RefCell<FlexBoxAnimations>>,
17
+ pub(crate) host_style_layers: Rc<RefCell<HostStyleLayers>>,
17
18
  }
18
19
 
19
20
  impl Default for FlexBox {
@@ -24,6 +25,7 @@ impl Default for FlexBox {
24
25
  core: Rc::new(RefCell::new(core)),
25
26
  props: Rc::new(RefCell::new(FlexBoxProps::default())),
26
27
  active_animations: Rc::new(RefCell::new(FlexBoxAnimations::default())),
28
+ host_style_layers: Rc::new(RefCell::new(HostStyleLayers::default())),
27
29
  }
28
30
  }
29
31
  }
@@ -99,6 +101,7 @@ impl FlexBox {
99
101
  core: Rc::downgrade(&self.core),
100
102
  props: Rc::downgrade(&self.props),
101
103
  active_animations: Rc::downgrade(&self.active_animations),
104
+ host_style_layers: Rc::downgrade(&self.host_style_layers),
102
105
  }
103
106
  }
104
107
 
@@ -207,6 +210,11 @@ impl FlexBox {
207
210
  }
208
211
 
209
212
  pub fn bg_color(&self, color: u32) -> &Self {
213
+ self.host_style_layers.borrow_mut().local.background = Some(color);
214
+ self.set_effective_background_color(color)
215
+ }
216
+
217
+ fn set_effective_background_color(&self, color: u32) -> &Self {
210
218
  self.cancel_background_color_transition();
211
219
  if self.should_animate_background_color(color) {
212
220
  let timing = {
@@ -233,6 +241,8 @@ impl FlexBox {
233
241
  }
234
242
 
235
243
  pub fn padding(&self, left: f32, top: f32, right: f32, bottom: f32) -> &Self {
244
+ self.host_style_layers.borrow_mut().local.padding =
245
+ Some(EdgeInsets::new(left, top, right, bottom));
236
246
  self.props.borrow_mut().padding = Some((left, top, right, bottom));
237
247
  if self.has_built_handle() {
238
248
  ui::set_padding(self.handle().raw(), left, top, right, bottom);
@@ -242,6 +252,7 @@ impl FlexBox {
242
252
  }
243
253
 
244
254
  pub fn flex_direction(&self, direction: FlexDirection) -> &Self {
255
+ self.host_style_layers.borrow_mut().local.flex_direction = Some(direction);
245
256
  self.props.borrow_mut().flex_direction = Some(direction);
246
257
  if self.has_built_handle() {
247
258
  ui::set_flex_direction(self.handle().raw(), direction as u32);
@@ -255,6 +266,7 @@ impl FlexBox {
255
266
  }
256
267
 
257
268
  pub fn corners(&self, tl: f32, tr: f32, br: f32, bl: f32) -> &Self {
269
+ self.host_style_layers.borrow_mut().local.corners = Some(Corners::new(tl, tr, br, bl));
258
270
  let existing = self.props.borrow().box_style.unwrap_or(BoxStyle {
259
271
  radius_tl: 0.0,
260
272
  radius_tr: 0.0,
@@ -285,6 +297,7 @@ impl FlexBox {
285
297
  }
286
298
 
287
299
  pub fn border_config(&self, border: Border) -> &Self {
300
+ self.host_style_layers.borrow_mut().local.border = Some(border);
288
301
  let existing = self.props.borrow().box_style.unwrap_or(BoxStyle {
289
302
  radius_tl: 0.0,
290
303
  radius_tr: 0.0,
@@ -313,6 +326,11 @@ impl FlexBox {
313
326
 
314
327
  pub fn opacity(&self, value: f32) -> &Self {
315
328
  let value = value.clamp(0.0, 1.0);
329
+ self.host_style_layers.borrow_mut().local.opacity = Some(value);
330
+ self.set_effective_opacity(value)
331
+ }
332
+
333
+ fn set_effective_opacity(&self, value: f32) -> &Self {
316
334
  self.cancel_opacity_transition();
317
335
  if self.should_animate_opacity(value) {
318
336
  let timing = {
@@ -360,6 +378,8 @@ impl FlexBox {
360
378
  blur_sigma: f32,
361
379
  spread: f32,
362
380
  ) -> &Self {
381
+ self.host_style_layers.borrow_mut().local.shadow =
382
+ Some(Shadow::new(color, offset_x, offset_y, blur_sigma, spread));
363
383
  self.props.borrow_mut().drop_shadow = Some(DropShadow {
364
384
  color,
365
385
  offset_x,
@@ -456,6 +476,9 @@ impl FlexBox {
456
476
  }
457
477
 
458
478
  pub fn focusable(&self, enabled: bool, tab_index: i32) -> &Self {
479
+ if enabled {
480
+ self.retained_node_ref().require_interactive();
481
+ }
459
482
  let mut core = self.core.borrow_mut();
460
483
  core.behavior.focusable = Some((enabled, tab_index));
461
484
  let interactive = core.behavior.enabled && core.behavior.inherited_enabled;
@@ -469,6 +492,7 @@ impl FlexBox {
469
492
  }
470
493
 
471
494
  pub fn cursor(&self, style: CursorStyle) -> &Self {
495
+ self.host_style_layers.borrow_mut().local.cursor = Some(style);
472
496
  self.core.borrow_mut().behavior.cursor = Some(style);
473
497
  crate::event::handle_cursor_style_changed(self.handle());
474
498
  self
@@ -491,9 +515,15 @@ impl FlexBox {
491
515
  }
492
516
 
493
517
  fn apply_animated_opacity(&self, value: f32) {
494
- self.props.borrow_mut().opacity = Some(value.clamp(0.0, 1.0));
518
+ let value = value.clamp(0.0, 1.0);
519
+ self.props.borrow_mut().opacity = Some(value);
495
520
  if self.has_built_handle() {
496
- self.build_self();
521
+ ui::set_layer_effect(
522
+ self.handle().raw(),
523
+ value,
524
+ self.props.borrow().blur_sigma.unwrap_or(0.0),
525
+ 0,
526
+ );
497
527
  self.notify_retained_mutation();
498
528
  }
499
529
  }
@@ -699,11 +729,13 @@ impl FlexBox {
699
729
  }
700
730
 
701
731
  pub fn justify_content(&self, justify: JustifyContent) -> &Self {
732
+ self.host_style_layers.borrow_mut().local.justify_content = Some(justify);
702
733
  self.core.borrow_mut().behavior.justify_content = Some(justify);
703
734
  self
704
735
  }
705
736
 
706
737
  pub fn align_items(&self, align: AlignItems) -> &Self {
738
+ self.host_style_layers.borrow_mut().local.align_items = Some(align);
707
739
  self.core.borrow_mut().behavior.align_items = Some(align);
708
740
  self
709
741
  }
@@ -718,6 +750,220 @@ impl FlexBox {
718
750
  self
719
751
  }
720
752
 
753
+ pub fn apply_presenter_style(&self, style: PresenterHostStyle) -> &Self {
754
+ let previous = self.host_style_layers.borrow().resolved();
755
+ self.host_style_layers.borrow_mut().presenter = style;
756
+ self.sync_resolved_host_style_if_changed(previous);
757
+ self
758
+ }
759
+
760
+ pub fn clear_presenter_style(&self) -> &Self {
761
+ self.apply_presenter_style(PresenterHostStyle::new())
762
+ }
763
+
764
+ pub fn clear_bg_color(&self) -> &Self {
765
+ self.clear_local_host_style(|style| style.background = None)
766
+ }
767
+
768
+ pub fn clear_padding(&self) -> &Self {
769
+ self.clear_local_host_style(|style| style.padding = None)
770
+ }
771
+
772
+ pub fn clear_corners(&self) -> &Self {
773
+ self.clear_local_host_style(|style| style.corners = None)
774
+ }
775
+
776
+ pub fn clear_border(&self) -> &Self {
777
+ self.clear_local_host_style(|style| style.border = None)
778
+ }
779
+
780
+ pub fn clear_drop_shadow(&self) -> &Self {
781
+ self.clear_local_host_style(|style| style.shadow = None)
782
+ }
783
+
784
+ pub fn clear_opacity(&self) -> &Self {
785
+ self.clear_local_host_style(|style| style.opacity = None)
786
+ }
787
+
788
+ pub fn clear_flex_direction(&self) -> &Self {
789
+ self.clear_local_host_style(|style| style.flex_direction = None)
790
+ }
791
+
792
+ pub fn clear_justify_content(&self) -> &Self {
793
+ self.clear_local_host_style(|style| style.justify_content = None)
794
+ }
795
+
796
+ pub fn clear_align_items(&self) -> &Self {
797
+ self.clear_local_host_style(|style| style.align_items = None)
798
+ }
799
+
800
+ pub fn clear_cursor(&self) -> &Self {
801
+ self.clear_local_host_style(|style| style.cursor = None)
802
+ }
803
+
804
+ pub fn resolved_host_style(&self) -> PresenterHostStyle {
805
+ self.host_style_layers.borrow().resolved()
806
+ }
807
+
808
+ fn clear_local_host_style(&self, clear: impl FnOnce(&mut PresenterHostStyle)) -> &Self {
809
+ let previous = self.host_style_layers.borrow().resolved();
810
+ clear(&mut self.host_style_layers.borrow_mut().local);
811
+ self.sync_resolved_host_style_if_changed(previous);
812
+ self
813
+ }
814
+
815
+ fn sync_resolved_host_style_if_changed(&self, previous: PresenterHostStyle) {
816
+ let resolved = self.host_style_layers.borrow().resolved();
817
+ if resolved == previous {
818
+ return;
819
+ }
820
+ self.sync_resolved_host_style(previous, resolved);
821
+ }
822
+
823
+ fn sync_resolved_host_style(&self, previous: PresenterHostStyle, resolved: PresenterHostStyle) {
824
+ let background_changed = previous.background != resolved.background;
825
+ let padding_changed = previous.padding != resolved.padding;
826
+ let flex_direction_changed = previous.flex_direction != resolved.flex_direction;
827
+ let justify_content_changed = previous.justify_content != resolved.justify_content;
828
+ let align_items_changed = previous.align_items != resolved.align_items;
829
+ let box_style_changed =
830
+ previous.corners != resolved.corners || previous.border != resolved.border;
831
+ let opacity_changed = previous.opacity != resolved.opacity;
832
+ let shadow_changed = previous.shadow != resolved.shadow;
833
+ let cursor_changed = previous.cursor != resolved.cursor;
834
+
835
+ {
836
+ let mut props = self.props.borrow_mut();
837
+ props.padding = resolved
838
+ .padding
839
+ .map(|value| (value.left, value.top, value.right, value.bottom));
840
+ props.flex_direction = resolved.flex_direction;
841
+ props.opacity = resolved.opacity;
842
+ props.drop_shadow = resolved.shadow.map(|value| DropShadow {
843
+ color: value.color,
844
+ offset_x: value.offset_x,
845
+ offset_y: value.offset_y,
846
+ blur_sigma: value.blur_sigma,
847
+ spread: value.spread,
848
+ });
849
+ props.box_style = if resolved.corners.is_some() || resolved.border.is_some() {
850
+ let corners = resolved.corners.unwrap_or_else(|| Corners::all(0.0));
851
+ let border = resolved
852
+ .border
853
+ .unwrap_or_else(|| Border::solid(0.0, 0x00000000));
854
+ Some(BoxStyle {
855
+ radius_tl: corners.top_left,
856
+ radius_tr: corners.top_right,
857
+ radius_br: corners.bottom_right,
858
+ radius_bl: corners.bottom_left,
859
+ border_width: border.width,
860
+ border_color: border.color,
861
+ border_style: border.style,
862
+ border_dash_on: border.dash_on,
863
+ border_dash_off: border.dash_off,
864
+ })
865
+ } else {
866
+ None
867
+ };
868
+ }
869
+ {
870
+ let mut core = self.core.borrow_mut();
871
+ core.behavior.justify_content = resolved.justify_content;
872
+ core.behavior.align_items = resolved.align_items;
873
+ core.behavior.cursor = resolved.cursor;
874
+ }
875
+ if !self.has_built_handle() {
876
+ self.props.borrow_mut().bg_color = resolved.background;
877
+ self.props.borrow_mut().opacity = resolved.opacity;
878
+ return;
879
+ }
880
+
881
+ let handle = self.handle().raw();
882
+ let mut direct_native_change = false;
883
+ if box_style_changed {
884
+ let corners = resolved.corners.unwrap_or_else(|| Corners::all(0.0));
885
+ let border = resolved
886
+ .border
887
+ .unwrap_or_else(|| Border::solid(0.0, 0x00000000));
888
+ ui::set_box_style(
889
+ handle,
890
+ if background_changed {
891
+ previous.background.unwrap_or(0x00000000)
892
+ } else {
893
+ resolved.background.unwrap_or(0x00000000)
894
+ },
895
+ corners.top_left,
896
+ corners.top_right,
897
+ corners.bottom_right,
898
+ corners.bottom_left,
899
+ border.width,
900
+ border.color,
901
+ border.style as u32,
902
+ border.dash_on,
903
+ border.dash_off,
904
+ );
905
+ direct_native_change = true;
906
+ }
907
+ if padding_changed {
908
+ let padding = resolved.padding.unwrap_or_else(|| EdgeInsets::all(0.0));
909
+ ui::set_padding(
910
+ handle,
911
+ padding.left,
912
+ padding.top,
913
+ padding.right,
914
+ padding.bottom,
915
+ );
916
+ direct_native_change = true;
917
+ }
918
+ if flex_direction_changed {
919
+ ui::set_flex_direction(
920
+ handle,
921
+ resolved.flex_direction.unwrap_or(FlexDirection::Column) as u32,
922
+ );
923
+ direct_native_change = true;
924
+ }
925
+ if justify_content_changed {
926
+ ui::set_justify_content(
927
+ handle,
928
+ resolved.justify_content.unwrap_or(JustifyContent::Start) as u32,
929
+ );
930
+ direct_native_change = true;
931
+ }
932
+ if align_items_changed {
933
+ ui::set_align_items(
934
+ handle,
935
+ resolved.align_items.unwrap_or(AlignItems::Stretch) as u32,
936
+ );
937
+ direct_native_change = true;
938
+ }
939
+ if shadow_changed {
940
+ let shadow = resolved
941
+ .shadow
942
+ .unwrap_or_else(|| Shadow::new(0x00000000, 0.0, 0.0, 0.0, 0.0));
943
+ ui::set_drop_shadow(
944
+ handle,
945
+ shadow.color,
946
+ shadow.offset_x,
947
+ shadow.offset_y,
948
+ shadow.blur_sigma,
949
+ shadow.spread,
950
+ );
951
+ direct_native_change = true;
952
+ }
953
+ if cursor_changed {
954
+ crate::event::handle_cursor_style_changed(self.handle());
955
+ }
956
+ if direct_native_change {
957
+ self.notify_retained_mutation();
958
+ }
959
+ if background_changed {
960
+ self.set_effective_background_color(resolved.background.unwrap_or(0x00000000));
961
+ }
962
+ if opacity_changed {
963
+ self.set_effective_opacity(resolved.opacity.unwrap_or(1.0));
964
+ }
965
+ }
966
+
721
967
  pub fn position_type(&self, position_type: PositionType) -> &Self {
722
968
  self.core.borrow_mut().behavior.position_type = Some(position_type);
723
969
  if self.has_built_handle() {
package/src/node/grid.rs CHANGED
@@ -139,6 +139,11 @@ impl Grid {
139
139
  self
140
140
  }
141
141
 
142
+ pub fn corners(&self, tl: f32, tr: f32, br: f32, bl: f32) -> &Self {
143
+ self.base.corners(tl, tr, br, bl);
144
+ self
145
+ }
146
+
142
147
  pub fn cursor(&self, style: CursorStyle) -> &Self {
143
148
  self.base.cursor(style);
144
149
  self