@effindomv2/fui-rs 0.1.23 → 0.1.24

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 (45) hide show
  1. package/Cargo.toml +1 -1
  2. package/README.md +12 -0
  3. package/package.json +1 -1
  4. package/src/controls/anti_selection_area.rs +0 -18
  5. package/src/controls/button.rs +14 -42
  6. package/src/controls/checkbox.rs +7 -0
  7. package/src/controls/combobox.rs +7 -6
  8. package/src/controls/context_menu.rs +38 -5
  9. package/src/controls/dialog.rs +41 -3
  10. package/src/controls/dropdown.rs +2 -2
  11. package/src/controls/form.rs +16 -20
  12. package/src/controls/internal/button_presenter.rs +5 -5
  13. package/src/controls/internal/checkbox_indicator_presenter.rs +1 -1
  14. package/src/controls/internal/pressable_labeled_control.rs +21 -7
  15. package/src/controls/internal/selectable_popup_list.rs +2 -2
  16. package/src/controls/internal/text_input_core.rs +38 -68
  17. package/src/controls/internal/text_input_presenter.rs +4 -4
  18. package/src/controls/mod.rs +11 -4
  19. package/src/controls/popup.rs +35 -20
  20. package/src/controls/radio_button.rs +7 -0
  21. package/src/controls/radio_group.rs +17 -0
  22. package/src/controls/selection_area.rs +0 -18
  23. package/src/controls/shared.rs +2 -17
  24. package/src/controls/switch.rs +7 -0
  25. package/src/controls/tests.rs +230 -6
  26. package/src/controls/text_area.rs +28 -142
  27. package/src/controls/text_editor_surface.rs +167 -0
  28. package/src/controls/text_input.rs +30 -144
  29. package/src/lib.rs +26 -20
  30. package/src/mobile_text_selection_toolbar.rs +2 -2
  31. package/src/node/core.rs +444 -64
  32. package/src/node/flex_box.rs +39 -47
  33. package/src/node/grid.rs +43 -128
  34. package/src/node/helpers.rs +34 -43
  35. package/src/node/image.rs +47 -56
  36. package/src/node/mod.rs +398 -73
  37. package/src/node/scroll_bar.rs +6 -0
  38. package/src/node/scroll_box.rs +8 -21
  39. package/src/node/scroll_view.rs +144 -13
  40. package/src/node/svg_node.rs +47 -66
  41. package/src/node/text_node.rs +358 -79
  42. package/src/node/virtual_list.rs +17 -0
  43. package/src/popup_presenter.rs +31 -0
  44. package/src/text.rs +59 -0
  45. package/src/text_indices.rs +48 -0
package/src/node/mod.rs CHANGED
@@ -2,8 +2,8 @@ use crate::bindings::ui;
2
2
  use crate::drawing::DrawContext;
3
3
  use crate::event::{
4
4
  FocusChangedEventArgs, GestureEventArgs, KeyEventArgs, LongPressEventArgs, PointerEventArgs,
5
- PointerType, WheelEventArgs, DEFAULT_LONG_PRESS_MINIMUM_DURATION_MS,
6
- DEFAULT_LONG_PRESS_MOVEMENT_TOLERANCE,
5
+ PointerType, SelectionChangedEventArgs, TextChangedEventArgs, WheelEventArgs,
6
+ DEFAULT_LONG_PRESS_MINIMUM_DURATION_MS, DEFAULT_LONG_PRESS_MOVEMENT_TOLERANCE,
7
7
  };
