fyrox_ui/
widget.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! Base widget for every other widget in the crate. It contains layout-specific info, parent-child relations
22//! visibility, various transforms, drag'n'drop-related data, etc. See [`Widget`] docs for more info.
23
24#![warn(missing_docs)]
25
26use crate::style::DEFAULT_STYLE;
27use crate::{
28    brush::Brush,
29    core::{
30        algebra::{Matrix3, Point2, Vector2},
31        math::Rect,
32        pool::Handle,
33        reflect::prelude::*,
34        uuid::Uuid,
35        visitor::prelude::*,
36        ImmutableString, SafeLock,
37    },
38    core::{parking_lot::Mutex, variable::InheritableVariable},
39    define_constructor,
40    message::{CursorIcon, Force, KeyCode, MessageDirection, UiMessage},
41    style::{
42        resource::{StyleResource, StyleResourceExt},
43        Style, StyledProperty,
44    },
45    BuildContext, HorizontalAlignment, LayoutEvent, MouseButton, MouseState, RcUiNodeHandle,
46    Thickness, UiNode, UserInterface, VerticalAlignment,
47};
48use fyrox_graph::BaseSceneGraph;
49use fyrox_material::{Material, MaterialResource};
50use fyrox_resource::Resource;
51use std::ops::{Deref, DerefMut};
52use std::{
53    any::Any,
54    cell::{Cell, RefCell},
55    cmp::Ordering,
56    fmt::{Debug, Formatter},
57    sync::{mpsc::Sender, Arc},
58};
59
60/// Sorting predicate that is used to sort widgets by some criteria.
61#[derive(Clone)]
62pub struct SortingPredicate(
63    pub Arc<dyn Fn(Handle<UiNode>, Handle<UiNode>, &UserInterface) -> Ordering + Send + Sync>,
64);
65
66impl SortingPredicate {
67    /// Creates new sorting predicate.
68    pub fn new<F>(func: F) -> Self
69    where
70        F: Fn(Handle<UiNode>, Handle<UiNode>, &UserInterface) -> Ordering + Send + Sync + 'static,
71    {
72        Self(Arc::new(func))
73    }
74}
75
76impl Debug for SortingPredicate {
77    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
78        write!(f, "SortingPredicate")
79    }
80}
81
82impl PartialEq for SortingPredicate {
83    fn eq(&self, other: &Self) -> bool {
84        std::ptr::eq(self.0.as_ref(), other.0.as_ref())
85    }
86}
87
88/// A set of messages for any kind of widgets (including user controls). These messages provides basic
89/// communication elements of the UI library.
90#[derive(Debug, Clone, PartialEq)]
91pub enum WidgetMessage {
92    /// Initiated when user clicks on a widget's geometry.
93    ///
94    /// Direction: **From UI**.
95    MouseDown {
96        /// Position of cursor.
97        pos: Vector2<f32>,
98        /// A button that was pressed.
99        button: MouseButton,
100    },
101
102    /// Initiated when user releases mouse button while cursor is over widget's geometry.
103    ///
104    /// Direction: **From UI**.
105    MouseUp {
106        /// Position of cursor.
107        pos: Vector2<f32>,
108        /// A button that was released.
109        button: MouseButton,
110    },
111
112    /// Initiated when user moves cursor over widget's geometry.
113    ///
114    /// Direction: **From/To UI**.
115    MouseMove {
116        /// New position of cursor in screen coordinates.
117        pos: Vector2<f32>,
118        /// State of mouse buttons.
119        state: MouseState,
120    },
121
122    /// Initiated when user scrolls mouse wheel while cursor is over widget's geometry.
123    ///
124    /// Direction: **From/To UI**.
125    MouseWheel {
126        /// Position of cursor.
127        pos: Vector2<f32>,
128        /// Amount of lines per mouse wheel turn.
129        amount: f32,
130    },
131
132    /// Initiated when cursor leaves geometry of a widget.
133    ///
134    /// Direction: **From UI**.
135    MouseLeave,
136
137    /// Initiated when cursor enters geometry of a widget.
138    ///
139    /// Direction: **From UI**.
140    MouseEnter,
141
142    /// Initiated when widget is in focus and user types something on a keyboard.
143    ///
144    /// Direction: **From/To UI**.
145    Text(String),
146
147    /// Initiated when widget is in focus and user presses a button on a keyboard.
148    ///
149    /// Direction: **From UI**.
150    KeyDown(KeyCode),
151
152    /// Initiated when widget is in focus and user releases a button on a keyboard.
153    ///
154    /// Direction: **From UI**.
155    KeyUp(KeyCode),
156
157    /// Initiated when widget received focus (when direction is [`MessageDirection::FromWidget`]). In most cases focus is received
158    /// by clicking on widget. You can request focus explicitly by sending this message to a widget with [`MessageDirection::ToWidget`]
159    ///
160    /// Direction: **From UI/To UI**.
161    Focus,
162
163    /// Initiated when widget has lost its focus (when direction is [`MessageDirection::FromWidget`]). Can be used to
164    /// removed focus from widget if sent with [`MessageDirection::ToWidget`]
165    ///
166    /// Direction: **From UI/To UI**.
167    Unfocus,
168
169    /// Initiated when dragging of a widget has started.
170    ///
171    /// Direction: **From UI**.
172    DragStarted(Handle<UiNode>),
173
174    /// Initiated when user drags a widget over some other widget.
175    ///
176    /// Direction: **From UI**.
177    DragOver(Handle<UiNode>),
178
179    /// Initiated when user drops a widget onto some other widget.
180    ///
181    /// Direction: **From UI**.
182    Drop(Handle<UiNode>),
183
184    /// A request to make widget topmost. Widget can be made topmost only in the same hierarchy
185    /// level only!
186    ///
187    /// Direction: **From/To UI**.
188    Topmost,
189
190    /// A request to make widget lowermost. Widget can be made lowermost only in the same hierarchy
191    /// level only!
192    ///
193    /// Direction: **From/To UI**.
194    Lowermost,
195
196    /// A request to detach widget from its current parent and attach to root canvas.
197    ///
198    /// Direction: **From/To UI**.
199    Unlink,
200
201    /// A request to delete widget with all its children widgets. All handles to a node and its
202    /// children will be invalid after processing such message!
203    ///
204    /// Direction: **From/To UI**.
205    Remove,
206
207    /// A request to link initiator with specified widget.
208    ///
209    /// Direction: **From/To UI**.
210    LinkWith(Handle<UiNode>),
211
212    /// A request to link initiator with specified widget and put it in front of children list.
213    ///
214    /// Direction: **From/To UI**.
215    LinkWithReverse(Handle<UiNode>),
216
217    /// A request to delete all the children widgets and replace them with the given nodes as the
218    /// new child nodes.
219    ///
220    /// Direction: **To UI**.
221    ReplaceChildren(Vec<Handle<UiNode>>),
222
223    /// A request to change background brush of a widget. Background brushes are used to fill volume of widgets.
224    ///
225    /// Direction: **From/To UI**
226    Background(StyledProperty<Brush>),
227
228    /// A request to change foreground brush of a widget. Foreground brushes are used for text, borders and so on.
229    ///
230    /// Direction: **From/To UI**
231    Foreground(StyledProperty<Brush>),
232
233    /// A request to change name of a widget. Name is given to widget mostly for debugging purposes.
234    ///
235    /// Direction: **From/To UI**
236    Name(String),
237
238    /// A request to set width of a widget. In most cases there is no need to explicitly set width of a widget,
239    /// because fyrox-ui uses automatic layout engine which will correctly calculate desired width of a widget.
240    ///
241    /// Direction: **From/To UI**
242    Width(f32),
243
244    /// A request to set height of a widget. In most cases there is no need to explicitly set height of a widget,
245    /// because fyrox-ui uses automatic layout engine which will correctly calculate desired height of a widget.
246    ///
247    /// Direction: **From/To UI**
248    Height(f32),
249
250    /// A request to set vertical alignment of a widget. Vertical alignment tells where to put widget in the parent
251    /// widget's bounds in vertical direction.
252    ///
253    /// Direction: **From/To UI**
254    VerticalAlignment(VerticalAlignment),
255
256    /// A request to set horizontal alignment of a widget. Horizontal alignment tells where to put widget in the parent
257    /// widget's bounds in horizontal direction.
258    ///
259    /// Direction: **From/To UI**
260    HorizontalAlignment(HorizontalAlignment),
261
262    /// A request to set maximum size of widget. Maximum size restricts size of a widget during layout pass. For example
263    /// you can set maximum size to a button which was placed into a grid's cell, if maximum size wouldn't be set, button
264    /// would be stretched to fill entire cell.
265    ///
266    /// Direction: **From/To UI**
267    MaxSize(Vector2<f32>),
268
269    /// A request to set minimum size of widget. Minimum size restricts size of a widget during layout pass. For example
270    /// you can set minimum size to a button which was placed into a grid's cell, if minimum size wouldn't be set, button
271    /// would be compressed to fill entire cell.
272    ///
273    /// Direction: **From/To UI**
274    MinSize(Vector2<f32>),
275
276    /// A request to set row number of a grid to which widget should belong to.
277    ///
278    /// Direction: **From/To UI**
279    ///
280    /// # Notes
281    ///
282    /// This is bad API and it should be changed in future. Grid should have explicit list of pairs (row, child) instead
283    /// of this indirect attachment.
284    Row(usize),
285
286    /// A request to set column number of a grid to which widget should belong to.
287    ///
288    /// Direction: **From/To UI**
289    ///
290    /// # Notes
291    ///
292    /// This is bad API and it should be changed in future. Grid should have explicit list of pairs (column, child) instead
293    /// of this indirect attachment.
294    Column(usize),
295
296    /// A request to set new margin of widget. Margin could be used to add some free space around widget to make UI look less
297    /// dense.
298    ///
299    /// Direction: **From/To UI**
300    Margin(Thickness),
301
302    /// A request to set new state hit test visibility. If set to false, widget will become "non-clickable". It is useful for
303    /// decorations which should be transparent for mouse events.
304    ///
305    /// Direction: **From/To UI**
306    HitTestVisibility(bool),
307
308    /// A request to set new visibility of a widget. Widget can be either visible or not. Invisible widgets does not take space
309    /// in layout pass and collapsed to a point.
310    ///
311    /// Direction: **From/To UI**
312    Visibility(bool),
313
314    /// A request to set new z index of a widget. Z index is used to change drawing order of widgets. Please note that it works
315    /// only in same hierarchy level, which means that it is impossible to set z index to 9999 (or similar huge value) to force
316    /// widget to be drawn on top of everything.
317    ///
318    /// Direction: **From/To UI**
319    ZIndex(usize),
320
321    /// A request to set new desired position of a widget. It is called "desired" because layout system may ignore it and set
322    /// some other position. Desired position works with a combination of a layout panel that supports direct coordinated
323    /// (Canvas for example).
324    ///
325    /// Direction: **From/To UI**
326    DesiredPosition(Vector2<f32>),
327
328    /// Aligns the widget in the specified widget's bounds using the given options. It can be used only if the
329    /// widget is a child of a container, that supports arbitrary positions (such as Canvas).
330    Align {
331        /// A handle of a node to which the sender of this message should be aligned to.
332        relative_to: Handle<UiNode>,
333        /// Horizontal alignment of the widget.
334        horizontal_alignment: HorizontalAlignment,
335        /// Vertical alignment of the widget.
336        vertical_alignment: VerticalAlignment,
337        /// Margins for each side.
338        margin: Thickness,
339    },
340
341    /// A request to enable or disable widget. Disabled widget won't receive mouse events and may look differently (it is defined
342    /// by internal styling).
343    ///
344    /// Direction: **From/To UI**
345    Enabled(bool),
346
347    /// A request to set desired position at center in local coordinates.
348    ///
349    /// Direction: **From/To UI**
350    Center,
351
352    /// A request to adjust widget's position to fit in parent's bounds.
353    AdjustPositionToFit,
354
355    /// A request to set new cursor icon for widget.
356    ///
357    /// Direction: **From/To UI**
358    Cursor(Option<CursorIcon>),
359
360    /// A request to set new opacity for widget.
361    ///
362    /// Direction: **From/To UI**
363    Opacity(Option<f32>),
364
365    /// A request to set new layout transform.
366    LayoutTransform(Matrix3<f32>),
367
368    /// A request to set new render transform.
369    RenderTransform(Matrix3<f32>),
370
371    /// A double click of a mouse button has occurred on a widget.
372    DoubleClick {
373        /// A button, that was double-clicked.
374        button: MouseButton,
375    },
376
377    /// A request to set new context menu for a widget. Old context menu will be removed only if its
378    /// reference counter was 1.
379    ContextMenu(Option<RcUiNodeHandle>),
380
381    /// A request to set new tooltip for a widget. Old tooltip will be removed only if its reference
382    /// counter was 1.
383    Tooltip(Option<RcUiNodeHandle>),
384
385    /// Initiated when user places finger on the screen.
386    ///
387    /// Direction: **From UI**.
388    TouchStarted {
389        /// position of user's finger
390        pos: Vector2<f32>,
391        /// pressure exerted on screen at pos
392        force: Option<Force>,
393        /// unique identifier for touch event
394        id: u64,
395    },
396
397    /// Initiated when user removes finger from the screen.
398    ///
399    /// Direction: **From UI**.
400    TouchEnded {
401        /// position of user's finger
402        pos: Vector2<f32>,
403        /// unique identifier for touch event
404        id: u64,
405    },
406
407    /// Initiated when user drags their finger across the screen.
408    ///
409    /// Direction: **From UI**.
410    TouchMoved {
411        /// position of user's finger
412        pos: Vector2<f32>,
413        /// pressure exerted on screen at pos
414        force: Option<Force>,
415        /// unique identifier for touch event
416        id: u64,
417    },
418
419    /// Initiated when user cancels their touch event.
420    ///
421    /// Direction: **From UI**.
422    TouchCancelled {
423        /// position of user's finger
424        pos: Vector2<f32>,
425        /// unique identifier for touch event
426        id: u64,
427    },
428
429    /// Initiated when user taps the screen two or more times in rapid succession.
430    ///
431    /// Direction: **From UI**.
432    DoubleTap {
433        /// position of user's finger
434        pos: Vector2<f32>,
435        /// pressure exerted on screen at pos
436        force: Option<Force>,
437        /// unique identifier for touch event
438        id: u64,
439    },
440
441    /// Sorts children widgets of a widget.
442    ///
443    /// Direction: **To UI**.
444    SortChildren(SortingPredicate),
445
446    /// Applies a style to the widget.
447    Style(StyleResource),
448
449    /// Asks a widget to reset its visual state. The actual response to this message is widget-specific.
450    /// In most cases, it does nothing.
451    ResetVisual,
452}
453
454impl WidgetMessage {
455    define_constructor!(
456        /// Creates [`WidgetMessage::Remove`] message.
457        WidgetMessage:Remove => fn remove(), layout: false
458    );
459
460    define_constructor!(
461        /// Creates [`WidgetMessage::Unlink`] message.
462        WidgetMessage:Unlink => fn unlink(), layout: false
463    );
464
465    define_constructor!(
466        /// Creates [`WidgetMessage::LinkWith`] message.
467        WidgetMessage:LinkWith => fn link(Handle<UiNode>), layout: false
468    );
469
470    define_constructor!(
471        /// Creates [`WidgetMessage::LinkWithReverse`] message.
472        WidgetMessage:LinkWithReverse => fn link_reverse(Handle<UiNode>), layout: false
473    );
474
475    define_constructor!(
476        /// Creates [`WidgetMessage::ReplaceChildren`] message.
477        WidgetMessage:ReplaceChildren => fn replace_children(Vec<Handle<UiNode>>), layout: false
478    );
479
480    define_constructor!(
481        /// Creates [`WidgetMessage::Background`] message.
482        WidgetMessage:Background => fn background(StyledProperty<Brush>), layout: false
483    );
484
485    define_constructor!(
486        /// Creates [`WidgetMessage::Foreground`] message.
487        WidgetMessage:Foreground => fn foreground(StyledProperty<Brush>), layout: false
488    );
489
490    define_constructor!(
491        /// Creates [`WidgetMessage::Visibility`] message.
492        WidgetMessage:Visibility => fn visibility(bool), layout: false
493    );
494
495    define_constructor!(
496        /// Creates [`WidgetMessage::Width`] message.
497        WidgetMessage:Width => fn width(f32), layout: false
498    );
499
500    define_constructor!(
501        /// Creates [`WidgetMessage::Height`] message.
502        WidgetMessage:Height => fn height(f32), layout: false
503    );
504
505    define_constructor!(
506        /// Creates [`WidgetMessage::DesiredPosition`] message.
507        WidgetMessage:DesiredPosition => fn desired_position(Vector2<f32>), layout: false
508    );
509
510    define_constructor!(
511        /// Creates [`WidgetMessage::Center`] message.
512        WidgetMessage:Center => fn center(), layout: true
513    );
514
515    define_constructor!(
516        /// Creates [`WidgetMessage::AdjustPositionToFit`] message.
517        WidgetMessage:AdjustPositionToFit => fn adjust_position_to_fit(), layout: true
518    );
519
520    define_constructor!(
521        /// Creates [`WidgetMessage::Align`] message.
522        WidgetMessage:Align => fn align(
523            relative_to: Handle<UiNode>,
524            horizontal_alignment: HorizontalAlignment,
525            vertical_alignment: VerticalAlignment,
526            margin: Thickness),
527        layout: true
528    );
529
530    define_constructor!(
531        /// Creates [`WidgetMessage::Topmost`] message.
532        WidgetMessage:Topmost => fn topmost(), layout: false
533    );
534
535    define_constructor!(
536        /// Creates [`WidgetMessage::Lowermost`] message.
537        WidgetMessage:Lowermost => fn lowermost(), layout: false
538    );
539
540    define_constructor!(
541        /// Creates [`WidgetMessage::Enabled`] message.
542        WidgetMessage:Enabled => fn enabled(bool), layout: false
543    );
544
545    define_constructor!(
546        /// Creates [`WidgetMessage::Name`] message.
547        WidgetMessage:Name => fn name(String), layout: false
548    );
549
550    define_constructor!(
551        /// Creates [`WidgetMessage::Row`] message.
552        WidgetMessage:Row => fn row(usize), layout: false
553    );
554
555    define_constructor!(
556        /// Creates [`WidgetMessage::Column`] message.
557        WidgetMessage:Column => fn column(usize), layout: false
558    );
559
560    define_constructor!(
561        /// Creates [`WidgetMessage::Cursor`] message.
562        WidgetMessage:Cursor => fn cursor(Option<CursorIcon>), layout: false
563    );
564
565    define_constructor!(
566        /// Creates [`WidgetMessage::ZIndex`] message.
567        WidgetMessage:ZIndex => fn z_index(usize), layout: false
568    );
569
570    define_constructor!(
571        /// Creates [`WidgetMessage::HitTestVisibility`] message.
572        WidgetMessage:HitTestVisibility => fn hit_test_visibility(bool), layout: false
573    );
574
575    define_constructor!(
576        /// Creates [`WidgetMessage::Margin`] message.
577        WidgetMessage:Margin => fn margin(Thickness), layout: false
578    );
579
580    define_constructor!(
581        /// Creates [`WidgetMessage::MinSize`] message.
582        WidgetMessage:MinSize => fn min_size(Vector2<f32>), layout: false
583    );
584
585    define_constructor!(
586        /// Creates [`WidgetMessage::MaxSize`] message.
587        WidgetMessage:MaxSize => fn max_size(Vector2<f32>), layout: false
588    );
589
590    define_constructor!(
591        /// Creates [`WidgetMessage::HorizontalAlignment`] message.
592        WidgetMessage:HorizontalAlignment => fn horizontal_alignment(HorizontalAlignment), layout: false
593    );
594
595    define_constructor!(
596        /// Creates [`WidgetMessage::VerticalAlignment`] message.
597        WidgetMessage:VerticalAlignment => fn vertical_alignment(VerticalAlignment), layout: false
598    );
599
600    define_constructor!(
601        /// Creates [`WidgetMessage::Opacity`] message.
602        WidgetMessage:Opacity => fn opacity(Option<f32>), layout: false
603    );
604
605    define_constructor!(
606        /// Creates [`WidgetMessage::LayoutTransform`] message.
607        WidgetMessage:LayoutTransform => fn layout_transform(Matrix3<f32>), layout: false
608    );
609
610    define_constructor!(
611        /// Creates [`WidgetMessage::RenderTransform`] message.
612        WidgetMessage:RenderTransform => fn render_transform(Matrix3<f32>), layout: false
613    );
614
615    define_constructor!(
616        /// Creates [`WidgetMessage::ContextMenu`] message.
617        WidgetMessage:ContextMenu => fn context_menu(Option<RcUiNodeHandle>), layout: false
618    );
619
620    define_constructor!(
621        /// Creates [`WidgetMessage::Tooltip`] message.
622        WidgetMessage:Tooltip => fn tooltip(Option<RcUiNodeHandle>), layout: false
623    );
624
625    define_constructor!(
626        /// Creates [`WidgetMessage::Focus`] message.
627        WidgetMessage:Focus => fn focus(), layout: false
628    );
629
630    define_constructor!(
631        /// Creates [`WidgetMessage::Unfocus`] message.
632        WidgetMessage:Unfocus => fn unfocus(), layout: false
633    );
634
635    // Internal messages. Do not use.
636    define_constructor!(
637        /// Creates [`WidgetMessage::MouseDown`] message. This method is for internal use only, and should not
638        /// be used anywhere else.
639        WidgetMessage:MouseDown => fn mouse_down(pos: Vector2<f32>, button: MouseButton), layout: false
640    );
641
642    define_constructor!(
643        /// Creates [`WidgetMessage::MouseUp`] message. This method is for internal use only, and should not
644        /// be used anywhere else.
645        WidgetMessage:MouseUp => fn mouse_up(pos: Vector2<f32>, button: MouseButton), layout: false
646    );
647
648    define_constructor!(
649        /// Creates [`WidgetMessage::MouseMove`] message. This method is for internal use only, and should not
650        /// be used anywhere else.
651        WidgetMessage:MouseMove => fn mouse_move(pos: Vector2<f32>, state: MouseState), layout: false
652    );
653
654    define_constructor!(
655        /// Creates [`WidgetMessage::MouseWheel`] message. This method is for internal use only, and should not
656        /// be used anywhere else.
657        WidgetMessage:MouseWheel => fn mouse_wheel(pos: Vector2<f32>, amount: f32), layout: false
658    );
659
660    define_constructor!(
661        /// Creates [`WidgetMessage::MouseLeave`] message. This method is for internal use only, and should not
662        /// be used anywhere else.
663        WidgetMessage:MouseLeave => fn mouse_leave(), layout: false
664    );
665
666    define_constructor!(
667        /// Creates [`WidgetMessage::MouseEnter`] message. This method is for internal use only, and should not
668        /// be used anywhere else.
669        WidgetMessage:MouseEnter => fn mouse_enter(), layout: false
670    );
671
672    define_constructor!(
673        /// Creates [`WidgetMessage::Text`] message. This method is for internal use only, and should not
674        /// be used anywhere else.
675        WidgetMessage:Text => fn text(String), layout: false
676    );
677
678    define_constructor!(
679        /// Creates [`WidgetMessage::KeyDown`] message. This method is for internal use only, and should not
680        /// be used anywhere else.
681        WidgetMessage:KeyDown => fn key_down(KeyCode), layout: false
682    );
683
684    define_constructor!(
685        /// Creates [`WidgetMessage::KeyUp`] message. This method is for internal use only, and should not
686        /// be used anywhere else.
687        WidgetMessage:KeyUp => fn key_up(KeyCode), layout: false
688    );
689
690    define_constructor!(
691        /// Creates [`WidgetMessage::DragStarted`] message. This method is for internal use only, and should not
692        /// be used anywhere else.
693        WidgetMessage:DragStarted => fn drag_started(Handle<UiNode>), layout: false
694    );
695
696    define_constructor!(
697        /// Creates [`WidgetMessage::DragOver`] message. This method is for internal use only, and should not
698        /// be used anywhere else.
699        WidgetMessage:DragOver => fn drag_over(Handle<UiNode>), layout: false
700    );
701
702    define_constructor!(
703        /// Creates [`WidgetMessage::Drop`] message. This method is for internal use only, and should not
704        /// be used anywhere else.
705        WidgetMessage:Drop => fn drop(Handle<UiNode>), layout: false
706    );
707
708    define_constructor!(
709        /// Creates [`WidgetMessage::DoubleClick`] message. This method is for internal use only, and should not
710        /// be used anywhere else.
711        WidgetMessage:DoubleClick => fn double_click(button: MouseButton), layout: false
712    );
713
714    define_constructor!(
715        /// Creates [`WidgetMessage::TouchStarted`] message. This method is for internal use only, and should not
716        /// be used anywhere else.
717        WidgetMessage:TouchStarted => fn touch_started(pos: Vector2<f32>, force: Option<Force>, id: u64), layout: false
718    );
719
720    define_constructor!(
721        /// Creates [`WidgetMessage::TouchEnded`] message. This method is for internal use only, and should not
722        /// be used anywhere else.
723        WidgetMessage:TouchEnded => fn touch_ended(pos: Vector2<f32>, id: u64), layout: false
724    );
725
726    define_constructor!(
727        /// Creates [`WidgetMessage::TouchMoved`] message. This method is for internal use only, and should not
728        /// be used anywhere else.
729        WidgetMessage:TouchMoved => fn touch_moved(pos: Vector2<f32>, force: Option<Force>, id: u64), layout: false
730    );
731
732    define_constructor!(
733        /// Creates [`WidgetMessage::TouchCancelled`] message. This method is for internal use only, and should not
734        /// be used anywhere else.
735        WidgetMessage:TouchCancelled => fn touch_cancelled(pos: Vector2<f32>, id: u64), layout: false
736    );
737
738    define_constructor!(
739        /// Creates [`WidgetMessage::DoubleTap`] message. This method is for internal use only, and should not
740        /// be used anywhere else.
741        WidgetMessage:DoubleTap => fn double_tap(pos: Vector2<f32>, force: Option<Force>, id: u64), layout: false
742    );
743
744    define_constructor!(
745        /// Creates [`WidgetMessage::SortChildren`] message.
746        WidgetMessage:SortChildren => fn sort_children(SortingPredicate), layout: false
747    );
748
749    define_constructor!(
750        /// Creates [`WidgetMessage::Style`] message.
751        WidgetMessage:Style => fn style(StyleResource), layout: false
752    );
753
754    define_constructor!(
755        /// Creates [`WidgetMessage::ResetVisual`] message.
756        WidgetMessage:ResetVisual => fn reset_visual(), layout: false
757    );
758}
759
760#[doc(hidden)]
761#[derive(Clone, Debug, Reflect, PartialEq)]
762pub struct WidgetMaterial(pub MaterialResource);
763
764impl Visit for WidgetMaterial {
765    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
766        self.0.visit(name, visitor)
767    }
768}
769
770impl Default for WidgetMaterial {
771    fn default() -> Self {
772        Self(MaterialResource::new_embedded(Material::standard_widget()))
773    }
774}
775
776impl Deref for WidgetMaterial {
777    type Target = MaterialResource;
778
779    fn deref(&self) -> &Self::Target {
780        &self.0
781    }
782}
783
784impl DerefMut for WidgetMaterial {
785    fn deref_mut(&mut self) -> &mut Self::Target {
786        &mut self.0
787    }
788}
789
790/// Widget is a base UI element, that is always used to build derived, more complex, widgets. In general, it is a container
791/// for layout information, basic visual appearance, visibility options, parent-child information. It does almost nothing
792/// on its own, instead, the user interface modifies its state accordingly.
793#[derive(Default, Debug, Clone, Reflect, Visit)]
794#[visit(optional)]
795pub struct Widget {
796    /// Self handle of the widget. It is valid **only**, if the widget is added to the user interface, in other
797    /// cases it will most likely be [`Handle::NONE`].
798    #[reflect(hidden)]
799    pub handle: Handle<UiNode>,
800    /// Name of the widget. Could be useful for debugging purposes.
801    pub name: ImmutableString,
802    /// Desired position relative to the parent node. It is just a recommendation for the layout system, actual position
803    /// will be stored in the `actual_local_position` field and can be fetched using [`Widget::actual_local_position`]
804    /// method.
805    #[reflect(setter = "set_desired_local_position_notify")]
806    pub desired_local_position: InheritableVariable<Vector2<f32>>,
807    /// Explicit width for the widget, or automatic if [`f32::NAN`] (means the value is undefined). Default is [`f32::NAN`].
808    #[reflect(setter = "set_width_notify")]
809    pub width: InheritableVariable<f32>,
810    /// Explicit height for the widget, or automatic if [`f32::NAN`] (means the value is undefined). Default is [`f32::NAN`].
811    #[reflect(setter = "set_height_notify")]
812    pub height: InheritableVariable<f32>,
813    /// Minimum width and height. Default is 0.0 for both axes.
814    #[reflect(setter = "set_min_size_notify")]
815    pub min_size: InheritableVariable<Vector2<f32>>,
816    /// Maximum width and height. Default is [`f32::INFINITY`] for both axes.
817    #[reflect(setter = "set_max_size_notify")]
818    pub max_size: InheritableVariable<Vector2<f32>>,
819    /// Background brush of the widget.
820    pub background: InheritableVariable<StyledProperty<Brush>>,
821    /// Foreground brush of the widget.
822    pub foreground: InheritableVariable<StyledProperty<Brush>>,
823    /// Index of the row to which this widget belongs to. It is valid only in when used in [`crate::grid::Grid`] widget.
824    #[reflect(setter = "set_row_notify")]
825    pub row: InheritableVariable<usize>,
826    /// Index of the column to which this widget belongs to. It is valid only in when used in [`crate::grid::Grid`] widget.
827    #[reflect(setter = "set_column_notify")]
828    pub column: InheritableVariable<usize>,
829    /// Vertical alignment of the widget.
830    #[reflect(setter = "set_vertical_alignment_notify")]
831    pub vertical_alignment: InheritableVariable<VerticalAlignment>,
832    /// Horizontal alignment of the widget.
833    #[reflect(setter = "set_horizontal_alignment_notify")]
834    pub horizontal_alignment: InheritableVariable<HorizontalAlignment>,
835    /// Margin for every sides of bounding rectangle. See [`Thickness`] docs for more info.
836    #[reflect(setter = "set_margin_notify")]
837    pub margin: InheritableVariable<Thickness>,
838    /// Current, **local**, visibility state of the widget.
839    #[reflect(setter = "set_visibility_notify")]
840    pub visibility: InheritableVariable<bool>,
841    /// Current, **global** (including the chain of parent widgets), visibility state of the widget.
842    #[reflect(hidden)]
843    pub global_visibility: bool,
844    /// A set of handles to children nodes of this widget.
845    #[reflect(hidden)]
846    pub children: Vec<Handle<UiNode>>,
847    /// A handle to the parent node of this widget.
848    #[reflect(hidden)]
849    pub parent: Handle<UiNode>,
850    /// Indices of drawing commands in the drawing context emitted by this widget. It is used for picking.
851    #[reflect(hidden)]
852    #[visit(skip)]
853    pub command_indices: RefCell<Vec<usize>>,
854    /// A flag, that indicates that the mouse is directly over the widget. It will be raised only for top-most widget in the
855    /// "stack" of widgets.
856    #[reflect(hidden)]
857    pub is_mouse_directly_over: bool,
858    /// A flag, that defines whether the widget is "visible" for hit testing (picking). Could be useful to prevent some widgets
859    /// from any interactions with mouse.
860    pub hit_test_visibility: InheritableVariable<bool>,
861    /// Index of the widget in parent's children list that defines its order in drawing and picking.
862    pub z_index: InheritableVariable<usize>,
863    /// A flag, that defines whether the drag from drag'n'drop functionality can be started by the widget or not.
864    pub allow_drag: InheritableVariable<bool>,
865    /// A flag, that defines whether the drop from drag'n'drop functionality can be accepted by the widget or not.
866    pub allow_drop: InheritableVariable<bool>,
867    /// Style of the widget.
868    pub style: Option<StyleResource>,
869    /// Optional, user-defined data.
870    #[reflect(hidden)]
871    #[visit(skip)]
872    pub user_data: Option<Arc<Mutex<dyn Any + Send>>>,
873    /// A flag, that defines whether the widget should be drawn in a separate drawind pass after any other widget that draws
874    /// normally.
875    pub draw_on_top: InheritableVariable<bool>,
876    /// A flag, that defines whether the widget is enabled or not. Disabled widgets cannot be interacted by used and they're
877    /// greyed out.
878    pub enabled: InheritableVariable<bool>,
879    /// Optional cursor icon that will be used for mouse cursor when hovering over the widget.
880    pub cursor: InheritableVariable<Option<CursorIcon>>,
881    /// Optional opacity of the widget. It should be in `[0.0..1.0]` range, where 0.0 - fully transparent, 1.0 - fully opaque.
882    pub opacity: InheritableVariable<Option<f32>>,
883    /// An optional ref counted handle to a tooltip used by the widget.
884    pub tooltip: Option<RcUiNodeHandle>,
885    /// Maximum available time to show the tooltip after the cursor was moved away from the widget.
886    pub tooltip_time: f32,
887    /// An optional ref counted handle to a context menu used by the widget.
888    pub context_menu: Option<RcUiNodeHandle>,
889    /// A flag, that defines whether the widget should be clipped by the parent bounds or not.
890    pub clip_to_bounds: InheritableVariable<bool>,
891    /// Current render transform of the node. It modifies layout information of the widget, as well as it affects visual transform
892    /// of the widget.
893    #[reflect(hidden)]
894    layout_transform: Matrix3<f32>,
895    /// Current render transform of the node. It only modifies the widget at drawing stage, layout information remains unmodified.
896    #[reflect(hidden)]
897    render_transform: Matrix3<f32>,
898    /// Current visual transform of the node. It always contains a result of mixing the layout and
899    /// render transformation matrices. Visual transform could be used to transform a point to
900    /// screen space. To transform a screen space point to local coordinates use [`Widget::screen_to_local`]
901    /// method.
902    #[reflect(hidden)]
903    pub visual_transform: Matrix3<f32>,
904    /// A flag, that defines whether the widget will preview UI messages or not. Basically, it defines whether [crate::Control::preview_message]
905    /// is called or not.
906    pub preview_messages: bool,
907    /// A flag, that defines whether the widget will receive any OS events or not. Basically, it defines whether [crate::Control::handle_os_event]
908    /// is called or not.
909    pub handle_os_events: bool,
910    /// Defines the order in which this widget will get keyboard focus when Tab key is pressed.
911    /// If set to [`None`], Tab key won't do anything on such widget. Default is [`None`].
912    pub tab_index: InheritableVariable<Option<usize>>,
913    /// A flag, that defines whether the Tab key navigation is enabled or disabled for this widget.
914    pub tab_stop: InheritableVariable<bool>,
915    /// A flag, that defines whether the widget will be update or not. Basically, it defines whether [crate::Control::update]
916    /// is called or not.
917    pub need_update: bool,
918    /// Enables (`false`) or disables (`true`) layout rounding.
919    pub ignore_layout_rounding: bool,
920    /// A flag, that indicates that the widget accepts user input. It could be used to determine, if
921    /// a user can interact with the widget using keyboard. It is also used for automatic assignment
922    /// of the tab index. Keep in mind, that this flag is only a marker and does not do anything else
923    /// on its own. Default value is `false`.
924    pub accepts_input: bool,
925    /// Internal sender for layout events.
926    #[reflect(hidden)]
927    #[visit(skip)]
928    pub layout_events_sender: Option<Sender<LayoutEvent>>,
929    /// Unique identifier of the widget.
930    pub id: Uuid,
931    /// A flag, that indicates whether this widget is a root widget of a hierarchy of widgets
932    /// instantiated from a resource.
933    #[reflect(hidden)]
934    pub is_resource_instance_root: bool,
935    /// A resource from which this widget was instantiated from, can work in pair with `original`
936    /// handle to get a corresponding widget from resource.
937    #[reflect(read_only)]
938    pub resource: Option<Resource<UserInterface>>,
939    /// A material, that should be used when rendering the widget.
940    pub material: InheritableVariable<WidgetMaterial>,
941    /// Handle to a widget in a user interface resource from which this node was instantiated from.
942    #[reflect(hidden)]
943    pub original_handle_in_resource: Handle<UiNode>,
944    //
945    // Layout. Interior mutability is a must here because layout performed in a series of recursive calls.
946    //
947    /// A flag, that defines whether the measurement results are still valid or not.
948    #[reflect(hidden)]
949    #[visit(skip)]
950    pub measure_valid: Cell<bool>,
951    /// A flag, that defines whether the arrangement results are still valid or not.
952    #[reflect(hidden)]
953    #[visit(skip)]
954    pub arrange_valid: Cell<bool>,
955    /// Results or previous measurement.
956    #[reflect(hidden)]
957    #[visit(skip)]
958    pub prev_measure: Cell<Vector2<f32>>,
959    /// Results or previous arrangement.
960    #[reflect(hidden)]
961    #[visit(skip)]
962    pub prev_arrange: Cell<Rect<f32>>,
963    /// Desired size of the node after Measure pass.
964    #[reflect(hidden)]
965    #[visit(skip)]
966    pub desired_size: Cell<Vector2<f32>>,
967    /// Actual local position of the widget after Arrange pass.
968    #[reflect(hidden)]
969    #[visit(skip)]
970    pub actual_local_position: Cell<Vector2<f32>>,
971    /// Actual local size of the widget after Arrange pass.
972    #[reflect(hidden)]
973    #[visit(skip)]
974    pub actual_local_size: Cell<Vector2<f32>>,
975    /// Previous global visibility of the widget.
976    #[reflect(hidden)]
977    #[visit(skip)]
978    pub prev_global_visibility: bool,
979    /// Current clip bounds of the widget.
980    #[reflect(hidden)]
981    #[visit(skip)]
982    pub clip_bounds: Cell<Rect<f32>>,
983}
984
985impl Widget {
986    /// Returns self handle of the widget.
987    #[inline]
988    pub fn handle(&self) -> Handle<UiNode> {
989        self.handle
990    }
991
992    /// Returns the name of the widget.
993    #[inline]
994    pub fn name(&self) -> &str {
995        self.name.as_str()
996    }
997
998    /// Sets the new name of the widget.
999    #[inline]
1000    pub fn set_name<P: AsRef<str>>(&mut self, name: P) -> &mut Self {
1001        self.name = ImmutableString::new(name);
1002        self
1003    }
1004
1005    /// Returns the actual size of the widget after the full layout cycle.
1006    #[inline]
1007    pub fn actual_local_size(&self) -> Vector2<f32> {
1008        self.actual_local_size.get()
1009    }
1010
1011    /// Returns size of the widget without any layout or rendering transform applied.
1012    #[inline]
1013    pub fn actual_initial_size(&self) -> Vector2<f32> {
1014        Rect::new(
1015            0.0,
1016            0.0,
1017            self.actual_local_size.get().x,
1018            self.actual_local_size.get().y,
1019        )
1020        .transform(&self.visual_transform.try_inverse().unwrap_or_default())
1021        .size
1022    }
1023
1024    /// Returns the actual global size of the widget after the full layout cycle.
1025    #[inline]
1026    pub fn actual_global_size(&self) -> Vector2<f32> {
1027        self.screen_bounds().size
1028    }
1029
1030    /// Sets the new minimum size of the widget.
1031    #[inline]
1032    pub fn set_min_size(&mut self, value: Vector2<f32>) -> &mut Self {
1033        self.min_size.set_value_and_mark_modified(value);
1034        self
1035    }
1036
1037    fn set_min_size_notify(&mut self, value: Vector2<f32>) -> Vector2<f32> {
1038        self.invalidate_layout();
1039        self.min_size.set_value_and_mark_modified(value)
1040    }
1041
1042    /// Sets the new minimum width of the widget.
1043    #[inline]
1044    pub fn set_min_width(&mut self, value: f32) -> &mut Self {
1045        self.min_size.x = value;
1046        self
1047    }
1048
1049    /// Sets the new minimum height of the widget.
1050    #[inline]
1051    pub fn set_min_height(&mut self, value: f32) -> &mut Self {
1052        self.min_size.y = value;
1053        self
1054    }
1055
1056    /// Sets the new minimum size of the widget.
1057    #[inline]
1058    pub fn min_size(&self) -> Vector2<f32> {
1059        *self.min_size
1060    }
1061
1062    /// Returns the minimum width of the widget.
1063    #[inline]
1064    pub fn min_width(&self) -> f32 {
1065        self.min_size.x
1066    }
1067
1068    /// Returns the minimum height of the widget.
1069    #[inline]
1070    pub fn min_height(&self) -> f32 {
1071        self.min_size.y
1072    }
1073
1074    /// Return `true` if the dragging of the widget is allowed, `false` - otherwise.
1075    #[inline]
1076    pub fn is_drag_allowed(&self) -> bool {
1077        *self.allow_drag
1078    }
1079
1080    /// Return `true` if the dropping of other widgets is allowed on this widget, `false` - otherwise.
1081    #[inline]
1082    pub fn is_drop_allowed(&self) -> bool {
1083        *self.allow_drop
1084    }
1085
1086    /// Maps the given point from screen to local widget's coordinates. Could be used to transform
1087    /// mouse cursor position (which is in screen space) to local widget coordinates.
1088    #[inline]
1089    pub fn screen_to_local(&self, point: Vector2<f32>) -> Vector2<f32> {
1090        self.visual_transform
1091            .try_inverse()
1092            .unwrap_or_default()
1093            .transform_point(&Point2::from(point))
1094            .coords
1095    }
1096
1097    /// Invalidates layout of the widget. **WARNING**: Do not use this method, unless you understand what you're doing,
1098    /// it will cause new layout pass for this widget which could be quite heavy and doing so on every frame for multiple
1099    /// widgets **will** cause severe performance issues.
1100    #[inline]
1101    pub fn invalidate_layout(&self) {
1102        self.invalidate_measure();
1103        self.invalidate_arrange();
1104        self.try_send_transform_changed_event();
1105    }
1106
1107    pub(crate) fn notify_z_index_changed(&self) {
1108        if let Some(sender) = self.layout_events_sender.as_ref() {
1109            sender
1110                .send(LayoutEvent::ZIndexChanged(self.handle))
1111                .unwrap()
1112        }
1113    }
1114
1115    /// Invalidates measurement results of the widget. **WARNING**: Do not use this method, unless you understand what you're
1116    /// doing, it will cause new measurement pass for this widget which could be quite heavy and doing so on every frame for
1117    /// multiple widgets **will** cause severe performance issues.
1118    #[inline]
1119    pub fn invalidate_measure(&self) {
1120        self.measure_valid.set(false);
1121
1122        if let Some(layout_events_sender) = self.layout_events_sender.as_ref() {
1123            let _ = layout_events_sender.send(LayoutEvent::MeasurementInvalidated(self.handle));
1124        }
1125    }
1126
1127    /// Invalidates arrangement results of the widget. **WARNING**: Do not use this method, unless you understand what you're
1128    /// doing, it will cause new arrangement pass for this widget which could be quite heavy and doing so on every frame for
1129    /// multiple widgets **will** cause severe performance issues.
1130    #[inline]
1131    pub fn invalidate_arrange(&self) {
1132        self.arrange_valid.set(false);
1133
1134        if let Some(layout_events_sender) = self.layout_events_sender.as_ref() {
1135            let _ = layout_events_sender.send(LayoutEvent::ArrangementInvalidated(self.handle));
1136        }
1137    }
1138
1139    /// Returns `true` if the widget is able to participate in hit testing, `false` - otherwise.
1140    #[inline]
1141    pub fn is_hit_test_visible(&self) -> bool {
1142        *self.hit_test_visibility
1143    }
1144
1145    /// Sets the new maximum size of the widget.
1146    #[inline]
1147    pub fn set_max_size(&mut self, value: Vector2<f32>) -> &mut Self {
1148        self.max_size.set_value_and_mark_modified(value);
1149        self
1150    }
1151
1152    fn set_max_size_notify(&mut self, value: Vector2<f32>) -> Vector2<f32> {
1153        self.invalidate_layout();
1154        std::mem::replace(&mut self.max_size, value)
1155    }
1156
1157    /// Returns current maximum size of the widget.
1158    #[inline]
1159    pub fn max_size(&self) -> Vector2<f32> {
1160        *self.max_size
1161    }
1162
1163    /// Returns maximum width of the widget.
1164    #[inline]
1165    pub fn max_width(&self) -> f32 {
1166        self.max_size.x
1167    }
1168
1169    /// Return maximum height of the widget.
1170    #[inline]
1171    pub fn max_height(&self) -> f32 {
1172        self.max_size.y
1173    }
1174
1175    /// Sets new Z index for the widget. Z index defines the sorting (stable) index which will be used to "arrange" widgets
1176    /// in the correct order.
1177    #[inline]
1178    pub fn set_z_index(&mut self, z_index: usize) -> &mut Self {
1179        self.z_index.set_value_and_mark_modified(z_index);
1180        self.notify_z_index_changed();
1181        self
1182    }
1183
1184    /// Returns current Z index of the widget.
1185    #[inline]
1186    pub fn z_index(&self) -> usize {
1187        *self.z_index
1188    }
1189
1190    /// Sets the new background of the widget.
1191    #[inline]
1192    pub fn set_background(&mut self, brush: Brush) -> &mut Self {
1193        self.background.property = brush;
1194        self
1195    }
1196
1197    /// Returns current background of the widget.
1198    #[inline]
1199    pub fn background(&self) -> Brush {
1200        self.background.property.clone()
1201    }
1202
1203    /// Sets new foreground of the widget.
1204    #[inline]
1205    pub fn set_foreground(&mut self, brush: Brush) -> &mut Self {
1206        self.foreground.property = brush;
1207        self
1208    }
1209
1210    /// Returns current foreground of the widget.
1211    #[inline]
1212    pub fn foreground(&self) -> Brush {
1213        self.foreground.property.clone()
1214    }
1215
1216    /// Sets new width of the widget.
1217    #[inline]
1218    pub fn set_width(&mut self, width: f32) -> &mut Self {
1219        self.width
1220            .set_value_and_mark_modified(width.clamp(self.min_size.x, self.max_size.x));
1221        self
1222    }
1223
1224    fn set_width_notify(&mut self, width: f32) -> f32 {
1225        self.invalidate_layout();
1226        std::mem::replace(&mut self.width, width)
1227    }
1228
1229    /// Returns current width of the widget.
1230    #[inline]
1231    pub fn width(&self) -> f32 {
1232        *self.width
1233    }
1234
1235    /// Return `true` if the widget is set to be drawn on top of every other, normally drawn, widgets, `false` - otherwise.
1236    pub fn is_draw_on_top(&self) -> bool {
1237        *self.draw_on_top
1238    }
1239
1240    /// Sets new height of the widget.
1241    #[inline]
1242    pub fn set_height(&mut self, height: f32) -> &mut Self {
1243        self.height
1244            .set_value_and_mark_modified(height.clamp(self.min_size.y, self.max_size.y));
1245        self
1246    }
1247
1248    fn set_height_notify(&mut self, height: f32) -> f32 {
1249        self.invalidate_layout();
1250        std::mem::replace(&mut self.height, height)
1251    }
1252
1253    /// Returns current height of the widget.
1254    #[inline]
1255    pub fn height(&self) -> f32 {
1256        *self.height
1257    }
1258
1259    /// Sets the desired local position of the widget.
1260    #[inline]
1261    pub fn set_desired_local_position(&mut self, pos: Vector2<f32>) -> &mut Self {
1262        self.desired_local_position.set_value_and_mark_modified(pos);
1263        self
1264    }
1265
1266    /// Returns current screen-space position of the widget.
1267    #[inline]
1268    pub fn screen_position(&self) -> Vector2<f32> {
1269        Vector2::new(self.visual_transform[6], self.visual_transform[7])
1270    }
1271
1272    #[inline]
1273    pub(crate) fn add_child(&mut self, child: Handle<UiNode>, in_front: bool) {
1274        self.invalidate_layout();
1275        if in_front && !self.children.is_empty() {
1276            self.children.insert(0, child)
1277        } else {
1278            self.children.push(child)
1279        }
1280    }
1281
1282    /// Returns a reference to the slice with the children widgets of this widget.
1283    #[inline(always)]
1284    pub fn children(&self) -> &[Handle<UiNode>] {
1285        &self.children
1286    }
1287
1288    #[inline]
1289    pub(crate) fn clear_children(&mut self) {
1290        self.invalidate_layout();
1291        self.children.clear();
1292    }
1293
1294    #[inline]
1295    pub(crate) fn remove_child(&mut self, child: Handle<UiNode>) {
1296        if let Some(i) = self.children.iter().position(|h| *h == child) {
1297            self.children.remove(i);
1298            self.invalidate_layout();
1299        }
1300    }
1301
1302    /// Returns current parent handle of the widget.
1303    #[inline]
1304    pub fn parent(&self) -> Handle<UiNode> {
1305        self.parent
1306    }
1307
1308    /// Sets new
1309    #[inline]
1310    pub(super) fn set_parent(&mut self, parent: Handle<UiNode>) {
1311        self.parent = parent;
1312    }
1313
1314    /// Sets new column of the widget. Columns are used only by [`crate::grid::Grid`] widget.
1315    #[inline]
1316    pub fn set_column(&mut self, column: usize) -> &mut Self {
1317        self.column.set_value_and_mark_modified(column);
1318        self
1319    }
1320
1321    fn set_column_notify(&mut self, column: usize) -> usize {
1322        self.invalidate_layout();
1323        std::mem::replace(&mut self.column, column)
1324    }
1325
1326    /// Returns current column of the widget. Columns are used only by [`crate::grid::Grid`] widget.
1327    #[inline]
1328    pub fn column(&self) -> usize {
1329        *self.column
1330    }
1331
1332    /// Sets new row of the widget. Rows are used only by [`crate::grid::Grid`] widget.
1333    #[inline]
1334    pub fn set_row(&mut self, row: usize) -> &mut Self {
1335        self.row.set_value_and_mark_modified(row);
1336        self
1337    }
1338
1339    fn set_row_notify(&mut self, row: usize) -> usize {
1340        self.invalidate_layout();
1341        std::mem::replace(&mut self.row, row)
1342    }
1343
1344    /// Returns current row of the widget. Rows are used only by [`crate::grid::Grid`] widget.
1345    #[inline]
1346    pub fn row(&self) -> usize {
1347        *self.row
1348    }
1349
1350    /// Returns the desired size of the widget.
1351    #[inline]
1352    pub fn desired_size(&self) -> Vector2<f32> {
1353        self.desired_size.get()
1354    }
1355
1356    /// Returns current desired local position of the widget.
1357    #[inline]
1358    pub fn desired_local_position(&self) -> Vector2<f32> {
1359        *self.desired_local_position
1360    }
1361
1362    fn set_desired_local_position_notify(&mut self, position: Vector2<f32>) -> Vector2<f32> {
1363        self.invalidate_layout();
1364        self.desired_local_position
1365            .set_value_and_mark_modified(position)
1366    }
1367
1368    /// Returns current screen-space bounds of the widget.
1369    #[inline]
1370    pub fn screen_bounds(&self) -> Rect<f32> {
1371        self.bounding_rect().transform(&self.visual_transform)
1372    }
1373
1374    /// Returns local-space bounding rect of the widget.
1375    #[inline]
1376    pub fn bounding_rect(&self) -> Rect<f32> {
1377        Rect::new(
1378            0.0,
1379            0.0,
1380            self.actual_local_size.get().x,
1381            self.actual_local_size.get().y,
1382        )
1383    }
1384
1385    /// Returns current visual transform of the widget.
1386    #[inline]
1387    pub fn visual_transform(&self) -> &Matrix3<f32> {
1388        &self.visual_transform
1389    }
1390
1391    /// Returns scaling along both axes.
1392    #[inline]
1393    pub fn visual_scaling(&self) -> Vector2<f32> {
1394        self.visual_transform
1395            .transform_vector(&Vector2::new(1.0, 1.0))
1396    }
1397
1398    /// Returns max uniform scaling of both axes.
1399    #[inline]
1400    pub fn visual_max_scaling(&self) -> f32 {
1401        self.visual_scaling().max()
1402    }
1403
1404    /// Sets new render transform.
1405    pub fn set_render_transform(&mut self, transform: Matrix3<f32>) {
1406        self.render_transform = transform;
1407        self.try_send_transform_changed_event();
1408    }
1409
1410    /// Returns current render transform of the widget.
1411    #[inline]
1412    pub fn render_transform(&self) -> &Matrix3<f32> {
1413        &self.render_transform
1414    }
1415
1416    /// Sets new layout transform.
1417    pub fn set_layout_transform(&mut self, transform: Matrix3<f32>) {
1418        self.layout_transform = transform;
1419        self.invalidate_layout();
1420    }
1421
1422    /// Returns current layout transform of the widget.
1423    #[inline]
1424    pub fn layout_transform(&self) -> &Matrix3<f32> {
1425        &self.layout_transform
1426    }
1427
1428    /// Returns `true`, if the widget has a descendant widget with the specified handle, `false` - otherwise.
1429    pub fn has_descendant(&self, node_handle: Handle<UiNode>, ui: &UserInterface) -> bool {
1430        for child_handle in self.children.iter() {
1431            if *child_handle == node_handle {
1432                return true;
1433            }
1434
1435            let result = ui
1436                .nodes
1437                .borrow(*child_handle)
1438                .has_descendant(node_handle, ui);
1439            if result {
1440                return true;
1441            }
1442        }
1443        false
1444    }
1445
1446    /// Searches a node up on tree starting from the given root that matches a criteria defined by the given func.
1447    pub fn find_by_criteria_up<Func: Fn(&UiNode) -> bool>(
1448        &self,
1449        ui: &UserInterface,
1450        func: Func,
1451    ) -> Handle<UiNode> {
1452        let mut parent_handle = self.parent;
1453        while parent_handle.is_some() {
1454            if let Some(parent_node) = ui.nodes.try_borrow(parent_handle) {
1455                if func(parent_node) {
1456                    return parent_handle;
1457                }
1458                parent_handle = parent_node.parent;
1459            } else {
1460                break;
1461            }
1462        }
1463        Handle::NONE
1464    }
1465
1466    /// Handles incoming [`WidgetMessage`]s. This method **must** be called in [`crate::control::Control::handle_routed_message`]
1467    /// of any derived widgets!
1468    pub fn handle_routed_message(&mut self, ui: &mut UserInterface, msg: &mut UiMessage) {
1469        if msg.destination() == self.handle() && msg.direction() == MessageDirection::ToWidget {
1470            if let Some(msg) = msg.data::<WidgetMessage>() {
1471                match msg {
1472                    &WidgetMessage::Opacity(opacity) => {
1473                        self.opacity.set_value_and_mark_modified(opacity);
1474                    }
1475                    WidgetMessage::Background(background) => {
1476                        *self.background = background.clone();
1477                    }
1478                    WidgetMessage::Foreground(foreground) => {
1479                        *self.foreground = foreground.clone();
1480                    }
1481                    WidgetMessage::Name(name) => self.name = ImmutableString::new(name),
1482                    &WidgetMessage::Width(width) => {
1483                        if *self.width != width {
1484                            self.set_width_notify(width);
1485                        }
1486                    }
1487                    &WidgetMessage::Height(height) => {
1488                        if *self.height != height {
1489                            self.set_height_notify(height);
1490                        }
1491                    }
1492                    WidgetMessage::VerticalAlignment(vertical_alignment) => {
1493                        if *self.vertical_alignment != *vertical_alignment {
1494                            self.set_vertical_alignment(*vertical_alignment);
1495                        }
1496                    }
1497                    WidgetMessage::HorizontalAlignment(horizontal_alignment) => {
1498                        if *self.horizontal_alignment != *horizontal_alignment {
1499                            self.set_horizontal_alignment(*horizontal_alignment);
1500                        }
1501                    }
1502                    WidgetMessage::MaxSize(max_size) => {
1503                        if *self.max_size != *max_size {
1504                            self.set_max_size_notify(*max_size);
1505                        }
1506                    }
1507                    WidgetMessage::MinSize(min_size) => {
1508                        if *self.min_size != *min_size {
1509                            self.set_min_size_notify(*min_size);
1510                        }
1511                    }
1512                    &WidgetMessage::Row(row) => {
1513                        if *self.row != row {
1514                            self.set_row_notify(row);
1515                        }
1516                    }
1517                    &WidgetMessage::Column(column) => {
1518                        if *self.column != column {
1519                            self.set_column_notify(column);
1520                        }
1521                    }
1522                    &WidgetMessage::Margin(margin) => {
1523                        if *self.margin != margin {
1524                            self.set_margin_notify(margin);
1525                        }
1526                    }
1527                    WidgetMessage::HitTestVisibility(hit_test_visibility) => {
1528                        self.hit_test_visibility
1529                            .set_value_and_mark_modified(*hit_test_visibility);
1530                    }
1531                    &WidgetMessage::Visibility(visibility) => {
1532                        self.set_visibility(visibility);
1533                    }
1534                    &WidgetMessage::DesiredPosition(pos) => {
1535                        if *self.desired_local_position != pos {
1536                            self.set_desired_local_position_notify(pos);
1537                        }
1538                    }
1539                    &WidgetMessage::Enabled(enabled) => {
1540                        self.enabled.set_value_and_mark_modified(enabled);
1541                    }
1542                    &WidgetMessage::Cursor(icon) => {
1543                        self.cursor.set_value_and_mark_modified(icon);
1544                    }
1545                    WidgetMessage::LayoutTransform(transform) => {
1546                        if &self.layout_transform != transform {
1547                            self.set_layout_transform(*transform);
1548                        }
1549                    }
1550                    WidgetMessage::RenderTransform(transform) => {
1551                        self.set_render_transform(*transform);
1552                    }
1553                    WidgetMessage::ZIndex(index) => {
1554                        if *self.z_index != *index {
1555                            self.set_z_index(*index);
1556                            self.invalidate_layout();
1557                        }
1558                    }
1559                    WidgetMessage::SortChildren(predicate) => {
1560                        self.children
1561                            .sort_unstable_by(|a, b| predicate.0(*a, *b, ui));
1562                        self.invalidate_layout();
1563                    }
1564                    WidgetMessage::Style(style) => {
1565                        self.background.update(style);
1566                        self.foreground.update(style);
1567                        self.style = Some(style.clone());
1568                    }
1569                    _ => (),
1570                }
1571            }
1572        }
1573    }
1574
1575    /// Sets new vertical alignment of the widget.
1576    #[inline]
1577    pub fn set_vertical_alignment(&mut self, vertical_alignment: VerticalAlignment) -> &mut Self {
1578        self.vertical_alignment
1579            .set_value_and_mark_modified(vertical_alignment);
1580        self
1581    }
1582
1583    fn set_vertical_alignment_notify(
1584        &mut self,
1585        vertical_alignment: VerticalAlignment,
1586    ) -> VerticalAlignment {
1587        self.invalidate_layout();
1588        self.vertical_alignment
1589            .set_value_and_mark_modified(vertical_alignment)
1590    }
1591
1592    /// Returns current vertical alignment of the widget.
1593    #[inline]
1594    pub fn vertical_alignment(&self) -> VerticalAlignment {
1595        *self.vertical_alignment
1596    }
1597
1598    /// Sets new horizontal alignment of the widget.
1599    #[inline]
1600    pub fn set_horizontal_alignment(
1601        &mut self,
1602        horizontal_alignment: HorizontalAlignment,
1603    ) -> &mut Self {
1604        self.horizontal_alignment
1605            .set_value_and_mark_modified(horizontal_alignment);
1606        self
1607    }
1608
1609    fn set_horizontal_alignment_notify(
1610        &mut self,
1611        horizontal_alignment: HorizontalAlignment,
1612    ) -> HorizontalAlignment {
1613        self.invalidate_layout();
1614        self.horizontal_alignment
1615            .set_value_and_mark_modified(horizontal_alignment)
1616    }
1617
1618    /// Returns current horizontal alignment of the widget.
1619    #[inline]
1620    pub fn horizontal_alignment(&self) -> HorizontalAlignment {
1621        *self.horizontal_alignment
1622    }
1623
1624    /// Sets new margin of the widget.
1625    #[inline]
1626    pub fn set_margin(&mut self, margin: Thickness) -> &mut Self {
1627        self.margin.set_value_and_mark_modified(margin);
1628        self
1629    }
1630
1631    fn set_margin_notify(&mut self, margin: Thickness) -> Thickness {
1632        self.invalidate_layout();
1633        self.margin.set_value_and_mark_modified(margin)
1634    }
1635
1636    /// Returns current margin of the widget.
1637    #[inline]
1638    pub fn margin(&self) -> Thickness {
1639        *self.margin
1640    }
1641
1642    /// Performs standard measurement of children nodes. It provides available size as a constraint and returns
1643    /// the maximum desired size across all children. As a result, this widget will have this size as its desired
1644    /// size to fit all the children nodes.
1645    #[inline]
1646    pub fn measure_override(
1647        &self,
1648        ui: &UserInterface,
1649        available_size: Vector2<f32>,
1650    ) -> Vector2<f32> {
1651        let mut size: Vector2<f32> = Vector2::default();
1652
1653        for &child in self.children.iter() {
1654            ui.measure_node(child, available_size);
1655            let desired_size = ui.node(child).desired_size();
1656            size.x = size.x.max(desired_size.x);
1657            size.y = size.y.max(desired_size.y);
1658        }
1659
1660        size
1661    }
1662
1663    /// Performs standard arrangement of the children nodes of the widget. It uses input final size to make a final
1664    /// bounding rectangle to arrange children. As a result, all the children nodes will be located at the top-left
1665    /// corner of this widget and stretched to fit its bounds.
1666    #[inline]
1667    pub fn arrange_override(&self, ui: &UserInterface, final_size: Vector2<f32>) -> Vector2<f32> {
1668        let final_rect = Rect::new(0.0, 0.0, final_size.x, final_size.y);
1669
1670        for &child in self.children.iter() {
1671            ui.arrange_node(child, &final_rect);
1672        }
1673
1674        final_size
1675    }
1676
1677    #[inline]
1678    pub(crate) fn commit_arrange(&self, position: Vector2<f32>, size: Vector2<f32>) {
1679        let old_actual_local_size = self.actual_local_size.replace(size);
1680        let old_actual_local_position = self.actual_local_position.replace(position);
1681        self.arrange_valid.set(true);
1682        if old_actual_local_position != position || old_actual_local_size != size {
1683            self.try_send_transform_changed_event();
1684        }
1685    }
1686
1687    fn try_send_transform_changed_event(&self) {
1688        if let Some(sender) = self.layout_events_sender.as_ref() {
1689            let _ = sender.send(LayoutEvent::TransformChanged(self.handle));
1690        }
1691    }
1692
1693    #[inline]
1694    pub(crate) fn set_children(&mut self, children: Vec<Handle<UiNode>>) {
1695        self.invalidate_layout();
1696        self.request_update_visibility();
1697        self.children = children;
1698    }
1699
1700    /// Returns `true` if the widget has a parent object in a resource from which it may restore
1701    /// values of its inheritable properties.
1702    #[inline]
1703    pub fn has_inheritance_parent(&self) -> bool {
1704        self.original_handle_in_resource.is_some() && self.resource.is_some()
1705    }
1706
1707    /// Returns `true` if the current results of arrangement of the widget are valid, `false` - otherwise.
1708    #[inline(always)]
1709    pub fn is_arrange_valid(&self) -> bool {
1710        self.arrange_valid.get()
1711    }
1712
1713    #[inline]
1714    pub(crate) fn commit_measure(&self, desired_size: Vector2<f32>) {
1715        self.desired_size.set(desired_size);
1716        self.measure_valid.set(true);
1717    }
1718
1719    /// Returns `true` if the current results of measurement of the widget are valid, `false` - otherwise.
1720    #[inline(always)]
1721    pub fn is_measure_valid(&self) -> bool {
1722        self.measure_valid.get()
1723    }
1724
1725    /// Returns current actual local position of the widget. It is valid only after layout pass!
1726    #[inline]
1727    pub fn actual_local_position(&self) -> Vector2<f32> {
1728        self.actual_local_position.get()
1729    }
1730
1731    /// Returns center point of the widget. It is valid only after layout pass!
1732    #[inline]
1733    pub fn center(&self) -> Vector2<f32> {
1734        self.actual_local_position() + self.actual_local_size().scale(0.5)
1735    }
1736
1737    #[inline]
1738    pub(crate) fn set_global_visibility(&mut self, value: bool) {
1739        self.prev_global_visibility = self.global_visibility;
1740        self.global_visibility = value;
1741    }
1742
1743    /// Returns `true` of the widget is globally visible, which means that all its parents are visible as well
1744    /// as this widget. It is valid only after the first update of the layout, otherwise if will be always false.
1745    #[inline]
1746    pub fn is_globally_visible(&self) -> bool {
1747        self.global_visibility
1748    }
1749
1750    /// Sets new visibility of the widget.
1751    #[inline]
1752    pub fn set_visibility(&mut self, visibility: bool) -> &mut Self {
1753        if *self.visibility != visibility {
1754            self.set_visibility_notify(visibility);
1755        }
1756        self
1757    }
1758
1759    fn set_visibility_notify(&mut self, visibility: bool) -> bool {
1760        self.invalidate_layout();
1761        self.request_update_visibility();
1762        std::mem::replace(&mut self.visibility, visibility)
1763    }
1764
1765    /// Requests (via event queue, so the request is deferred) the update of the visibility of the widget.
1766    #[inline]
1767    pub fn request_update_visibility(&self) {
1768        if let Some(layout_events_sender) = self.layout_events_sender.as_ref() {
1769            let _ = layout_events_sender.send(LayoutEvent::VisibilityChanged(self.handle));
1770        }
1771    }
1772
1773    /// Returns current visibility of the widget.
1774    #[inline]
1775    pub fn visibility(&self) -> bool {
1776        *self.visibility
1777    }
1778
1779    /// Enables or disables the widget. Disabled widgets does not interact with user and usually greyed out.
1780    #[inline]
1781    pub fn set_enabled(&mut self, enabled: bool) -> &mut Self {
1782        self.enabled.set_value_and_mark_modified(enabled);
1783        self
1784    }
1785
1786    /// Returns `true` if the widget if enabled, `false` - otherwise.
1787    #[inline]
1788    pub fn enabled(&self) -> bool {
1789        *self.enabled
1790    }
1791
1792    /// Sets new cursor of the widget.
1793    #[inline]
1794    pub fn set_cursor(&mut self, cursor: Option<CursorIcon>) {
1795        self.cursor.set_value_and_mark_modified(cursor);
1796    }
1797
1798    /// Returns current cursor of the widget.
1799    #[inline]
1800    pub fn cursor(&self) -> Option<CursorIcon> {
1801        *self.cursor
1802    }
1803
1804    /// Tries to fetch user-defined data of the specified type `T`.
1805    #[inline]
1806    pub fn user_data_cloned<T: Clone + 'static>(&self) -> Option<T> {
1807        self.user_data.as_ref().and_then(|v| {
1808            let guard = v.safe_lock();
1809            guard.downcast_ref::<T>().cloned()
1810        })
1811    }
1812
1813    /// Returns current clipping bounds of the widget. It is valid only after at least one layout pass.
1814    #[inline]
1815    pub fn clip_bounds(&self) -> Rect<f32> {
1816        self.clip_bounds.get()
1817    }
1818
1819    /// Set new opacity of the widget. Opacity should be in `[0.0..1.0]` range.
1820    #[inline]
1821    pub fn set_opacity(&mut self, opacity: Option<f32>) -> &mut Self {
1822        self.opacity.set_value_and_mark_modified(opacity);
1823        self
1824    }
1825
1826    /// Returns current opacity of the widget.
1827    #[inline]
1828    pub fn opacity(&self) -> Option<f32> {
1829        *self.opacity
1830    }
1831
1832    /// Returns current tooltip handle of the widget.
1833    #[inline]
1834    pub fn tooltip(&self) -> Option<RcUiNodeHandle> {
1835        self.tooltip.clone()
1836    }
1837
1838    /// Sets new tooltip handle of the widget (if any).
1839    #[inline]
1840    pub fn set_tooltip(&mut self, tooltip: Option<RcUiNodeHandle>) -> &mut Self {
1841        self.tooltip = tooltip;
1842        self
1843    }
1844
1845    /// Returns maximum available time to show the tooltip after the cursor was moved away from the widget.
1846    #[inline]
1847    pub fn tooltip_time(&self) -> f32 {
1848        self.tooltip_time
1849    }
1850
1851    /// Set the maximum available time to show the tooltip after the cursor was moved away from the widget.
1852    #[inline]
1853    pub fn set_tooltip_time(&mut self, tooltip_time: f32) -> &mut Self {
1854        self.tooltip_time = tooltip_time;
1855        self
1856    }
1857
1858    /// Returns current context menu of the widget.
1859    #[inline]
1860    pub fn context_menu(&self) -> Option<RcUiNodeHandle> {
1861        self.context_menu.clone()
1862    }
1863
1864    /// The context menu receives `PopupMessage`s for being displayed, and so should support those.
1865    #[inline]
1866    pub fn set_context_menu(&mut self, context_menu: Option<RcUiNodeHandle>) -> &mut Self {
1867        self.context_menu = context_menu;
1868        self
1869    }
1870}
1871
1872/// Implements `Deref<Target = Widget> + DerefMut` for your widget. It is used to reduce boilerplate code and
1873/// make it less bug-prone.
1874#[macro_export]
1875macro_rules! define_widget_deref {
1876    ($ty: ty) => {
1877        impl Deref for $ty {
1878            type Target = Widget;
1879
1880            fn deref(&self) -> &Self::Target {
1881                &self.widget
1882            }
1883        }
1884
1885        impl DerefMut for $ty {
1886            fn deref_mut(&mut self) -> &mut Self::Target {
1887                &mut self.widget
1888            }
1889        }
1890    };
1891}
1892
1893/// Widget builder creates [`Widget`] instances.
1894pub struct WidgetBuilder {
1895    /// Name of the widget.
1896    pub name: String,
1897    /// Width of the widget.
1898    pub width: f32,
1899    /// Height of the widget.
1900    pub height: f32,
1901    /// Desired position of the widget.
1902    pub desired_position: Vector2<f32>,
1903    /// Vertical alignment of the widget.
1904    pub vertical_alignment: VerticalAlignment,
1905    /// Horizontal alignment of the widget.
1906    pub horizontal_alignment: HorizontalAlignment,
1907    /// Max size of the widget.
1908    pub max_size: Option<Vector2<f32>>,
1909    /// Min size of the widget.
1910    pub min_size: Option<Vector2<f32>>,
1911    /// Background brush of the widget.
1912    pub background: Option<StyledProperty<Brush>>,
1913    /// Foreground brush of the widget.
1914    pub foreground: Option<StyledProperty<Brush>>,
1915    /// Row index of the widget.
1916    pub row: usize,
1917    /// Column index of the widget.
1918    pub column: usize,
1919    /// Margin of the widget.
1920    pub margin: Thickness,
1921    /// Children handles of the widget.
1922    pub children: Vec<Handle<UiNode>>,
1923    /// Whether the hit test is enabled or not.
1924    pub is_hit_test_visible: bool,
1925    /// Whether the widget is visible or not.
1926    pub visibility: bool,
1927    /// Z index of the widget.
1928    pub z_index: usize,
1929    /// Whether the dragging of the widget is allowed or not.
1930    pub allow_drag: bool,
1931    /// Whether the drop of the widget is allowed or not.
1932    pub allow_drop: bool,
1933    /// User-defined data.
1934    pub user_data: Option<Arc<Mutex<dyn Any + Send>>>,
1935    /// Whether to draw the widget on top of any other or not.
1936    pub draw_on_top: bool,
1937    /// Whether the widget is enabled or not.
1938    pub enabled: bool,
1939    /// Cursor of the widget.
1940    pub cursor: Option<CursorIcon>,
1941    /// Opacity of the widget.
1942    pub opacity: Option<f32>,
1943    /// Tooltip of the widget.
1944    pub tooltip: Option<RcUiNodeHandle>,
1945    /// Visibility interval (in seconds) of the tooltip of the widget.
1946    pub tooltip_time: f32,
1947    /// Context menu of the widget.
1948    pub context_menu: Option<RcUiNodeHandle>,
1949    /// Whether the preview messages is enabled or not.
1950    pub preview_messages: bool,
1951    /// Whether the widget will handle OS events or not.
1952    pub handle_os_events: bool,
1953    /// Whether the widget will be updated or not.
1954    pub need_update: bool,
1955    /// Layout transform of the widget.
1956    pub layout_transform: Matrix3<f32>,
1957    /// Render transform of the widget.
1958    pub render_transform: Matrix3<f32>,
1959    /// Whether the widget bounds should be clipped by its parent or not.
1960    pub clip_to_bounds: bool,
1961    /// Unique id of the widget.
1962    pub id: Uuid,
1963    /// Defines the order in which this widget will get keyboard focus when Tab key is pressed.
1964    /// If set to [`None`], Tab key won't do anything on such widget. Default is [`None`].
1965    pub tab_index: Option<usize>,
1966    /// A flag, that defines whether the Tab key navigation is enabled or disabled for this widget.
1967    pub tab_stop: bool,
1968    /// A flag, that indicates that the widget accepts user input.
1969    pub accepts_input: bool,
1970    /// A material that will be used for rendering.
1971    pub material: WidgetMaterial,
1972    /// Style of the widget.
1973    pub style: StyleResource,
1974}
1975
1976impl Default for WidgetBuilder {
1977    fn default() -> Self {
1978        Self::new()
1979    }
1980}
1981
1982impl WidgetBuilder {
1983    /// Creates new widget builder with the default values.
1984    pub fn new() -> Self {
1985        Self {
1986            name: Default::default(),
1987            width: f32::NAN,
1988            height: f32::NAN,
1989            vertical_alignment: VerticalAlignment::default(),
1990            horizontal_alignment: HorizontalAlignment::default(),
1991            max_size: None,
1992            min_size: None,
1993            background: None,
1994            foreground: None,
1995            row: 0,
1996            column: 0,
1997            margin: Thickness::zero(),
1998            desired_position: Vector2::default(),
1999            children: Vec::new(),
2000            is_hit_test_visible: true,
2001            visibility: true,
2002            z_index: 0,
2003            allow_drag: false,
2004            allow_drop: false,
2005            user_data: None,
2006            draw_on_top: false,
2007            enabled: true,
2008            cursor: None,
2009            opacity: None,
2010            tooltip: Default::default(),
2011            tooltip_time: 0.1,
2012            context_menu: Default::default(),
2013            preview_messages: false,
2014            handle_os_events: false,
2015            need_update: false,
2016            layout_transform: Matrix3::identity(),
2017            render_transform: Matrix3::identity(),
2018            clip_to_bounds: true,
2019            id: Uuid::new_v4(),
2020            tab_index: None,
2021            tab_stop: false,
2022            accepts_input: false,
2023            material: Default::default(),
2024            style: DEFAULT_STYLE.resource.clone(),
2025        }
2026    }
2027
2028    /// Enables or disables message previewing of the widget. It basically defines whether the [`crate::Control::preview_message`] will
2029    /// be called or not.
2030    pub fn with_preview_messages(mut self, state: bool) -> Self {
2031        self.preview_messages = state;
2032        self
2033    }
2034
2035    /// Enables or disables OS event handling of the widget. It basically defines whether the [`crate::Control::handle_os_event`] will
2036    /// be called or not.
2037    pub fn with_handle_os_events(mut self, state: bool) -> Self {
2038        self.handle_os_events = state;
2039        self
2040    }
2041
2042    /// Enables or disables updating of the widget. It basically defines whether the [`crate::Control::update`] will
2043    /// be called or not.
2044    pub fn with_need_update(mut self, state: bool) -> Self {
2045        self.need_update = state;
2046        self
2047    }
2048
2049    /// Sets the desired width of the widget.
2050    pub fn with_width(mut self, width: f32) -> Self {
2051        self.width = width;
2052        self
2053    }
2054
2055    /// Sets the desired height of the widget.
2056    pub fn with_height(mut self, height: f32) -> Self {
2057        self.height = height;
2058        self
2059    }
2060
2061    /// Enables or disables clipping of widget's bound to its parent's bounds.
2062    pub fn with_clip_to_bounds(mut self, clip_to_bounds: bool) -> Self {
2063        self.clip_to_bounds = clip_to_bounds;
2064        self
2065    }
2066
2067    /// Enables or disables the widget.
2068    pub fn with_enabled(mut self, enabled: bool) -> Self {
2069        self.enabled = enabled;
2070        self
2071    }
2072
2073    /// Sets the desired vertical alignment of the widget.
2074    pub fn with_vertical_alignment(mut self, valign: VerticalAlignment) -> Self {
2075        self.vertical_alignment = valign;
2076        self
2077    }
2078
2079    /// Sets the desired horizontal alignment of the widget.
2080    pub fn with_horizontal_alignment(mut self, halign: HorizontalAlignment) -> Self {
2081        self.horizontal_alignment = halign;
2082        self
2083    }
2084
2085    /// Sets the max size of the widget.
2086    pub fn with_max_size(mut self, max_size: Vector2<f32>) -> Self {
2087        self.max_size = Some(max_size);
2088        self
2089    }
2090
2091    /// Sets the min size of the widget.
2092    pub fn with_min_size(mut self, min_size: Vector2<f32>) -> Self {
2093        self.min_size = Some(min_size);
2094        self
2095    }
2096
2097    /// Sets the desired background brush of the widget.
2098    pub fn with_background(mut self, brush: StyledProperty<Brush>) -> Self {
2099        self.background = Some(brush);
2100        self
2101    }
2102
2103    /// Sets the desired foreground brush of the widget.
2104    pub fn with_foreground(mut self, brush: StyledProperty<Brush>) -> Self {
2105        self.foreground = Some(brush);
2106        self
2107    }
2108
2109    /// Sets the desired row index of the widget.
2110    pub fn on_row(mut self, row: usize) -> Self {
2111        self.row = row;
2112        self
2113    }
2114
2115    /// Sets the desired column index of the widget.
2116    pub fn on_column(mut self, column: usize) -> Self {
2117        self.column = column;
2118        self
2119    }
2120
2121    /// Sets the desired margin of the widget.
2122    pub fn with_margin(mut self, margin: Thickness) -> Self {
2123        self.margin = margin;
2124        self
2125    }
2126
2127    /// Sets the desired, uniform margin of the widget.
2128    pub fn with_uniform_margin(mut self, margin: f32) -> Self {
2129        self.margin = Thickness::uniform(margin);
2130        self
2131    }
2132
2133    /// Sets the desired position of the widget.
2134    pub fn with_desired_position(mut self, desired_position: Vector2<f32>) -> Self {
2135        self.desired_position = desired_position;
2136        self
2137    }
2138
2139    /// Sets the desired layout transform of the widget.
2140    pub fn with_layout_transform(mut self, layout_transform: Matrix3<f32>) -> Self {
2141        self.layout_transform = layout_transform;
2142        self
2143    }
2144
2145    /// Sets the desired render transform of the widget.
2146    pub fn with_render_transform(mut self, render_transform: Matrix3<f32>) -> Self {
2147        self.render_transform = render_transform;
2148        self
2149    }
2150
2151    /// Sets the desired Z index of the widget.
2152    pub fn with_z_index(mut self, z_index: usize) -> Self {
2153        self.z_index = z_index;
2154        self
2155    }
2156
2157    /// Adds a child handle to the widget. [`Handle::NONE`] values are ignored.
2158    pub fn with_child(mut self, handle: Handle<UiNode>) -> Self {
2159        if handle.is_some() {
2160            self.children.push(handle);
2161        }
2162        self
2163    }
2164
2165    /// Enables or disables top-most widget drawing.
2166    pub fn with_draw_on_top(mut self, draw_on_top: bool) -> Self {
2167        self.draw_on_top = draw_on_top;
2168        self
2169    }
2170
2171    /// Sets the desired set of children nodes.
2172    pub fn with_children<I: IntoIterator<Item = Handle<UiNode>>>(mut self, children: I) -> Self {
2173        for child in children.into_iter() {
2174            if child.is_some() {
2175                self.children.push(child)
2176            }
2177        }
2178        self
2179    }
2180
2181    /// Sets the desired widget name.
2182    pub fn with_name(mut self, name: &str) -> Self {
2183        self.name = String::from(name);
2184        self
2185    }
2186
2187    /// Enables or disables hit test of the widget.
2188    pub fn with_hit_test_visibility(mut self, state: bool) -> Self {
2189        self.is_hit_test_visible = state;
2190        self
2191    }
2192
2193    /// Sets the desired widget visibility.
2194    pub fn with_visibility(mut self, visibility: bool) -> Self {
2195        self.visibility = visibility;
2196        self
2197    }
2198
2199    /// Enables or disables an ability to drop other widgets on this widget.
2200    pub fn with_allow_drop(mut self, allow_drop: bool) -> Self {
2201        self.allow_drop = allow_drop;
2202        self
2203    }
2204
2205    /// Enables or disables dragging of the widget.
2206    pub fn with_allow_drag(mut self, allow_drag: bool) -> Self {
2207        self.allow_drag = allow_drag;
2208        self
2209    }
2210
2211    /// Sets the desired widget user data.
2212    pub fn with_user_data(mut self, user_data: Arc<Mutex<dyn Any + Send>>) -> Self {
2213        self.user_data = Some(user_data);
2214        self
2215    }
2216
2217    /// Sets the desired widget cursor.
2218    pub fn with_cursor(mut self, cursor: Option<CursorIcon>) -> Self {
2219        self.cursor = cursor;
2220        self
2221    }
2222
2223    /// Sets the desired widget opacity.
2224    pub fn with_opacity(mut self, opacity: Option<f32>) -> Self {
2225        self.opacity = opacity;
2226        self
2227    }
2228
2229    /// Sets the desired widget id.
2230    pub fn with_id(mut self, id: Uuid) -> Self {
2231        self.id = id;
2232        self
2233    }
2234
2235    /// Sets the desired tooltip for the node.
2236    ///
2237    /// ## Important
2238    ///
2239    /// The widget will share the tooltip, which means that when widget will be deleted, the
2240    /// tooltip will be deleted only if there's no one use the tooltip anymore.
2241    pub fn with_tooltip(mut self, tooltip: RcUiNodeHandle) -> Self {
2242        self.tooltip = Some(tooltip);
2243        self
2244    }
2245
2246    /// Sets the desired tooltip for the node.
2247    ///
2248    /// ## Important
2249    ///
2250    /// The widget will share the tooltip, which means that when widget will be deleted, the
2251    /// tooltip will be deleted only if there's no one use the tooltip anymore.
2252    pub fn with_opt_tooltip(mut self, tooltip: Option<RcUiNodeHandle>) -> Self {
2253        self.tooltip = tooltip;
2254        self
2255    }
2256
2257    /// Sets the desired tooltip time.
2258    pub fn with_tooltip_time(mut self, tooltip_time: f32) -> Self {
2259        self.tooltip_time = tooltip_time;
2260        self
2261    }
2262
2263    /// The context menu receives `PopupMessage`s for being displayed, and so should support those.
2264    pub fn with_context_menu(mut self, context_menu: RcUiNodeHandle) -> Self {
2265        self.context_menu = Some(context_menu);
2266        self
2267    }
2268
2269    /// Sets the desired tab index.
2270    pub fn with_tab_index(mut self, tab_index: Option<usize>) -> Self {
2271        self.tab_index = tab_index;
2272        self
2273    }
2274
2275    /// Sets a flag, that defines whether the Tab key navigation is enabled or disabled for this widget.
2276    pub fn with_tab_stop(mut self, tab_stop: bool) -> Self {
2277        self.tab_stop = tab_stop;
2278        self
2279    }
2280
2281    /// Sets a flag, that indicates that the widget accepts user input.
2282    pub fn with_accepts_input(mut self, accepts_input: bool) -> Self {
2283        self.accepts_input = accepts_input;
2284        self
2285    }
2286
2287    /// Sets a material which will be used for rendering of this widget.
2288    pub fn with_material(mut self, material: WidgetMaterial) -> Self {
2289        self.material = material;
2290        self
2291    }
2292
2293    /// Finishes building of the base widget.
2294    pub fn build(self, ctx: &BuildContext) -> Widget {
2295        Widget {
2296            handle: Default::default(),
2297            name: self.name.into(),
2298            desired_local_position: self.desired_position.into(),
2299            width: self.width.into(),
2300            height: self.height.into(),
2301            desired_size: Cell::new(Vector2::default()),
2302            actual_local_position: Cell::new(Vector2::default()),
2303            actual_local_size: Cell::new(Vector2::default()),
2304            min_size: self.min_size.unwrap_or_default().into(),
2305            max_size: self
2306                .max_size
2307                .unwrap_or_else(|| Vector2::new(f32::INFINITY, f32::INFINITY))
2308                .into(),
2309            background: self
2310                .background
2311                .unwrap_or_else(|| ctx.style.property(Style::BRUSH_PRIMARY))
2312                .into(),
2313            foreground: self
2314                .foreground
2315                .unwrap_or_else(|| ctx.style.property(Style::BRUSH_FOREGROUND))
2316                .into(),
2317            row: self.row.into(),
2318            column: self.column.into(),
2319            vertical_alignment: self.vertical_alignment.into(),
2320            horizontal_alignment: self.horizontal_alignment.into(),
2321            margin: self.margin.into(),
2322            visibility: self.visibility.into(),
2323            global_visibility: true,
2324            prev_global_visibility: false,
2325            children: self.children,
2326            parent: Handle::NONE,
2327            command_indices: Default::default(),
2328            is_mouse_directly_over: false,
2329            measure_valid: Cell::new(false),
2330            arrange_valid: Cell::new(false),
2331            hit_test_visibility: self.is_hit_test_visible.into(),
2332            prev_measure: Default::default(),
2333            prev_arrange: Default::default(),
2334            z_index: self.z_index.into(),
2335            allow_drag: self.allow_drag.into(),
2336            allow_drop: self.allow_drop.into(),
2337            user_data: self.user_data.clone(),
2338            draw_on_top: self.draw_on_top.into(),
2339            enabled: self.enabled.into(),
2340            cursor: self.cursor.into(),
2341            clip_bounds: Cell::new(Default::default()),
2342            opacity: self.opacity.into(),
2343            tooltip: self.tooltip,
2344            tooltip_time: self.tooltip_time,
2345            context_menu: self.context_menu,
2346            preview_messages: self.preview_messages,
2347            handle_os_events: self.handle_os_events,
2348            tab_index: self.tab_index.into(),
2349            tab_stop: self.tab_stop.into(),
2350            need_update: self.need_update,
2351            ignore_layout_rounding: false,
2352            accepts_input: self.accepts_input,
2353            layout_events_sender: None,
2354            layout_transform: self.layout_transform,
2355            render_transform: self.render_transform,
2356            visual_transform: Matrix3::identity(),
2357            clip_to_bounds: self.clip_to_bounds.into(),
2358            id: self.id,
2359            is_resource_instance_root: false,
2360            resource: None,
2361            material: self.material.into(),
2362            original_handle_in_resource: Default::default(),
2363            style: Some(ctx.style.clone()),
2364        }
2365    }
2366}