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; 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 {
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 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 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 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 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 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 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; 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#[derive(Clone, Debug)]
882pub struct WidgetAction {
883 pub data: Option< Arc<dyn ActionTrait>>,
888 pub action: Box<dyn WidgetActionTrait>,
890 pub widgets: SmallVec<[WidgetRef;4]>,
893 pub widget_uid: WidgetUid,
895 pub path: HeapLiveIdPath,
897 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 fn filter_widget_actions(&self, widget_uid: WidgetUid) -> impl Iterator<Item = &WidgetAction>;
975 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}