8
8
  use crate::ffi::{
9
9
  AlignItems, AlignSelf, BorderStyle, CursorStyle, FlexDirection, FlexWrap, GridUnit,
@@ -13,7 +13,7 @@ use crate::ffi::{
13
13
  };
14
14
  use crate::theme;
15
15
  use crate::transitions::NodeTransitions;
16
- use crate::typography::{FontFamily, FontStyle, FontWeight};
16
+ use crate::typography::{FontFamily, FontStack, FontStyle, FontWeight};
17
17
  use std::any::Any;
18
18
  use std::cell::RefCell;
19
19
  use std::rc::{Rc, Weak};
@@ -53,15 +53,33 @@ pub use scroll_box::ScrollBox;
53
53
  pub use scroll_state::ScrollState;
54
54
  pub use scroll_view::ScrollView;
55
55
  pub use svg_node::SvgNode;
56
- pub use text_node::{TextCore, TextNode};
56
+ pub use text_node::TextNode;
57
57
  pub use virtual_list::VirtualList;
58
58
 
59
59
  pub type Image = ImageNode;
60
+ pub type Portal = FlexBox;
60
61
  pub type Svg = SvgNode;
61
62
  pub type Text = TextNode;
62
63
 
63
64
  pub trait HasFlexBoxRoot {
64
65
  fn flex_box_root(&self) -> &FlexBox;
66
+
67
+ #[doc(hidden)]
68
+ fn set_flex_box_surface_width(&self, value: f32, unit: Unit) {
69
+ self.flex_box_root().width(value, unit);
70
+ }
71
+
72
+ #[doc(hidden)]
73
+ fn set_flex_box_surface_height(&self, value: f32, unit: Unit) {
74
+ self.flex_box_root().height(value, unit);
75
+ }
76
+
77
+ #[doc(hidden)]
78
+ fn append_flex_box_surface_child(&self, child: NodeRef) {
79
+ self.flex_box_root()
80
+ .retained_node_ref()
81
+ .append_child_ref(&child);
82
+ }
65
83
  }
66
84
 
67
85
  pub trait ThemeBindable: Sized + 'static {
@@ -102,6 +120,41 @@ impl ThemeBindable for FlexBox {
102
120
 
103
121
  pub trait HasTextNode {
104
122
  fn text_node(&self) -> &TextNode;
123
+
124
+ #[doc(hidden)]
125
+ fn set_text_surface_content(&self, content: String) {
126
+ self.text_node().text(content);
127
+ }
128
+
129
+ #[doc(hidden)]
130
+ fn set_text_surface_font_stack(&self, stack: FontStack, size: f32) {
131
+ self.text_node().font_stack(stack, size);
132
+ }
133
+
134
+ #[doc(hidden)]
135
+ fn set_text_surface_font_family(&self, family: FontFamily) {
136
+ self.text_node().font_family(family);
137
+ }
138
+
139
+ #[doc(hidden)]
140
+ fn set_text_surface_font_weight(&self, weight: FontWeight) {
141
+ self.text_node().font_weight(weight);
142
+ }
143
+
144
+ #[doc(hidden)]
145
+ fn set_text_surface_font_style(&self, style: FontStyle) {
146
+ self.text_node().font_style(style);
147
+ }
148
+
149
+ #[doc(hidden)]
150
+ fn set_text_surface_font_size(&self, size: f32) {
151
+ self.text_node().font_size(size);
152
+ }
153
+
154
+ #[doc(hidden)]
155
+ fn set_text_surface_color(&self, color: u32) {
156
+ self.text_node().text_color(color);
157
+ }
105
158
  }
106
159
 
107
160
  pub trait TextLayoutSurface: HasTextNode {
@@ -115,6 +168,18 @@ pub trait TextLayoutSurface: HasTextNode {
115
168
  self
116
169
  }
117
170
 
171
+ fn width_len(&self, length: Length) -> &Self {
172
+ let (value, unit) = length;
173
+ self.text_node().width(value, unit);
174
+ self
175
+ }
176
+
177
+ fn height_len(&self, length: Length) -> &Self {
178
+ let (value, unit) = length;
179
+ self.text_node().height(value, unit);
180
+ self
181
+ }
182
+
118
183
  fn fill_width(&self) -> &Self {
119
184
  self.text_node().fill_width();
120
185
  self
@@ -130,8 +195,33 @@ pub trait TextLayoutSurface: HasTextNode {
130
195
  self
131
196
  }
132
197
 
133
- fn line_height(&self, line_height: f32) -> &Self {
134
- self.text_node().line_height(line_height);
198
+ fn fill_width_percent(&self, percent: f32) -> &Self {
199
+ self.text_node().fill_width_percent(percent);
200
+ self
201
+ }
202
+
203
+ fn fill_height_percent(&self, percent: f32) -> &Self {
204
+ self.text_node().fill_height_percent(percent);
205
+ self
206
+ }
207
+
208
+ fn min_width(&self, value: f32, unit: Unit) -> &Self {
209
+ self.text_node().min_width(value, unit);
210
+ self
211
+ }
212
+
213
+ fn max_width(&self, value: f32, unit: Unit) -> &Self {
214
+ self.text_node().max_width(value, unit);
215
+ self
216
+ }
217
+
218
+ fn min_height(&self, value: f32, unit: Unit) -> &Self {
219
+ self.text_node().min_height(value, unit);
220
+ self
221
+ }
222
+
223
+ fn max_height(&self, value: f32, unit: Unit) -> &Self {
224
+ self.text_node().max_height(value, unit);
135
225
  self
136
226
  }
137
227
 
@@ -173,165 +263,361 @@ pub trait TextLayoutSurface: HasTextNode {
173
263
 
174
264
  impl<T: HasTextNode> TextLayoutSurface for T {}
175
265
 
266
+ pub trait TextContentSurface: HasTextNode {
267
+ fn text(&self, content: impl Into<String>) -> &Self {
268
+ self.set_text_surface_content(content.into());
269
+ self
270
+ }
271
+
272
+ fn content(&self) -> String {
273
+ self.text_node().content()
274
+ }
275
+ }
276
+
277
+ impl<T: HasTextNode> TextContentSurface for T {}
278
+
279
+ pub trait TextTypographySurface: HasTextNode {
280
+ fn font_stack(&self, stack: FontStack, size: f32) -> &Self {
281
+ self.set_text_surface_font_stack(stack, size);
282
+ self
283
+ }
284
+
285
+ fn font_family(&self, family: FontFamily) -> &Self {
286
+ self.set_text_surface_font_family(family);
287
+ self
288
+ }
289
+
290
+ fn font_weight(&self, weight: FontWeight) -> &Self {
291
+ self.set_text_surface_font_weight(weight);
292
+ self
293
+ }
294
+
295
+ fn font_style(&self, style: FontStyle) -> &Self {
296
+ self.set_text_surface_font_style(style);
297
+ self
298
+ }
299
+
300
+ fn font_size(&self, size: f32) -> &Self {
301
+ self.set_text_surface_font_size(size);
302
+ self
303
+ }
304
+
305
+ fn line_height(&self, line_height: f32) -> &Self {
306
+ self.text_node().line_height(line_height);
307
+ self
308
+ }
309
+
310
+ fn text_color(&self, color: u32) -> &Self {
311
+ self.set_text_surface_color(color);
312
+ self
313
+ }
314
+ }
315
+
316
+ impl<T: HasTextNode> TextTypographySurface for T {}
317
+
318
+ pub trait TextSelectionSurface: HasTextNode {
319
+ fn uses_default_selection_behavior(&self) -> bool {
320
+ self.text_node().uses_default_selection_behavior()
321
+ }
322
+
323
+ fn is_selectable_text(&self) -> bool {
324
+ self.text_node().is_selectable_text()
325
+ }
326
+
327
+ fn selection_start(&self) -> u32 {
328
+ self.text_node().selection_start()
329
+ }
330
+
331
+ fn selection_end(&self) -> u32 {
332
+ self.text_node().selection_end()
333
+ }
334
+
335
+ fn selectable(&self, selectable: bool) -> &Self {
336
+ self.text_node().selectable(selectable);
337
+ self
338
+ }
339
+
340
+ fn selection_color(&self, color: u32) -> &Self {
341
+ self.text_node().selection_color(color);
342
+ self
343
+ }
344
+
345
+ fn selection_range(&self, start: u32, end: u32) -> &Self {
346
+ self.text_node().selection_range(start, end);
347
+ self
348
+ }
349
+
350
+ fn caret_color(&self, color: u32) -> &Self {
351
+ self.text_node().caret_color(color);
352
+ self
353
+ }
354
+ }
355
+
356
+ impl<T: HasTextNode> TextSelectionSurface for T {}
357
+
358
+ pub trait TextEditingSurface: HasTextNode {
359
+ fn is_editable_text(&self) -> bool {
360
+ self.text_node().is_editable_text()
361
+ }
362
+
363
+ fn editable(&self, editable: bool) -> &Self {
364
+ self.text_node().editable(editable);
365
+ self
366
+ }
367
+
368
+ fn obscured(&self, obscured: bool) -> &Self {
369
+ self.text_node().obscured(obscured);
370
+ self
371
+ }
372
+ }
373
+
374
+ impl<T: HasTextNode> TextEditingSurface for T {}
375
+
376
+ pub trait TextEventSurface: HasTextNode {
377
+ fn on_text_changed(&self, handler: impl Fn(TextChangedEventArgs) + 'static) -> &Self {
378
+ self.text_node().on_text_changed(handler);
379
+ self
380
+ }
381
+
382
+ fn on_selection_changed(&self, handler: impl Fn(SelectionChangedEventArgs) + 'static) -> &Self {
383
+ self.text_node().on_selection_changed(handler);
384
+ self
385
+ }
386
+ }
387
+
388
+ impl<T: HasTextNode> TextEventSurface for T {}
389
+
390
+ pub trait TextSurface:
391
+ TextLayoutSurface
392
+ + TextContentSurface
393
+ + TextTypographySurface
394
+ + TextSelectionSurface
395
+ + TextEditingSurface
396
+ + TextEventSurface
397
+ {
398
+ }
399
+
400
+ impl<T> TextSurface for T where
401
+ T: TextLayoutSurface
402
+ + TextContentSurface
403
+ + TextTypographySurface
404
+ + TextSelectionSurface
405
+ + TextEditingSurface
406
+ + TextEventSurface
407
+ {
408
+ }
409
+
176
410
  impl HasTextNode for TextNode {
177
411
  fn text_node(&self) -> &TextNode {
178
412
  self
179
413
  }
180
414
  }
181
415
 
182
- pub trait FlexBoxSurface: HasFlexBoxRoot {
416
+ pub trait LayoutSurface {
417
+ #[doc(hidden)]
418
+ fn layout_surface_root(&self) -> &FlexBox;
419
+
420
+ #[doc(hidden)]
421
+ fn set_layout_surface_width(&self, value: f32, unit: Unit);
422
+
423
+ #[doc(hidden)]
424
+ fn set_layout_surface_height(&self, value: f32, unit: Unit);
425
+
183
426
  fn width(&self, width: f32, unit: Unit) -> &Self {
184
- self.flex_box_root().width(width, unit);
427
+ self.set_layout_surface_width(width, unit);
185
428
  self
186
429
  }
187
430
 
188
431
  fn width_len(&self, length: Length) -> &Self {
189
- self.flex_box_root().width_len(length);
432
+ let (value, unit) = length;
433
+ self.set_layout_surface_width(value, unit);
190
434
  self
191
435
  }
192
436
 
193
437
  fn height(&self, height: f32, unit: Unit) -> &Self {
194
- self.flex_box_root().height(height, unit);
438
+ self.set_layout_surface_height(height, unit);
195
439
  self
196
440
  }
197
441
 
198
442
  fn height_len(&self, length: Length) -> &Self {
199
- self.flex_box_root().height_len(length);
443
+ let (value, unit) = length;
444
+ self.set_layout_surface_height(value, unit);
200
445
  self
201
446
  }
202
447
 
203
448
  fn fill_width(&self) -> &Self {
204
- self.flex_box_root().fill_width();
449
+ self.layout_surface_root().fill_width();
205
450
  self
206
451
  }
207
452
 
208
453
  fn fill_height(&self) -> &Self {
209
- self.flex_box_root().fill_height();
454
+ self.layout_surface_root().fill_height();
210
455
  self
211
456
  }
212
457
 
213
458
  fn fill_size(&self) -> &Self {
214
- self.flex_box_root().fill_size();
459
+ self.layout_surface_root().fill_size();
215
460
  self
216
461
  }
217
462
 
218
463
  fn fill_width_percent(&self, percent: f32) -> &Self {
219
- self.flex_box_root().fill_width_percent(percent);
464
+ self.layout_surface_root().fill_width_percent(percent);
220
465
  self
221
466
  }
222
467
 
223
468
  fn fill_height_percent(&self, percent: f32) -> &Self {
224
- self.flex_box_root().fill_height_percent(percent);
469
+ self.layout_surface_root().fill_height_percent(percent);
225
470
  self
226
471
  }
227
472
 
228
473
  fn min_width(&self, value: f32, unit: Unit) -> &Self {
229
- self.flex_box_root().min_width(value, unit);
474
+ self.layout_surface_root().min_width(value, unit);
230
475
  self
231
476
  }
232
477
 
233
478
  fn min_width_len(&self, length: Length) -> &Self {
234
- self.flex_box_root().min_width_len(length);
479
+ self.layout_surface_root().min_width_len(length);
235
480
  self
236
481
  }
237
482
 
238
483
  fn max_width(&self, value: f32, unit: Unit) -> &Self {
239
- self.flex_box_root().max_width(value, unit);
484
+ self.layout_surface_root().max_width(value, unit);
240
485
  self
241
486
  }
242
487
 
243
488
  fn max_width_len(&self, length: Length) -> &Self {
244
- self.flex_box_root().max_width_len(length);
489
+ self.layout_surface_root().max_width_len(length);
245
490
  self
246
491
  }
247
492
 
248
493
  fn min_height(&self, value: f32, unit: Unit) -> &Self {
249
- self.flex_box_root().min_height(value, unit);
494
+ self.layout_surface_root().min_height(value, unit);
250
495
  self
251
496
  }
252
497
 
253
498
  fn min_height_len(&self, length: Length) -> &Self {
254
- self.flex_box_root().min_height_len(length);
499
+ self.layout_surface_root().min_height_len(length);
255
500
  self
256
501
  }
257
502
 
258
503
  fn max_height(&self, value: f32, unit: Unit) -> &Self {
259
- self.flex_box_root().max_height(value, unit);
504
+ self.layout_surface_root().max_height(value, unit);
260
505
  self
261
506
  }
262
507
 
263
508
  fn max_height_len(&self, length: Length) -> &Self {
264
- self.flex_box_root().max_height_len(length);
509
+ self.layout_surface_root().max_height_len(length);
265
510
  self
266
511
  }
267
512
 
268
- fn padding(&self, left: f32, top: f32, right: f32, bottom: f32) -> &Self {
269
- self.flex_box_root().padding(left, top, right, bottom);
513
+ fn margin(&self, left: f32, top: f32, right: f32, bottom: f32) -> &Self {
514
+ self.layout_surface_root().margin(left, top, right, bottom);
270
515
  self
271
516
  }
272
517
 
273
- fn clear_padding(&self) -> &Self {
274
- self.flex_box_root().clear_padding();
518
+ fn position_type(&self, position_type: PositionType) -> &Self {
519
+ self.layout_surface_root().position_type(position_type);
275
520
  self
276
521
  }
277
522
 
278
- fn margin(&self, left: f32, top: f32, right: f32, bottom: f32) -> &Self {
279
- self.flex_box_root().margin(left, top, right, bottom);
523
+ fn position_absolute(&self) -> &Self {
524
+ self.layout_surface_root()
525
+ .position_type(PositionType::Absolute);
526
+ self
527
+ }
528
+
529
+ fn position(&self, left: f32, top: f32) -> &Self {
530
+ self.layout_surface_root().position(left, top);
531
+ self
532
+ }
533
+ }
534
+
535
+ impl<T: HasFlexBoxRoot> LayoutSurface for T {
536
+ fn layout_surface_root(&self) -> &FlexBox {
537
+ self.flex_box_root()
538
+ }
539
+
540
+ fn set_layout_surface_width(&self, value: f32, unit: Unit) {
541
+ self.set_flex_box_surface_width(value, unit);
542
+ }
543
+
544
+ fn set_layout_surface_height(&self, value: f32, unit: Unit) {
545
+ self.set_flex_box_surface_height(value, unit);
546
+ }
547
+ }
548
+
549
+ pub trait BoxStyleSurface {
550
+ #[doc(hidden)]
551
+ fn box_style_surface_root(&self) -> &FlexBox;
552
+
553
+ fn interactive(&self, interactive: bool) -> &Self {
554
+ self.box_style_surface_root().interactive(interactive);
555
+ self
556
+ }
557
+
558
+ fn padding(&self, left: f32, top: f32, right: f32, bottom: f32) -> &Self {
559
+ self.box_style_surface_root()
560
+ .padding(left, top, right, bottom);
561
+ self
562
+ }
563
+
564
+ fn clear_padding(&self) -> &Self {
565
+ self.box_style_surface_root().clear_padding();
280
566
  self
281
567
  }
282
568
 
283
569
  fn corner_radius(&self, radius: f32) -> &Self {
284
- self.flex_box_root().corner_radius(radius);
570
+ self.box_style_surface_root().corner_radius(radius);
285
571
  self
286
572
  }
287
573
 
288
574
  fn clear_corners(&self) -> &Self {
289
- self.flex_box_root().clear_corners();
575
+ self.box_style_surface_root().clear_corners();
290
576
  self
291
577
  }
292
578
 
293
579
  fn corners(&self, tl: f32, tr: f32, br: f32, bl: f32) -> &Self {
294
- self.flex_box_root().corners(tl, tr, br, bl);
580
+ self.box_style_surface_root().corners(tl, tr, br, bl);
295
581
  self
296
582
  }
297
583
 
298
584
  fn border(&self, width: f32, color: u32) -> &Self {
299
- self.flex_box_root().border(width, color);
585
+ self.box_style_surface_root().border(width, color);
300
586
  self
301
587
  }
302
588
 
303
589
  fn border_config(&self, border: Border) -> &Self {
304
- self.flex_box_root().border_config(border);
590
+ self.box_style_surface_root().border_config(border);
305
591
  self
306
592
  }
307
593
 
308
594
  fn clear_border(&self) -> &Self {
309
- self.flex_box_root().clear_border();
595
+ self.box_style_surface_root().clear_border();
310
596
  self
311
597
  }
312
598
 
313
599
  fn bg_color(&self, color: u32) -> &Self {
314
- self.flex_box_root().bg_color(color);
600
+ self.box_style_surface_root().bg_color(color);
315
601
  self
316
602
  }
317
603
 
318
604
  fn clear_bg_color(&self) -> &Self {
319
- self.flex_box_root().clear_bg_color();
605
+ self.box_style_surface_root().clear_bg_color();
320
606
  self
321
607
  }
322
608
 
323
609
  fn opacity(&self, value: f32) -> &Self {
324
- self.flex_box_root().opacity(value);
610
+ self.box_style_surface_root().opacity(value);
325
611
  self
326
612
  }
327
613
 
328
614
  fn clear_opacity(&self) -> &Self {
329
- self.flex_box_root().clear_opacity();
615
+ self.box_style_surface_root().clear_opacity();
330
616
  self
331
617
  }
332
618
 
333
619
  fn blur(&self, sigma: f32) -> &Self {
334
- self.flex_box_root().blur(sigma);
620
+ self.box_style_surface_root().blur(sigma);
335
621
  self
336
622
  }
337
623
 
@@ -343,18 +629,18 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
343
629
  blur_sigma: f32,
344
630
  spread: f32,
345
631
  ) -> &Self {
346
- self.flex_box_root()
632
+ self.box_style_surface_root()
347
633
  .drop_shadow(color, offset_x, offset_y, blur_sigma, spread);
348
634
  self
349
635
  }
350
636
 
351
637
  fn clear_drop_shadow(&self) -> &Self {
352
- self.flex_box_root().clear_drop_shadow();
638
+ self.box_style_surface_root().clear_drop_shadow();
353
639
  self
354
640
  }
355
641
 
356
642
  fn background_blur(&self, sigma: f32) -> &Self {
357
- self.flex_box_root().background_blur(sigma);
643
+ self.box_style_surface_root().background_blur(sigma);
358
644
  self
359
645
  }
360
646
 
@@ -367,7 +653,7 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
367
653
  offsets: Vec<f32>,
368
654
  colors: Vec<u32>,
369
655
  ) -> &Self {
370
- self.flex_box_root()
656
+ self.box_style_surface_root()
371
657
  .linear_gradient(start_x, start_y, end_x, end_y, offsets, colors);
372
658
  self
373
659
  }
@@ -380,83 +666,122 @@ pub trait FlexBoxSurface: HasFlexBoxRoot {
380
666
  end_y: f32,
381
667
  stops: Vec<GradientStop>,
382
668
  ) -> &Self {
383
- self.flex_box_root()
669
+ self.box_style_surface_root()
384
670
  .linear_gradient_stops(start_x, start_y, end_x, end_y, stops);
385
671
  self
386
672
  }
387
673
 
388
674
  fn transitions(&self, transitions: Option<NodeTransitions>) -> &Self {
389
- self.flex_box_root().transitions(transitions);
675
+ self.box_style_surface_root().transitions(transitions);
676
+ self
677
+ }
678
+
679
+ fn clip_to_bounds(&self, clip: bool) -> &Self {
680
+ self.box_style_surface_root().clip_to_bounds(clip);
681
+ self
682
+ }
683
+ }
684
+
685
+ impl<T: HasFlexBoxRoot> BoxStyleSurface for T {
686
+ fn box_style_surface_root(&self) -> &FlexBox {
687
+ self.flex_box_root()
688
+ }
689
+ }
690
+
691
+ pub trait FlexLayoutSurface {
692
+ #[doc(hidden)]
693
+ fn flex_layout_surface_root(&self) -> &FlexBox;
694
+
695
+ fn flex_direction(&self, direction: FlexDirection) -> &Self {
696
+ self.flex_layout_surface_root().flex_direction(direction);
390
697
  self
391
698
  }
392
699
 
393
700
  fn flex_basis(&self, basis: f32) -> &Self {
394
- self.flex_box_root().flex_basis(basis);
701
+ self.flex_layout_surface_root().flex_basis(basis);
395
702
  self
396
703
  }
397
704
 
398
705
  fn justify_content(&self, justify: JustifyContent) -> &Self {
399
- self.flex_box_root().justify_content(justify);
706
+ self.flex_layout_surface_root().justify_content(justify);
400
707
  self
401
708
  }
402
709
 
403
710
  fn clear_justify_content(&self) -> &Self {
404
- self.flex_box_root().clear_justify_content();
711
+ self.flex_layout_surface_root().clear_justify_content();
405
712
  self
406
713
  }
407
714
 
408
715
  fn align_items(&self, align: AlignItems) -> &Self {
409
- self.flex_box_root().align_items(align);
716
+ self.flex_layout_surface_root().align_items(align);
410
717
  self
411
718
  }
412
719
 
413
720
  fn clear_align_items(&self) -> &Self {
414
- self.flex_box_root().clear_align_items();
721
+ self.flex_layout_surface_root().clear_align_items();
415
722
  self
416
723
  }
417
724
 
418
725
  fn align_self(&self, align: AlignSelf) -> &Self {
419
- self.flex_box_root().align_self(align);
726
+ self.flex_layout_surface_root().align_self(align);
420
727
  self
421
728
  }
422
729
 
423
730
  fn flex_wrap(&self, wrap: FlexWrap) -> &Self {
424
- self.flex_box_root().flex_wrap(wrap);
731
+ self.flex_layout_surface_root().flex_wrap(wrap);
425
732
  self
426
733
  }
734
+ }
427
735
 
428
- fn position_type(&self, position_type: PositionType) -> &Self {
429
- self.flex_box_root().position_type(position_type);
430
- self
736
+ impl<T: HasFlexBoxRoot> FlexLayoutSurface for T {
737
+ fn flex_layout_surface_root(&self) -> &FlexBox {
738
+ self.flex_box_root()
431
739
  }
740
+ }
432
741
 
433
- fn position(&self, left: f32, top: f32) -> &Self {
434
- self.flex_box_root().position(left, top);
435
- self
436
- }
742
+ /// Fluent retained-child composition for FlexBox-backed nodes and controls.
743
+ ///
744
+ /// Composed controls may install presenter-owned children before user content;
745
+ /// `child` and `children` append without replacing those presenter children.
746
+ /// A caller can remove a child it owns through [`Node::remove_child`] without
747
+ /// disturbing the control-owned prefix. Controls with a distinct public content
748
+ /// surface override the hidden append adapter to match their FUI-AS counterpart.
749
+ pub trait ChildContainerSurface {
750
+ #[doc(hidden)]
751
+ fn append_surface_child(&self, child: NodeRef);
437
752
 
438
- fn clip_to_bounds(&self, clip: bool) -> &Self {
439
- self.flex_box_root().clip_to_bounds(clip);
753
+ fn child<T: Node>(&self, child: &T) -> &Self {
754
+ self.append_surface_child(child.retained_node_ref());
440
755
  self
441
756
  }
442
757
 
443
- fn cursor(&self, style: CursorStyle) -> &Self {
444
- self.flex_box_root().cursor(style);
758
+ fn children<I, C>(&self, children: I) -> &Self
759
+ where
760
+ I: IntoIterator<Item = C>,
761
+ C: Into<Child>,
762
+ {
763
+ for child in children {
764
+ self.append_surface_child(child.into().node_ref);
765
+ }
445
766
  self
446
767
  }
768
+ }
447
769
 
448
- fn clear_cursor(&self) -> &Self {
449
- self.flex_box_root().clear_cursor();
450
- self
770
+ impl<T: HasFlexBoxRoot> ChildContainerSurface for T {
771
+ fn append_surface_child(&self, child: NodeRef) {
772
+ self.append_flex_box_surface_child(child);
451
773
  }
774
+ }
452
775
 
453
- fn visibility(&self, visibility: Visibility) -> &Self {
454
- self.flex_box_root().visibility(visibility);
455
- self
456
- }
776
+ pub trait FlexBoxSurface:
777
+ LayoutSurface + BoxStyleSurface + FlexLayoutSurface + ChildContainerSurface
778
+ {
457
779
  }
458
780
 
459
- impl<T: HasFlexBoxRoot> FlexBoxSurface for T {}
781
+ impl<T> FlexBoxSurface for T where
782
+ T: LayoutSurface + BoxStyleSurface + FlexLayoutSurface + ChildContainerSurface
783
+ {
784
+ }
460
785
 
461
786
  #[derive(Clone)]
462
787
  pub struct Child {