makepad_widgets/
widget.rs

1pub use crate::register_widget;
2use {
3    crate::makepad_draw::*,
4    crate::designer_data::DesignerDataToWidget,
5    std::any::TypeId,
6    std::cell::RefCell,
7    std::collections::BTreeMap,
8    std::fmt,
9    std::sync::Arc,
10    std::fmt::{Debug, Error, Formatter},
11    std::rc::Rc,
12};
13
14#[derive(Clone, Copy)]
15pub enum WidgetCache {
16    Yes,
17    No,
18    Clear,
19}
20
21#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
22pub struct WidgetUid(pub u64);
23
24pub trait WidgetDesign: WidgetNode {}
25
26#[derive(Clone, Debug, DefaultNone)]
27pub enum WidgetDesignAction {
28    PickedBody,
29    None,
30}
31
32pub trait WidgetNode: LiveApply {
33    fn widget_design(&mut self) -> Option<&mut dyn WidgetDesign> {
34        return None;
35    }
36    fn uid_to_widget(&self, _uid: WidgetUid) -> WidgetRef;
37    fn find_widgets(&self, _path: &[LiveId], _cached: WidgetCache, _results: &mut WidgetSet);
38    fn walk(&mut self, _cx: &mut Cx) -> Walk;
39    fn area(&self) -> Area; //{return Area::Empty;}
40    fn redraw(&mut self, _cx: &mut Cx);
41    fn set_action_data(&mut self, _data:Arc<dyn ActionTrait>){}
42    fn action_data(&self)->Option<Arc<dyn ActionTrait>>{None}
43        
44    fn set_visible(&mut self, _cx:&mut Cx, _visible:bool){}
45    fn visible(&self) -> bool {true}
46}
47
48pub trait Widget: WidgetNode {
49    fn handle_event_with(
50        &mut self,
51        cx: &mut Cx,
52        event: &Event,
53        scope: &mut Scope,
54        _sweep_area: Area,
55    ) {
56        self.handle_event(cx, event, scope)
57    }
58    fn handle_event(&mut self, _cx: &mut Cx, _event: &Event, _scope: &mut Scope) {}
59
60    fn widget(&self, path: &[LiveId]) -> WidgetRef {
61        let mut results = WidgetSet::default();
62        self.find_widgets(path, WidgetCache::Yes, &mut results);
63        return results.into_first();
64    }
65
66    fn widgets(&self, paths: &[&[LiveId]]) -> WidgetSet {
67        let mut results = WidgetSet::default();
68        for path in paths {
69            self.find_widgets(path, WidgetCache::Yes, &mut results);
70        }
71        results
72    }
73
74    // fn widget_uid(&self)->WidgetUid;
75    fn widget_uid(&self) -> WidgetUid {
76        return WidgetUid(self as *const _ as *const () as u64);
77    }
78
79    fn widget_to_data(
80        &self,
81        _cx: &mut Cx,
82        _actions: &Actions,
83        _nodes: &mut LiveNodeVec,
84        _path: &[LiveId],
85    ) -> bool {
86        false
87    }
88    fn data_to_widget(&mut self, _cx: &mut Cx, _nodes: &[LiveNode], _path: &[LiveId]) {}
89    
90    fn draw_3d(&mut self, _cx:&mut Cx3d, _scope: &mut Scope)->DrawStep{
91        DrawStep::done()
92    }
93    
94    fn draw_3d_all(&mut self, cx:&mut Cx3d, scope: &mut Scope){
95        while self.draw_3d(cx, scope).is_step() {}
96    }
97    
98    fn draw_walk(&mut self, _cx: &mut Cx2d, _scope: &mut Scope, _walk: Walk) -> DrawStep{
99        DrawStep::done()
100    }
101
102    fn draw(&mut self, cx: &mut Cx2d, scope: &mut Scope) -> DrawStep {
103        let walk = self.walk(cx);
104        self.draw_walk(cx, scope, walk)
105    }
106
107    fn draw_walk_all(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) {
108        while self.draw_walk(cx, scope, walk).is_step() {}
109    }
110    
111    fn draw_all(&mut self, cx: &mut Cx2d, scope: &mut Scope) {
112        while self.draw(cx, scope).is_step() {}
113    }
114    
115    fn draw_unscoped(&mut self, cx: &mut Cx2d) -> DrawStep {
116       self.draw(cx, &mut Scope::empty())
117    }
118    
119    fn draw_all_unscoped(&mut self, cx: &mut Cx2d) {
120        self.draw_all(cx, &mut Scope::empty());
121    }
122        
123    
124    fn text(&self) -> String {
125        String::new()
126    }
127
128    fn set_text(&mut self, _cx:&mut Cx, _v: &str) {}
129    
130    fn set_key_focus(&self, cx:&mut Cx){
131        cx.set_key_focus(self.area())
132    }
133    
134    fn key_focus(&self, cx:&Cx)->bool{
135        cx.has_key_focus(self.area())
136    }
137    
138    fn set_disabled(&mut self, _cx:&mut Cx, _disabled:bool){
139    }
140                
141    fn disabled(&self, _cx:&Cx) -> bool {
142        false
143    }
144        
145    /*fn set_text_and_redraw(&mut self, cx: &mut Cx, v: &str) {
146        self.set_text(v);
147        self.redraw(cx);
148    }*/
149    /*
150    fn create_child(
151        &mut self,
152        _cx: &mut Cx,
153        _live_ptr: LivePtr,
154        _at: CreateAt,
155        _new_id: LiveId,
156        _nodes: &[LiveNode]
157    ) -> WidgetRef {
158        WidgetRef::empty()
159    }
160
161    fn find_template(&self, _id: &[LiveId; 1]) -> Option<LivePtr> {
162        None
163    }*/
164
165    fn ref_cast_type_id(&self) -> LiveType
166    where
167        Self: 'static,
168    {
169        LiveType::of::<Self>()
170    }
171
172    fn ui_runner(&self) -> UiRunner<Self> where Self: Sized + 'static {
173        UiRunner::new(self.widget_uid().0 as usize)
174    }
175}
176
177#[derive(Clone, Copy)]
178pub enum CreateAt {
179    Template,
180    Begin,
181    After(LiveId),
182    Before(LiveId),
183    End,
184}
185
186pub trait DrawStepApi {
187    fn done() -> DrawStep {
188        Result::Ok(())
189    }
190    fn make_step_here(arg: WidgetRef) -> DrawStep {
191        Result::Err(arg)
192    }
193    fn make_step() -> DrawStep {
194        Result::Err(WidgetRef::empty())
195    }
196    fn is_done(&self) -> bool;
197    fn is_step(&self) -> bool;
198    fn step(self) -> Option<WidgetRef>;
199}
200
201impl DrawStepApi for DrawStep {
202    fn is_done(&self) -> bool {
203        match *self {
204            Result::Ok(_) => true,
205            Result::Err(_) => false,
206        }
207    }
208    fn is_step(&self) -> bool {
209        match *self {
210            Result::Ok(_) => false,
211            Result::Err(_) => true,
212        }
213    }
214
215    fn step(self) -> Option<WidgetRef> {
216        match self {
217            Result::Ok(_) => None,
218            Result::Err(nd) => Some(nd),
219        }
220    }
221}
222
223pub type DrawStep = Result<(), WidgetRef>;
224
225generate_any_trait_api!(Widget);
226
227pub trait WidgetFactory {
228    fn new(&self, cx: &mut Cx) -> Box<dyn Widget>;
229}
230
231#[derive(Default, LiveComponentRegistry)]
232pub struct WidgetRegistry {
233    pub map: BTreeMap<LiveType, (LiveComponentInfo, Box<dyn WidgetFactory>)>,
234}
235
236pub struct WidgetRefInner {
237    pub widget: Box<dyn Widget>,
238}
239#[derive(Clone, Default)]
240pub struct WidgetRef(Rc<RefCell<Option<WidgetRefInner>>>);
241
242impl Debug for WidgetRef {
243    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
244        write!(f, "WidgetRef {}", self.widget_uid().0)
245    }
246}
247
248#[derive(Default, Clone, Debug)]
249pub struct WidgetSet(pub SmallVec<[WidgetRef;2]>);
250
251impl WidgetSet {
252    pub fn is_empty(&mut self) -> bool {
253        self.0.len() == 0
254    }
255
256    pub fn push(&mut self, item: WidgetRef) {
257        self.0.push(item);
258    }
259
260    pub fn extend_from_set(&mut self, other: &WidgetSet) {
261        for item in other.iter(){
262            self.0.push(item.clone())
263        }
264    }
265
266    pub fn into_first(self) -> WidgetRef {
267        for item in self.0{
268            return item
269        }
270        WidgetRef::empty()
271    }
272
273    pub fn widgets(&self, paths: &[&[LiveId]]) -> WidgetSet {
274        let mut results = WidgetSet::default();
275        for widget in &self.0 {
276            if let Some(inner) = widget.0.borrow().as_ref() {
277                for path in paths {
278                    inner
279                        .widget
280                        .find_widgets(path, WidgetCache::Yes, &mut results);
281                }
282            }
283        }
284        results
285    }
286
287    pub fn contains(&self, widget: &WidgetRef) -> bool {
288        for item in &self.0 {
289            if *item == *widget {
290                return true;
291            }
292        }
293        false
294    }
295}
296
297impl LiveHook for WidgetSet {}
298impl LiveApply for WidgetSet {
299    fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
300        for inner in &self.0 {
301            let mut inner = inner.0.borrow_mut();
302            if let Some(component) = &mut *inner {
303                return component.widget.apply(cx, apply, index, nodes);
304            }
305        }
306        nodes.skip_node(index)
307    }
308}
309
310impl WidgetSet {
311    pub fn empty() -> Self {
312        Self::default()
313    }
314    
315    pub fn set_text(&self, cx: &mut Cx, v: &str) {
316        for item in &self.0 {
317            item.set_text(cx, v)
318        }
319    }
320
321    pub fn iter(&self)->WidgetSetIterator{
322        return WidgetSetIterator{
323            widget_set: self,
324            index: 0
325        }
326    }
327    
328    pub fn filter_actions<'a>(&'a self, actions:&'a Actions)-> impl Iterator<Item = &'a WidgetAction>{
329        actions.filter_widget_actions_set(self)
330    }
331}
332
333
334pub struct WidgetSetIterator<'a> {
335    widget_set: &'a WidgetSet,
336    index: usize,
337}
338
339impl<'a> Iterator for WidgetSetIterator<'a> {
340    // We can refer to this type using Self::Item
341    type Item = &'a WidgetRef;
342    fn next(&mut self) -> Option<Self::Item> {
343        if self.index < self.widget_set.0.len(){
344            let idx = self.index;
345            self.index += 1;
346            return Some(&self.widget_set.0[idx])
347        }
348        None
349    }
350}
351
352impl PartialEq for WidgetRef {
353    fn eq(&self, other: &WidgetRef) -> bool {
354        Rc::ptr_eq(&self.0, &other.0)
355    }
356
357    fn ne(&self, other: &WidgetRef) -> bool {
358        !Rc::ptr_eq(&self.0, &other.0)
359    }
360}
361pub trait OptionWidgetRefExt{
362    fn into_ref(self) -> WidgetRef;
363}
364impl OptionWidgetRefExt for Option<WidgetRef>{
365    fn into_ref(self) -> WidgetRef{
366        if let Some(v) = self{
367            return v
368        }
369        else{
370            WidgetRef::empty()
371        }     
372    }
373}
374
375impl WidgetRef {
376    pub fn into_option(self)->Option<WidgetRef>{
377        if self.is_empty(){
378            None
379        }
380        else{
381            Some(self)
382        }
383    }
384    
385    pub fn empty() -> Self {
386        Self(Rc::new(RefCell::new(None)))
387    }
388
389    pub fn is_empty(&self) -> bool {
390        self.0.borrow().as_ref().is_none()
391    }
392
393    pub fn new_with_inner(widget: Box<dyn Widget>) -> Self {
394        Self(Rc::new(RefCell::new(Some(WidgetRefInner { widget }))))
395    }
396    /// ## handle event with a sweep area
397    ///
398    /// this is used for the sweep event, this fn can help to pass the event into popup,
399    /// the widget should implement the `handle_event_with` fn in `impl Widget for $Widget`
400    ///
401    /// ### Example
402    /// ```rust
403    /// impl Widget for Button {
404    /// fn handle_event_with(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope, sweep_area: Area) {
405    ///     let uid = self.widget_uid();
406    ///
407    ///     if self.animator_handle_event(cx, event).must_redraw() {
408    ///         self.draw_button.redraw(cx);
409    ///     }
410    ///     match event.hits_with_options(cx, self.draw_button.area(), HitOptions::new().with_sweep_area(sweep_area) ) {
411    ///         Hit::FingerDown(f_down) => {
412    ///             if self.grab_key_focus {
413    ///                  cx.set_key_focus(self.sweep_area);
414    ///             }
415    ///             cx.widget_action(uid, &scope.path, GButtonEvent::Pressed(f_down.modifiers));
416    ///             self.animator_play(cx, id!(hover.pressed));
417    ///         }
418    ///         _ =>()
419    ///     }
420    /// }
421    /// ```
422    /// ### Details
423    /// See [Flexible Popup](https://palpus-rs.github.io/Gen-UI.github.io/makepad/code/widgets/flexible_popup.html)
424    pub fn handle_event_with(
425        &self,
426        cx: &mut Cx,
427        event: &Event,
428        scope: &mut Scope,
429        sweep_area: Area,
430    ) {
431        if let Some(inner) = self.0.borrow_mut().as_mut() {
432            inner.widget.handle_event_with(cx, event, scope, sweep_area)
433        }
434    }
435    
436    pub fn handle_event(&self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
437        let start = cx.new_actions.len();
438        if let Some(inner) = self.0.borrow_mut().as_mut() {
439            inner.widget.handle_event(cx, event, scope); 
440        }
441        let end = cx.new_actions.len();
442        if start != end{
443            for action in &mut cx.new_actions[start..end]{
444                if let Some(action) = action.downcast_mut::<WidgetAction>() {
445                    action.widgets.push(self.clone());
446                }
447            }
448        }
449    }
450
451    /// Returns the unique ID (UID) of this widget.
452    ///
453    /// Returns `WidgetUid(0)` if the widget is currently borrowed or is empty.
454    pub fn widget_uid(&self) -> WidgetUid {
455        self.0
456            .try_borrow()
457            .ok()
458            .and_then(|r| r.as_ref().map(|w| w.widget.widget_uid()))
459            .unwrap_or(WidgetUid(0))
460    }
461
462    pub fn area(&self) -> Area {
463        if let Some(inner) = self.0.borrow().as_ref() {
464            return inner.widget.area();
465        }
466        Area::Empty
467    }
468
469    pub fn widget_to_data(
470        &self,
471        cx: &mut Cx,
472        actions: &Actions,
473        nodes: &mut LiveNodeVec,
474        path: &[LiveId],
475    ) -> bool {
476        if let Some(inner) = self.0.borrow_mut().as_mut() {
477            return inner.widget.widget_to_data(cx, actions, nodes, path);
478        }
479        false
480    }
481    
482    pub fn set_action_data<T:ActionTrait + PartialEq>(&self, data:T){
483        if let Some(inner) = self.0.borrow_mut().as_mut() {
484            if let Some(v) = inner.widget.action_data(){
485                if let Some(v) = v.downcast_ref::<T>(){
486                    if v.ne(&data){
487                        inner.widget.set_action_data(Arc::new(data));
488                    }
489                }
490            }
491            else{
492                inner.widget.set_action_data(Arc::new(data));
493            }
494        }
495    }
496    
497    pub fn set_action_data_always<T:ActionTrait>(&self, data:T){
498        if let Some(inner) = self.0.borrow_mut().as_mut() {
499            inner.widget.set_action_data(Arc::new(data));
500        }
501    }
502
503    pub fn data_to_widget(&self, cx: &mut Cx, nodes: &[LiveNode], path: &[LiveId]) {
504        if let Some(inner) = self.0.borrow_mut().as_mut() {
505            inner.widget.data_to_widget(cx, nodes, path);
506        }
507    }
508
509    pub fn uid_to_widget(&self, uid: WidgetUid) -> WidgetRef {
510        if self.widget_uid() == uid {
511            return self.clone();
512        }
513        if let Some(inner) = self.0.borrow().as_ref() {
514            return inner.widget.uid_to_widget(uid);
515        }
516        WidgetRef::empty()
517    }
518        
519    pub fn clear_query_cache(&self){
520        if let Some(inner) = self.0.borrow_mut().as_ref() {
521            let mut res = WidgetSet::empty();
522            inner.widget.find_widgets(&[], WidgetCache::Clear, &mut res);
523        }
524    }
525    
526    pub fn find_widgets(&self, path: &[LiveId], cached: WidgetCache, results: &mut WidgetSet) {
527        if let Some(inner) = self.0.borrow().as_ref() {
528            inner.widget.find_widgets(path, cached, results)
529        }
530    }
531
532    pub fn widget(&self, path: &[LiveId]) -> WidgetRef {
533        if let Some(inner) = self.0.borrow_mut().as_mut() {
534            return inner.widget.widget(path);
535        }
536        WidgetRef::empty()
537    }
538    
539    // depricate this one
540    pub fn widgets(&self, paths: &[&[LiveId]]) -> WidgetSet {
541        if let Some(inner) = self.0.borrow_mut().as_mut() {
542            return inner.widget.widgets(paths);
543        }
544        WidgetSet::default()
545    }
546    
547    pub fn widget_set(&self, paths: &[&[LiveId]]) -> WidgetSet {
548        if let Some(inner) = self.0.borrow_mut().as_mut() {
549            return inner.widget.widgets(paths);
550        }
551        WidgetSet::default()
552    }
553    
554    pub fn draw_walk(&self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
555        if let Some(inner) = self.0.borrow_mut().as_mut() {
556            if let Some(nd) = inner.widget.draw_walk(cx, scope, walk).step() {
557                if nd.is_empty() {
558                    return DrawStep::make_step_here(self.clone());
559                }
560                return DrawStep::make_step_here(nd);
561            }
562        }
563        DrawStep::done()
564    }
565
566    pub fn draw_walk_all(&self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) {
567        if let Some(inner) = self.0.borrow_mut().as_mut() {
568            inner.widget.draw_walk_all(cx, scope, walk)
569        }
570    }
571    
572    pub fn draw_3d_all(&self, cx: &mut Cx3d, scope: &mut Scope) {
573        if let Some(inner) = self.0.borrow_mut().as_mut() {
574            inner.widget.draw_3d_all(cx, scope)
575        }
576    }
577    
578    pub fn draw_3d(&mut self, cx: &mut Cx3d, scope: &mut Scope) -> DrawStep {
579        if let Some(inner) = self.0.borrow_mut().as_mut() {
580            if let Some(nd) = inner.widget.draw_3d(cx, scope).step() {
581                if nd.is_empty() {
582                    return DrawStep::make_step_here(self.clone());
583                }
584                return DrawStep::make_step_here(nd);
585            }
586        }
587        DrawStep::done()
588    }
589    
590    pub fn draw(&mut self, cx: &mut Cx2d, scope: &mut Scope) -> DrawStep {
591        if let Some(inner) = self.0.borrow_mut().as_mut() {
592            if let Some(nd) = inner.widget.draw(cx, scope).step() {
593                if nd.is_empty() {
594                    return DrawStep::make_step_here(self.clone());
595                }
596                return DrawStep::make_step_here(nd);
597            }
598        }
599        DrawStep::done()
600    }
601    
602    pub fn draw_unscoped(&mut self, cx: &mut Cx2d) -> DrawStep {
603        if let Some(inner) = self.0.borrow_mut().as_mut() {
604            if let Some(nd) = inner.widget.draw(cx, &mut Scope::empty()).step() {
605                if nd.is_empty() {
606                    return DrawStep::make_step_here(self.clone());
607                }
608                return DrawStep::make_step_here(nd);
609            }
610        }
611        DrawStep::done()
612    }
613
614    pub fn walk(&self, cx: &mut Cx) -> Walk {
615        if let Some(inner) = self.0.borrow_mut().as_mut() {
616            return inner.widget.walk(cx);
617        }
618        Walk::default()
619    }
620
621    // forwarding Widget trait
622    pub fn redraw(&self, cx: &mut Cx) {
623        if let Some(inner) = self.0.borrow_mut().as_mut() {
624            return inner.widget.redraw(cx);
625        }
626    }
627    
628    pub fn set_visible(&self, cx:&mut Cx, visible:bool) {
629        if let Some(inner) = self.0.borrow_mut().as_mut() {
630            return inner.widget.set_visible(cx, visible);
631        }
632    }
633    
634    pub fn visible(&self) -> bool {
635        if let Some(inner) = self.0.borrow().as_ref() {
636            return inner.widget.visible();
637        }
638        true
639    }
640    
641    pub fn text(&self) -> String {
642        if let Some(inner) = self.0.borrow_mut().as_mut() {
643            inner.widget.text()
644        } else {
645            String::new()
646        }
647    }
648    
649    pub fn set_text(&self, cx: &mut Cx, v: &str) {
650        if let Some(inner) = self.0.borrow_mut().as_mut() {
651            inner.widget.set_text(cx, v)
652        }
653    }
654    
655    pub fn key_focus(&self, cx:&Cx) -> bool {
656        if let Some(inner) = self.0.borrow().as_ref() {
657            inner.widget.key_focus(cx)
658        } else {
659            false
660        }
661    }
662        
663    pub fn set_key_focus(&self, cx: &mut Cx) {
664        if let Some(inner) = self.0.borrow_mut().as_mut() {
665            inner.widget.set_key_focus(cx)
666        }
667    }
668    
669    pub fn set_disabled(&self, cx:&mut Cx, disabled:bool) {
670        if let Some(inner) = self.0.borrow_mut().as_mut() {
671            return inner.widget.set_disabled(cx, disabled);
672        }
673    }
674        
675    pub fn disabled(&self, cx:&Cx) -> bool {
676        if let Some(inner) = self.0.borrow().as_ref() {
677            return inner.widget.disabled(cx);
678        }
679        true
680    }
681    
682    pub fn draw_all(&self, cx: &mut Cx2d, scope: &mut Scope) {
683        if let Some(inner) = self.0.borrow_mut().as_mut() {
684            return inner.widget.draw_all(cx, scope);
685        }
686    }
687    
688    pub fn action_data(&self)->Option<Arc<dyn ActionTrait>>{
689        if let Some(inner) = self.0.borrow().as_ref() {
690            return inner.widget.action_data()
691        }
692        None
693    }
694        
695    pub fn filter_actions<'a>(&'a self, actions:&'a Actions)-> impl Iterator<Item = &'a WidgetAction>{
696        actions.filter_widget_actions(self.widget_uid())
697    }
698    
699    pub fn draw_all_unscoped(&self, cx: &mut Cx2d) {
700        if let Some(inner) = self.0.borrow_mut().as_mut() {
701            return inner.widget.draw_all_unscoped(cx);
702        }
703    }
704
705    pub fn borrow_mut<T: 'static + Widget>(&self) -> Option<std::cell::RefMut<'_, T>> {
706        if let Ok(ret) = std::cell::RefMut::filter_map(self.0.borrow_mut(), |inner| {
707            if let Some(inner) = inner.as_mut() {
708                inner.widget.downcast_mut::<T>()
709            } else {
710                None
711            }
712        }) {
713            Some(ret)
714        } else {
715            None
716        }
717    }
718
719    pub fn borrow<T: 'static + Widget>(&self) -> Option<std::cell::Ref<'_, T>> {
720        if let Ok(ret) = std::cell::Ref::filter_map(self.0.borrow(), |inner| {
721            if let Some(inner) = inner.as_ref() {
722                inner.widget.downcast_ref::<T>()
723            } else {
724                None
725            }
726        }) {
727            Some(ret)
728        } else {
729            None
730        }
731    }
732
733    pub fn apply_over(&self, cx: &mut Cx, nodes: &[LiveNode]) {
734        self.apply(cx, &mut ApplyFrom::Over.into(), 0, nodes);
735    }
736    
737    fn store_designer_backref(&self, cx:&mut Cx, apply:&mut Apply, index:usize){
738        if let Some(scope) = &mut apply.scope{
739            if let Some(file_id) = apply.from.file_id(){
740                if let Some(dd) = scope.data.get_mut::<DesignerDataToWidget>(){
741                    let ptr = cx.live_registry.borrow().file_id_index_to_live_ptr(file_id, index);
742                    dd.live_ptr_to_widget.insert(ptr, self.clone());
743                }
744            }                        
745        }
746    }
747    fn apply(&self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
748        let mut inner = self.0.borrow_mut();
749        if let LiveValue::Class { live_type, .. } = nodes[index].value {
750            if let Some(component) = &mut *inner {
751                if component.widget.ref_cast_type_id() != live_type {
752                    *inner = None; // type changed, drop old component
753                    log!("TYPECHANGE {:?}", nodes[index]);
754                } else {
755                    self.store_designer_backref(cx, apply, index);
756                    let idx = component.widget.apply(cx, apply, index, nodes);
757                    component.widget.redraw(cx);
758                    return idx;
759                }
760            }
761            if let Some(component) = cx
762                .live_registry
763                .clone()
764                .borrow()
765                .components
766                .get::<WidgetRegistry>()
767                .new(cx, live_type)
768            {
769                if cx.debug.marker() == 1 {
770                    panic!()
771                }
772                *inner = Some(WidgetRefInner { widget: component });
773                self.store_designer_backref(cx, apply, index);
774                if let Some(component) = &mut *inner {
775                    let idx = component.widget.apply(cx, apply, index, nodes);
776                    component.widget.redraw(cx);
777                    return idx;
778                }
779            } else {
780                cx.apply_error_cant_find_target(
781                    live_error_origin!(),
782                    index,
783                    nodes,
784                    nodes[index].id,
785                );
786            }
787        } else if let Some(component) = &mut *inner {
788            self.store_designer_backref(cx, apply, index);
789            let idx = component.widget.apply(cx, apply, index, nodes);
790            component.widget.redraw(cx);
791            return idx;
792        }
793        cx.apply_error_cant_find_target(live_error_origin!(), index, nodes, nodes[index].id);
794        
795        nodes.skip_node(index)
796    }
797    
798}
799
800impl LiveHook for WidgetRef {}
801impl LiveApply for WidgetRef {
802    fn apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
803        <WidgetRef>::apply(self, cx, apply, index, nodes)
804    }
805}
806
807impl LiveNew for WidgetRef {
808    fn new(_cx: &mut Cx) -> Self {
809        Self(Rc::new(RefCell::new(None)))
810    }
811
812    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
813        LiveTypeInfo {
814            module_id: LiveModuleId::from_str(&module_path!()).unwrap(),
815            live_type: LiveType::of::<dyn Widget>(),
816            fields: Vec::new(),
817            live_ignore: true,
818            type_name: LiveId(0),
819        }
820    }
821}
822
823pub trait WidgetActionTrait: 'static + Send+ Sync {
824    fn ref_cast_type_id(&self) -> TypeId;
825    fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
826    fn box_clone(&self) -> Box<dyn WidgetActionTrait>;
827}
828
829pub trait ActionDefault{
830    fn default_ref(&self) -> Box<dyn WidgetActionTrait>;
831}
832
833impl<T: 'static + ?Sized + Clone + Debug + Send+ Sync> WidgetActionTrait for T {
834    fn ref_cast_type_id(&self) -> TypeId {
835        TypeId::of::<T>()
836    }
837
838    fn box_clone(&self) -> Box<dyn WidgetActionTrait> {
839        Box::new((*self).clone())
840    }
841    fn debug_fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
842        self.fmt(f)
843    }
844}
845
846impl Debug for dyn WidgetActionTrait {
847    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
848        self.debug_fmt(f)
849    }
850}
851
852generate_any_trait_api!(WidgetActionTrait);
853
854impl Clone for Box<dyn WidgetActionTrait> {
855    fn clone(&self) -> Box<dyn WidgetActionTrait> {
856        self.as_ref().box_clone()
857    }
858}
859
860
861#[derive(Default)]
862pub struct WidgetActionData{
863    data: Option<Arc<dyn ActionTrait>>
864}
865
866impl WidgetActionData{
867    pub fn set(&mut self,  data:impl ActionTrait){
868        self.data = Some(Arc::new(data));
869    }
870    
871    pub fn set_box(&mut self,  data:Arc<dyn ActionTrait>){
872        self.data = Some(data);
873    }
874    
875    pub fn clone_data(&self)->Option<Arc<dyn ActionTrait>>{
876        self.data.clone()
877    }
878}
879
880/// An action emitted by another widget via the `widget_action()` method.
881#[derive(Clone, Debug)]
882pub struct WidgetAction {
883    /// Extra data that can be stored on a widget at draw time,
884    /// and then cheaply cloned to be emitted as part of an action.
885    ///
886    /// To attach data to a widget action, use the `widget_action_with_data()` method.
887    pub data: Option< Arc<dyn ActionTrait>>,
888    /// The emitted action object itself, which acts as a dyn Any-like.
889    pub action: Box<dyn WidgetActionTrait>,
890    /// The complete list of widgets this action bubbles up from.
891    /// You can use this to explore the UI tree of the widget that emitted the action.
892    pub widgets: SmallVec<[WidgetRef;4]>,
893    /// The UID of the widget that emitted this action.
894    pub widget_uid: WidgetUid,
895    /// The path-list of the widgets this action bubbles up from (if any).
896    pub path: HeapLiveIdPath,
897    /// Used by list-like widgets (e.g., PortalList) to mark a group-uid around item-actions.
898    pub group: Option<WidgetActionGroup>,
899}
900
901#[derive(Clone, Debug)]
902pub struct WidgetActionGroup {
903    pub group_uid: WidgetUid,
904    pub item_uid: WidgetUid,
905}
906
907pub trait WidgetActionCxExt {
908    fn widget_action(&mut self, uid: WidgetUid, path: &HeapLiveIdPath, t: impl WidgetActionTrait);
909    fn widget_action_with_data(
910        &mut self,
911        action_data: &WidgetActionData,
912        widget_uid: WidgetUid,
913        path: &HeapLiveIdPath,
914        t: impl WidgetActionTrait,
915    );
916    fn group_widget_actions<F, R>(&mut self, group_id: WidgetUid, item_id: WidgetUid, f: F) -> R
917    where
918        F: FnOnce(&mut Cx) -> R;
919}
920
921
922pub trait WidgetActionsApi {
923    
924    fn widget(&self, path:&[LiveId])->WidgetRef;
925    
926    fn widget_action(&self, path:&[LiveId])->Option<&WidgetAction>;
927        
928    fn find_widget_action_cast<T: WidgetActionTrait>(
929        &self,
930        widget_uid: WidgetUid,
931    ) -> T
932    where
933        T: Default + Clone;
934    fn find_widget_action(&self, widget_uid: WidgetUid) -> Option<&WidgetAction>;
935    /// ## Filter all actions by widget uid
936    /// this function use to filter all actions from `Event::Actions(actions)`,
937    /// if multi actions in same widget may happened in the same time, this function will help you get all
938    /// and back an Iter
939    /// ### Attention
940    /// **If you want to focus on target actions and need to cast directly use `filter_widget_action_cast`**
941    /// ### Examples
942    /// #### find and directly do target action without param
943    /// you can `filter_widget_actions` and then do find to get target action you want,
944    /// then do map to do want you what
945    /// ```rust
946    /// let actions = cx.capture_actions(|cx| self.super_widget.handle_event(cx, event, scope));
947    ///
948    /// self.gbutton(id!(auto_connect)).borrow().map(|x| {
949    ///     let mut actions = actions.filter_widget_actions(x.widget_uid());
950    ///     actions.find(|action| {
951    ///         if let GButtonEvent::Clicked(_) = action.cast(){
952    ///             true
953    ///         }else{
954    ///             false
955    ///         }
956    ///     }).map(|action|{
957    ///         dbg!(action);
958    ///     });
959    /// });
960    /// ```
961    /// #### find and cast
962    /// ```rust
963    /// let actions = cx.capture_actions(|cx| self.super_widget.handle_event(cx, event, scope));
964    ///
965    /// self.gbutton(id!(auto_connect)).borrow().map(|x| {
966    /// let actions = actions.filter_widget_actions(x.widget_uid());
967    ///     actions.for_each(|action| {
968    ///         if let GButtonEvent::Clicked(param) = action.cast(){
969    ///             dbg!(param);
970    ///         }
971    ///     })
972    /// });
973    /// ```
974    fn filter_widget_actions(&self, widget_uid: WidgetUid) -> impl Iterator<Item = &WidgetAction>;
975    /// ## Filter widget actions by widget id and cast
976    /// this function can help you cast the widget actions to the widget you want, the diff is:
977    /// - try cast all widget actions (This method is not recommended when a large number of actions occur simultaneously)
978    /// - back `Iterator<Item = T>` not `Iterator<Item = &T>`
979    /// ### Example
980    /// ```rust
981    /// self.gbutton(id!(auto_connect)).borrow().map(|x| {
982    /// let actions = actions.filter_widget_actions_cast::<GButtonEvent>(x.widget_uid());
983    ///     actions.for_each(|action| {
984    ///         if let GButtonEvent::Clicked(param) = action{
985    ///             dbg!(param);
986    ///         }
987    ///     })
988    /// });
989    /// ```
990    fn filter_widget_actions_cast<T: WidgetActionTrait>(
991        &self,
992        widget_uid: WidgetUid,
993    ) -> impl Iterator<Item = T>
994    where
995        T: Default + Clone;
996        
997    fn filter_actions_data<T: ActionTrait>(
998            &self,
999        ) -> impl Iterator<Item = &T>
1000        where
1001        T: Clone;
1002        
1003    fn filter_widget_actions_set(&self, set: &WidgetSet) -> impl Iterator<Item = &WidgetAction>;
1004}
1005
1006pub trait WidgetActionOptionApi {
1007    fn widget_uid_eq(&self, widget_uid: WidgetUid) -> Option<&WidgetAction>;
1008    fn cast<T: WidgetActionTrait>(&self) -> T
1009    where
1010        T: Default + Clone;
1011    fn cast_ref<T: WidgetActionTrait+ ActionDefaultRef>(&self) -> &T;
1012}
1013
1014impl WidgetActionOptionApi for Option<&WidgetAction> {
1015    fn widget_uid_eq(&self, widget_uid: WidgetUid) -> Option<&WidgetAction> {
1016        if let Some(item) = self {
1017            if item.widget_uid == widget_uid {
1018                return Some(item);
1019            }
1020        }
1021        None
1022    }
1023
1024    fn cast<T: WidgetActionTrait>(&self) -> T
1025    where
1026        T: Default + Clone,
1027    {
1028        if let Some(item) = self {
1029            if let Some(item) = item.action.downcast_ref::<T>() {
1030                return item.clone();
1031            }
1032        }
1033        T::default()
1034    }
1035    
1036    fn cast_ref<T: WidgetActionTrait+ ActionDefaultRef>(&self) -> &T
1037    {
1038        if let Some(item) = self {
1039            if let Some(item) = item.action.downcast_ref::<T>() {
1040                return item;
1041            }
1042        }
1043        T::default_ref()
1044    }
1045}
1046
1047pub trait WidgetActionCast {
1048    fn as_widget_action(&self) -> Option<&WidgetAction>;
1049}
1050
1051impl WidgetActionCast for Action {
1052    fn as_widget_action(&self) -> Option<&WidgetAction> {
1053        self.downcast_ref::<WidgetAction>()
1054    }
1055}
1056
1057impl WidgetActionsApi for Actions {
1058    fn widget_action(&self, path:&[LiveId])->Option<&WidgetAction>{
1059        for action in self {
1060            if let Some(action) = action.downcast_ref::<WidgetAction>() {
1061                let mut ap = action.path.data.iter().rev();
1062                if path.iter().rev().all(|p| ap.find(|&ap| p == ap).is_some()){
1063                    return Some(action)
1064                }
1065            }
1066        }
1067        None
1068    }
1069    
1070    fn widget(&self, path:&[LiveId])->WidgetRef{
1071        self.iter().find_map(|action| {
1072            action.downcast_ref::<WidgetAction>().and_then(|action| {
1073                let mut ret = None;
1074                let mut ap = action.path.data.iter().rev();
1075                path.iter().enumerate().rev().all(|(i, p)| {
1076                    let found = ap.find(|&ap| p == ap).is_some(); 
1077                    if found && ret.is_none() {
1078                        ret = action.widgets.get(i);
1079                    }
1080                    found
1081                }).then_some(ret).flatten()
1082            })
1083        }).map_or_else(|| WidgetRef::empty(), |ret| ret.clone())
1084    }
1085    
1086    fn find_widget_action(&self, widget_uid: WidgetUid) -> Option<&WidgetAction> {
1087        for action in self {
1088            if let Some(action) = action.downcast_ref::<WidgetAction>() {
1089                if action.widget_uid == widget_uid {
1090                    return Some(action);
1091                }
1092            }
1093        }
1094        None
1095    }
1096    
1097    fn find_widget_action_cast<T: WidgetActionTrait + 'static + Send>(
1098        &self,
1099        widget_uid: WidgetUid,
1100    ) -> T
1101    where
1102        T: Default + Clone,
1103    {
1104        if let Some(item) = self.find_widget_action(widget_uid) {
1105            if let Some(item) = item.action.downcast_ref::<T>() {
1106                return item.clone();
1107            }
1108        }
1109        T::default()
1110    }
1111
1112    fn filter_widget_actions(&self, widget_uid: WidgetUid) -> impl Iterator<Item = &WidgetAction> {
1113        self.iter().filter_map(move |action| {
1114            action
1115                .downcast_ref::<WidgetAction>()
1116                .and_then(|action| (action.widget_uid == widget_uid).then_some(action))
1117        })
1118    }
1119    
1120
1121    fn filter_widget_actions_cast<T: WidgetActionTrait >(
1122        &self,
1123        widget_uid: WidgetUid,
1124    ) -> impl Iterator<Item = T>
1125    where
1126        T: Default + Clone,
1127    {
1128        self.filter_widget_actions(widget_uid).map(|action| {
1129            if let Some(a) = action.action.downcast_ref::<T>() {
1130                a.clone()
1131            }else {
1132                T::default()
1133            }
1134        })
1135    }
1136    
1137    fn filter_actions_data<T: ActionTrait>(
1138        &self,
1139    ) -> impl Iterator<Item = &T>
1140    {
1141        self.iter().filter_map(move |action| {
1142            action
1143            .downcast_ref::<WidgetAction>()
1144            .and_then(|action|{
1145                if let Some(a) = &action.data{
1146                    if let Some(a) = a.downcast_ref::<T>() {
1147                        Some(a)
1148                    }else {
1149                        None
1150                    }
1151                }else {
1152                    None
1153                }
1154            })
1155        })
1156    }
1157        
1158    fn filter_widget_actions_set(&self, set:&WidgetSet) -> impl Iterator<Item = &WidgetAction> {
1159        self.iter().filter_map(move |action| {
1160            action
1161            .downcast_ref::<WidgetAction>()
1162            .and_then(|action| (
1163                set.iter().any(|w| action.widget_uid == w.widget_uid())
1164            ).then_some(action))
1165        })
1166    }
1167}
1168
1169impl WidgetActionCxExt for Cx {
1170    fn widget_action(
1171        &mut self,
1172        widget_uid: WidgetUid,
1173        path: &HeapLiveIdPath,
1174        t: impl WidgetActionTrait,
1175    ) {
1176        self.action(WidgetAction {
1177            widget_uid,
1178            data: None,
1179            path: path.clone(),
1180            widgets: Default::default(),
1181            action: Box::new(t),
1182            group: None,
1183        })
1184    }
1185    
1186    fn widget_action_with_data(
1187        &mut self,
1188        action_data: &WidgetActionData,
1189        widget_uid: WidgetUid,
1190        path: &HeapLiveIdPath,
1191        t: impl WidgetActionTrait,
1192    ) {
1193        self.action(WidgetAction {
1194            widget_uid,
1195            data: action_data.clone_data(),
1196            path: path.clone(),
1197            widgets: Default::default(),
1198            action: Box::new(t),
1199            group: None,
1200        })
1201    }
1202
1203    fn group_widget_actions<F, R>(&mut self, group_uid: WidgetUid, item_uid: WidgetUid, f: F) -> R
1204    where
1205        F: FnOnce(&mut Cx) -> R,
1206    {
1207        self.mutate_actions(
1208            |cx| f(cx),
1209            |actions| {
1210                for action in actions {
1211                    if let Some(action) = action.downcast_mut::<WidgetAction>() {
1212                        if action.group.is_none() {
1213                            action.group = Some(WidgetActionGroup {
1214                                group_uid,
1215                                item_uid,
1216                            })
1217                        }
1218                    }
1219                }
1220            },
1221        )
1222    }
1223    
1224}
1225
1226impl WidgetAction {
1227    pub fn widget(&self)->&WidgetRef{
1228        self.widgets.first().unwrap()
1229    }
1230    
1231    pub fn widget_nth(&self, n:usize)->&WidgetRef{
1232        self.widgets.iter().nth(n).unwrap()
1233    }
1234    
1235    pub fn cast<T: WidgetActionTrait + 'static + Send>(&self) -> T
1236    where
1237        T: Default + Clone,
1238    {
1239        if let Some(item) = self.action.downcast_ref::<T>() {
1240            return item.clone();
1241        }
1242        T::default()
1243    }
1244    
1245    pub fn cast_ref<T: WidgetActionTrait + 'static + Send + ActionDefaultRef>(&self) -> &T
1246    {
1247        if let Some(item) = self.action.downcast_ref::<T>() {
1248            return item
1249        }
1250        T::default_ref()
1251    }
1252    
1253    pub fn downcast_ref<T: WidgetActionTrait + Send + ActionDefaultRef>(&self) -> Option<&T>
1254    {
1255        self.action.downcast_ref::<T>()
1256    }
1257}
1258
1259pub struct DrawStateWrap<T: Clone> {
1260    state: Option<T>,
1261    redraw_id: u64,
1262}
1263
1264impl<T: Clone> Default for DrawStateWrap<T> {
1265    fn default() -> Self {
1266        Self {
1267            state: None,
1268            redraw_id: 0,
1269        }
1270    }
1271}
1272
1273impl<T: Clone> DrawStateWrap<T> {
1274    pub fn begin(&mut self, cx: &mut CxDraw, init: T) -> bool {
1275        if self.redraw_id != cx.redraw_id() {
1276            self.redraw_id = cx.redraw_id();
1277            self.state = Some(init);
1278            true
1279        } else {
1280            false
1281        }
1282    }
1283
1284    pub fn begin_with<F, S>(&mut self, cx: &mut CxDraw, v: &S, init: F) -> bool
1285    where
1286        F: FnOnce(&mut CxDraw, &S) -> T,
1287    {
1288        if self.redraw_id != cx.redraw_id() {
1289            self.redraw_id = cx.redraw_id();
1290            self.state = Some(init(cx, v));
1291            true
1292        } else {
1293            false
1294        }
1295    }
1296
1297    pub fn begin_state(&mut self, cx: &mut Cx) -> Option<&mut Option<T>>
1298    {
1299        if self.redraw_id != cx.redraw_id() {
1300            self.redraw_id = cx.redraw_id();
1301            Some(&mut self.state)
1302        } else {
1303            None
1304        }
1305    }
1306
1307    pub fn get(&self) -> Option<T> {
1308        self.state.clone()
1309    }
1310
1311    pub fn as_ref(&self) -> Option<&T> {
1312        self.state.as_ref()
1313    }
1314
1315    pub fn as_mut(&mut self) -> Option<&mut T> {
1316        self.state.as_mut()
1317    }
1318
1319    pub fn set(&mut self, value: T) {
1320        self.state = Some(value);
1321    }
1322
1323    pub fn end(&mut self) {
1324        self.state = None;
1325    }
1326}
1327
1328#[macro_export]
1329macro_rules! register_widget {
1330    ( $ cx: ident, $ ty: ty) => {{
1331        struct Factory();
1332        impl WidgetFactory for Factory {
1333            fn new(&self, cx: &mut Cx) -> Box<dyn Widget> {
1334                Box::new(<$ty>::new(cx))
1335            }
1336        }
1337        register_component_factory!($cx, WidgetRegistry, $ty, Factory);
1338    }};
1339}