@effindomv2/fui-rs 0.1.7 → 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.
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 +15 -11
  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 +2 -0
  31. package/src/node/flex_box.rs +245 -2
  32. package/src/node/grid.rs +5 -0
  33. package/src/node/helpers.rs +6 -3
  34. package/src/node/mod.rs +48 -0
  35. package/src/node/presenter_host_style.rs +177 -0
  36. package/src/node/text_node.rs +35 -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
  }
@@ -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,
@@ -469,6 +489,7 @@ impl FlexBox {
469
489
  }
470
490
 
471
491
  pub fn cursor(&self, style: CursorStyle) -> &Self {
492
+ self.host_style_layers.borrow_mut().local.cursor = Some(style);
472
493
  self.core.borrow_mut().behavior.cursor = Some(style);
473
494
  crate::event::handle_cursor_style_changed(self.handle());
474
495
  self
@@ -491,9 +512,15 @@ impl FlexBox {
491
512
  }
492
513
 
493
514
  fn apply_animated_opacity(&self, value: f32) {
494
- self.props.borrow_mut().opacity = Some(value.clamp(0.0, 1.0));
515
+ let value = value.clamp(0.0, 1.0);
516
+ self.props.borrow_mut().opacity = Some(value);
495
517
  if self.has_built_handle() {
496
- self.build_self();
518
+ ui::set_layer_effect(
519
+ self.handle().raw(),
520
+ value,
521
+ self.props.borrow().blur_sigma.unwrap_or(0.0),
522
+ 0,
523
+ );
497
524
  self.notify_retained_mutation();
498
525
  }
499
526
  }
@@ -699,11 +726,13 @@ impl FlexBox {
699
726
  }
700
727
 
701
728
  pub fn justify_content(&self, justify: JustifyContent) -> &Self {
729
+ self.host_style_layers.borrow_mut().local.justify_content = Some(justify);
702
730
  self.core.borrow_mut().behavior.justify_content = Some(justify);
703
731
  self
704
732
  }
705
733
 
706
734
  pub fn align_items(&self, align: AlignItems) -> &Self {
735
+ self.host_style_layers.borrow_mut().local.align_items = Some(align);
707
736
  self.core.borrow_mut().behavior.align_items = Some(align);
708
737
  self
709
738
  }
@@ -718,6 +747,220 @@ impl FlexBox {
718
747
  self
719
748
  }
720
749
 
750
+ pub fn apply_presenter_style(&self, style: PresenterHostStyle) -> &Self {
751
+ let previous = self.host_style_layers.borrow().resolved();
752
+ self.host_style_layers.borrow_mut().presenter = style;
753
+ self.sync_resolved_host_style_if_changed(previous);
754
+ self
755
+ }
756
+
757
+ pub fn clear_presenter_style(&self) -> &Self {
758
+ self.apply_presenter_style(PresenterHostStyle::new())
759
+ }
760
+
761
+ pub fn clear_bg_color(&self) -> &Self {
762
+ self.clear_local_host_style(|style| style.background = None)
763
+ }
764
+
765
+ pub fn clear_padding(&self) -> &Self {
766
+ self.clear_local_host_style(|style| style.padding = None)
767
+ }
768
+
769
+ pub fn clear_corners(&self) -> &Self {
770
+ self.clear_local_host_style(|style| style.corners = None)
771
+ }
772
+
773
+ pub fn clear_border(&self) -> &Self {
774
+ self.clear_local_host_style(|style| style.border = None)
775
+ }
776
+
777
+ pub fn clear_drop_shadow(&self) -> &Self {
778
+ self.clear_local_host_style(|style| style.shadow = None)
779
+ }
780
+
781
+ pub fn clear_opacity(&self) -> &Self {
782
+ self.clear_local_host_style(|style| style.opacity = None)
783
+ }
784
+
785
+ pub fn clear_flex_direction(&self) -> &Self {
786
+ self.clear_local_host_style(|style| style.flex_direction = None)
787
+ }
788
+
789
+ pub fn clear_justify_content(&self) -> &Self {
790
+ self.clear_local_host_style(|style| style.justify_content = None)
791
+ }
792
+
793
+ pub fn clear_align_items(&self) -> &Self {
794
+ self.clear_local_host_style(|style| style.align_items = None)
795
+ }
796
+
797
+ pub fn clear_cursor(&self) -> &Self {
798
+ self.clear_local_host_style(|style| style.cursor = None)
799
+ }
800
+
801
+ pub fn resolved_host_style(&self) -> PresenterHostStyle {
802
+ self.host_style_layers.borrow().resolved()
803
+ }
804
+
805
+ fn clear_local_host_style(&self, clear: impl FnOnce(&mut PresenterHostStyle)) -> &Self {
806
+ let previous = self.host_style_layers.borrow().resolved();
807
+ clear(&mut self.host_style_layers.borrow_mut().local);
808
+ self.sync_resolved_host_style_if_changed(previous);
809
+ self
810
+ }
811
+
812
+ fn sync_resolved_host_style_if_changed(&self, previous: PresenterHostStyle) {
813
+ let resolved = self.host_style_layers.borrow().resolved();
814
+ if resolved == previous {
815
+ return;
816
+ }
817
+ self.sync_resolved_host_style(previous, resolved);
818
+ }
819
+
820
+ fn sync_resolved_host_style(&self, previous: PresenterHostStyle, resolved: PresenterHostStyle) {
821
+ let background_changed = previous.background != resolved.background;
822
+ let padding_changed = previous.padding != resolved.padding;
823
+ let flex_direction_changed = previous.flex_direction != resolved.flex_direction;
824
+ let justify_content_changed = previous.justify_content != resolved.justify_content;
825
+ let align_items_changed = previous.align_items != resolved.align_items;
826
+ let box_style_changed =
827
+ previous.corners != resolved.corners || previous.border != resolved.border;
828
+ let opacity_changed = previous.opacity != resolved.opacity;
829
+ let shadow_changed = previous.shadow != resolved.shadow;
830
+ let cursor_changed = previous.cursor != resolved.cursor;
831
+
832
+ {
833
+ let mut props = self.props.borrow_mut();
834
+ props.padding = resolved
835
+ .padding
836
+ .map(|value| (value.left, value.top, value.right, value.bottom));
837
+ props.flex_direction = resolved.flex_direction;
838
+ props.opacity = resolved.opacity;
839
+ props.drop_shadow = resolved.shadow.map(|value| DropShadow {
840
+ color: value.color,
841
+ offset_x: value.offset_x,
842
+ offset_y: value.offset_y,
843
+ blur_sigma: value.blur_sigma,
844
+ spread: value.spread,
845
+ });
846
+ props.box_style = if resolved.corners.is_some() || resolved.border.is_some() {
847
+ let corners = resolved.corners.unwrap_or_else(|| Corners::all(0.0));
848
+ let border = resolved
849
+ .border
850
+ .unwrap_or_else(|| Border::solid(0.0, 0x00000000));
851
+ Some(BoxStyle {
852
+ radius_tl: corners.top_left,
853
+ radius_tr: corners.top_right,
854
+ radius_br: corners.bottom_right,
855
+ radius_bl: corners.bottom_left,
856
+ border_width: border.width,
857
+ border_color: border.color,
858
+ border_style: border.style,
859
+ border_dash_on: border.dash_on,
860
+ border_dash_off: border.dash_off,
861
+ })
862
+ } else {
863
+ None
864
+ };
865
+ }
866
+ {
867
+ let mut core = self.core.borrow_mut();
868
+ core.behavior.justify_content = resolved.justify_content;
869
+ core.behavior.align_items = resolved.align_items;
870
+ core.behavior.cursor = resolved.cursor;
871
+ }
872
+ if !self.has_built_handle() {
873
+ self.props.borrow_mut().bg_color = resolved.background;
874
+ self.props.borrow_mut().opacity = resolved.opacity;
875
+ return;
876
+ }
877
+
878
+ let handle = self.handle().raw();
879
+ let mut direct_native_change = false;
880
+ if box_style_changed {
881
+ let corners = resolved.corners.unwrap_or_else(|| Corners::all(0.0));
882
+ let border = resolved
883
+ .border
884
+ .unwrap_or_else(|| Border::solid(0.0, 0x00000000));
885
+ ui::set_box_style(
886
+ handle,
887
+ if background_changed {
888
+ previous.background.unwrap_or(0x00000000)
889
+ } else {
890
+ resolved.background.unwrap_or(0x00000000)
891
+ },
892
+ corners.top_left,
893
+ corners.top_right,
894
+ corners.bottom_right,
895
+ corners.bottom_left,
896
+ border.width,
897
+ border.color,
898
+ border.style as u32,
899
+ border.dash_on,
900
+ border.dash_off,
901
+ );
902
+ direct_native_change = true;
903
+ }
904
+ if padding_changed {
905
+ let padding = resolved.padding.unwrap_or_else(|| EdgeInsets::all(0.0));
906
+ ui::set_padding(
907
+ handle,
908
+ padding.left,
909
+ padding.top,
910
+ padding.right,
911
+ padding.bottom,
912
+ );
913
+ direct_native_change = true;
914
+ }
915
+ if flex_direction_changed {
916
+ ui::set_flex_direction(
917
+ handle,
918
+ resolved.flex_direction.unwrap_or(FlexDirection::Column) as u32,
919
+ );
920
+ direct_native_change = true;
921
+ }
922
+ if justify_content_changed {
923
+ ui::set_justify_content(
924
+ handle,
925
+ resolved.justify_content.unwrap_or(JustifyContent::Start) as u32,
926
+ );
927
+ direct_native_change = true;
928
+ }
929
+ if align_items_changed {
930
+ ui::set_align_items(
931
+ handle,
932
+ resolved.align_items.unwrap_or(AlignItems::Stretch) as u32,
933
+ );
934
+ direct_native_change = true;
935
+ }
936
+ if shadow_changed {
937
+ let shadow = resolved
938
+ .shadow
939
+ .unwrap_or_else(|| Shadow::new(0x00000000, 0.0, 0.0, 0.0, 0.0));
940
+ ui::set_drop_shadow(
941
+ handle,
942
+ shadow.color,
943
+ shadow.offset_x,
944
+ shadow.offset_y,
945
+ shadow.blur_sigma,
946
+ shadow.spread,
947
+ );
948
+ direct_native_change = true;
949
+ }
950
+ if cursor_changed {
951
+ crate::event::handle_cursor_style_changed(self.handle());
952
+ }
953
+ if direct_native_change {
954
+ self.notify_retained_mutation();
955
+ }
956
+ if background_changed {
957
+ self.set_effective_background_color(resolved.background.unwrap_or(0x00000000));
958
+ }
959
+ if opacity_changed {
960
+ self.set_effective_opacity(resolved.opacity.unwrap_or(1.0));
961
+ }
962
+ }
963
+
721
964
  pub fn position_type(&self, position_type: PositionType) -> &Self {
722
965
  self.core.borrow_mut().behavior.position_type = Some(position_type);
723
966
  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
@@ -181,9 +181,12 @@ pub(crate) fn apply_text_props(handle: NodeHandle, props: &TextProps, behavior:
181
181
  if props.has_style_runs {
182
182
  ui::set_text_style_runs(handle.raw(), &props.style_runs);
183
183
  }
184
- if let Some(color) = props.text_color {
185
- ui::set_text_color(handle.raw(), color);
186
- }
184
+ ui::set_text_color(
185
+ handle.raw(),
186
+ props
187
+ .text_color
188
+ .unwrap_or_else(|| crate::theme::current_theme().colors.text_primary),
189
+ );
187
190
  if let Some(line_height) = props.line_height {
188
191
  ui::set_line_height(handle.raw(), line_height);
189
192
  }