1use {
2 crate::makepad_draw::*,
3 std::fmt::{Formatter, Debug, Error},
4 std::collections::BTreeMap,
5 std::any::TypeId,
6 std::cell::RefCell,
7 std::rc::Rc
8};
9pub use crate::register_widget;
10
11#[derive(Clone, Copy)]
12pub enum WidgetCache {
13 Yes,
14 No,
15 Clear
16}
17
18#[derive(Clone, Debug, Copy, PartialEq)]
19pub struct WidgetUid(pub u64);
20
21pub trait WidgetDesign {
22}
23
24pub trait Widget: LiveApply {
25 fn handle_widget_event_with(
26 &mut self,
27 _cx: &mut Cx,
28 _event: &Event,
29 _fn_action: &mut dyn FnMut(&mut Cx, WidgetActionItem)
30 ) {}
31
32 fn handle_widget_event(&mut self, cx: &mut Cx, event: &Event) -> WidgetActions {
33 let mut actions = Vec::new();
34 self.handle_widget_event_with(cx, event, &mut | _, action | {
35 actions.push(action);
36 });
37 actions
38 }
39
40 fn find_widgets(&mut self, _path: &[LiveId], _cached: WidgetCache, _results: &mut WidgetSet) {
41 }
42
43 fn widget(&mut self, path: &[LiveId]) -> WidgetRef {
44 let mut results = WidgetSet::default();
45 self.find_widgets(path, WidgetCache::Yes, &mut results);
46 return results.into_first()
47 }
48
49 fn widgets(&mut self, paths: &[&[LiveId]]) -> WidgetSet {
50 let mut results = WidgetSet::default();
51 for path in paths {
52 self.find_widgets(path, WidgetCache::Yes, &mut results);
53 }
54 results
55 }
56
57 fn widget_uid(&self) -> WidgetUid {return WidgetUid(self as *const _ as *const () as u64)}
59
60 fn widget_to_data(&self, _cx: &mut Cx, _actions: &WidgetActions, _nodes: &mut LiveNodeVec, _path: &[LiveId]) -> bool {false}
61 fn data_to_widget(&mut self, _cx: &mut Cx, _nodes: &[LiveNode], _path: &[LiveId]) {}
62
63 fn draw_walk_widget(&mut self, cx: &mut Cx2d, walk: Walk) -> WidgetDraw;
64 fn walk(&mut self, _cx:&mut Cx) -> Walk {Walk::default()}
65 fn redraw(&mut self, _cx: &mut Cx);
66
67 fn is_visible(&self) -> bool {
68 true
69 }
70
71 fn draw_widget(&mut self, cx: &mut Cx2d) -> WidgetDraw {
72 let walk = self.walk(cx);
73 self.draw_walk_widget(cx, walk)
74 }
75
76 fn draw_widget_all(&mut self, cx: &mut Cx2d) {
77 while self.draw_widget(cx).is_hook() {};
78 }
79
80 fn text(&self) -> String {
81 String::new()
82 }
83
84 fn set_text(&mut self, _v: &str) {
85 }
86
87 fn set_text_and_redraw(&mut self, cx: &mut Cx, v: &str) {
88 self.set_text(v);
89 self.redraw(cx);
90 }
91 fn type_id(&self) -> LiveType where Self: 'static {LiveType::of::<Self>()}
108}
109
110#[derive(Clone, Copy)]
111pub enum CreateAt {
112 Template,
113 Begin,
114 After(LiveId),
115 Before(LiveId),
116 End
117}
118
119pub trait WidgetDrawApi {
120 fn done() -> WidgetDraw {Result::Ok(())}
121 fn hook(arg: WidgetRef) -> WidgetDraw {Result::Err(arg)}
122 fn hook_above() -> WidgetDraw {Result::Err(WidgetRef::empty())}
123 fn is_done(&self) -> bool;
124 fn is_hook(&self) -> bool;
125 fn hook_widget(self) -> Option<WidgetRef>;
126}
127
128impl WidgetDrawApi for WidgetDraw {
129 fn is_done(&self) -> bool {
130 match *self {
131 Result::Ok(_) => true,
132 Result::Err(_) => false
133 }
134 }
135 fn is_hook(&self) -> bool {
136 match *self {
137 Result::Ok(_) => false,
138 Result::Err(_) => true
139 }
140 }
141 fn hook_widget(self) -> Option<WidgetRef> {
142 match self {
143 Result::Ok(_) => None,
144 Result::Err(nd) => Some(nd)
145 }
146 }
147}
148
149pub type WidgetDraw = Result<(), WidgetRef>;
167
168generate_ref_cast_api!(Widget);
169
170pub trait WidgetFactory {
171 fn new(&self, cx: &mut Cx) -> Box<dyn Widget>;
172}
173
174#[derive(Default, LiveComponentRegistry)]
175pub struct WidgetRegistry {
176 pub map: BTreeMap<LiveType, (LiveComponentInfo, Box<dyn WidgetFactory>)>
177}
178
179pub trait WidgetAction: 'static {
180 fn type_id(&self) -> TypeId;
181 fn box_clone(&self) -> Box<dyn WidgetAction>;
182}
183
184impl<T: 'static + ? Sized + Clone> WidgetAction for T {
185 fn type_id(&self) -> TypeId {
186 TypeId::of::<T>()
187 }
188
189 fn box_clone(&self) -> Box<dyn WidgetAction> {
190 Box::new((*self).clone())
191 }
192}
193
194generate_clone_cast_api!(WidgetAction);
195
196impl Clone for Box<dyn WidgetAction> {
197 fn clone(&self) -> Box<dyn WidgetAction> {
198 self.as_ref().box_clone()
199 }
200}
201
202#[derive(Clone, Default)]
203pub struct WidgetRef(Rc<RefCell<Option<Box<dyn Widget >> >>);
204
205impl Debug for WidgetRef {
206 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
207 write!(f, "WidgetRef {}", self.widget_uid().0)
208 }
209}
210
211#[derive(Clone)]
212pub enum WidgetSet {
213 Inline {
214 set: [Option<WidgetRef>; 4],
215 len: usize
216 },
217 Vec(Vec<WidgetRef>),
218 Empty
219}
220
221impl std::fmt::Debug for WidgetSet {
222 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
223 match self {
224 Self::Inline {len, ..} => {
225 let _ = write!(f, "WidgetSet::Inline: {}", len);
226 },
227 Self::Vec(vec) => {
228 let _ = write!(f, "WidgetSet::Vec: {}", vec.len());
229 },
230 Self::Empty => {
231 let _ = write!(f, "WidgetSet::Empty");
232 }
233 }
234 Ok(())
235 }
236}
237
238impl Default for WidgetSet {
239 fn default() -> Self {Self::Empty}
240}
241
242impl WidgetSet {
243 pub fn is_empty(&mut self) -> bool {
244 if let Self::Empty = self {
245 true
246 }
247 else {
248 false
249 }
250 }
251 pub fn push(&mut self, item: WidgetRef) {
252 match self {
253 Self::Empty => {
254 *self = Self::Inline {
255 set: [Some(item), None, None, None],
256 len: 1
257 }
258 }
259 Self::Inline {len, set} => {
260 if *len == set.len() {
261 let mut vec = Vec::new();
262 for item in set {
263 vec.push(item.clone().unwrap());
264 }
265 vec.push(item);
266 *self = Self::Vec(vec);
267 }
268 else {
269 set[*len] = Some(item);
270 *len += 1;
271 }
272 }
273 Self::Vec(vec) => {
274 vec.push(item);
275 }
276 }
277 }
278
279 pub fn extend_from_set(&mut self, other: &WidgetSet) {
280 for item in other.iter() {
281 self.push(item);
282 }
283 }
284
285 pub fn into_first(self) -> WidgetRef {
286 match self {
287 Self::Empty => {
288 WidgetRef::empty()
289 }
290 Self::Inline {len: _, mut set} => {
291 set[0].take().unwrap()
292 }
293 Self::Vec(mut vec) => {
294 vec.remove(0)
295 }
296 }
297 }
298
299 pub fn widgets(&self, paths: &[&[LiveId]]) -> WidgetSet {
300 let mut results = WidgetSet::default();
301 for widget in self.iter() {
302 if let Some(inner) = widget.0.borrow_mut().as_mut() {
303 for path in paths {
304 inner.find_widgets(path, WidgetCache::Yes, &mut results);
305 }
306 }
307 }
308 results
309 }
310
311 pub fn contains(&self, widget: &WidgetRef) -> bool {
312 for item in self.iter() {
313 if item == *widget {
314 return true
315 }
316 }
317 false
318 }
319}
320
321impl LiveHook for WidgetSet {}
322impl LiveApply for WidgetSet {
323 fn apply(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
324 for inner in self.iter() {
325 let mut inner = inner.0.borrow_mut();
326 if let Some(component) = &mut *inner {
327 return component.apply(cx, from, index, nodes)
328 }
329 }
330 nodes.skip_node(index)
331 }
332}
333
334impl WidgetSet {
335 pub fn empty() -> Self {Self::Empty}
336 pub fn iter(&self) -> WidgetSetIterator {
337 WidgetSetIterator {
338 widget_set: self,
339 index: 0
340 }
341 }
342
343 pub fn set_text(&self, v: &str) {
344 for item in self.iter(){
345 item.set_text(v)
346 }
347 }
348
349 pub fn set_text_and_redraw(&self, cx: &mut Cx, v: &str) {
350 for item in self.iter(){
351 item.set_text_and_redraw(cx, v)
352 }
353 }
354}
355
356pub struct WidgetSetIterator<'a> {
357 widget_set: &'a WidgetSet,
358 index: usize
359}
360
361impl<'a> Iterator for WidgetSetIterator<'a> {
362 type Item = WidgetRef;
364 fn next(&mut self) -> Option<Self::Item> {
365 match self.widget_set {
366 WidgetSet::Empty => {
367 return None;
368 }
369 WidgetSet::Inline {set, len} => {
370 if self.index >= *len {
371 return None
372 }
373 let ret = set[self.index].as_ref().unwrap();
374 self.index += 1;
375 return Some(ret.clone())
376 }
377 WidgetSet::Vec(vec) => {
378 if self.index >= vec.len() {
379 return None
380 }
381 let ret = &vec[self.index];
382 self.index += 1;
383 return Some(ret.clone())
384 }
385 }
386 }
387}
388
389impl PartialEq for WidgetRef {
390 fn eq(&self, other: &WidgetRef) -> bool {
391 Rc::ptr_eq(&self.0, &other.0)
392 }
393
394 fn ne(&self, other: &WidgetRef) -> bool {
395 !Rc::ptr_eq(&self.0, &other.0)
396 }
397}
398
399impl WidgetRef {
400 pub fn empty() -> Self {Self (Rc::new(RefCell::new(None)))}
401
402 pub fn is_empty(&self) -> bool {
403 self.0.borrow().as_ref().is_none()
404 }
405 pub fn new_with_inner(widget: Box<dyn Widget>) -> Self {
406 Self (Rc::new(RefCell::new(Some(widget))))
407 }
408
409 pub fn handle_widget_event_with(&self, cx: &mut Cx, event: &Event, dispatch_action: &mut dyn FnMut(&mut Cx, WidgetActionItem)) {
410 if let Some(inner) = self.0.borrow_mut().as_mut() {
411 return inner.handle_widget_event_with(cx, event, dispatch_action)
412 }
413 }
414
415 pub fn handle_widget_event(&self, cx: &mut Cx, event: &Event) -> Vec<WidgetActionItem> {
416 if let Some(inner) = self.0.borrow_mut().as_mut() {
417 return inner.handle_widget_event(cx, event)
418 }
419 Vec::new()
420 }
421
422 pub fn widget_uid(&self) -> WidgetUid {
423 if let Some(inner) = self.0.borrow().as_ref() {
424 return inner.widget_uid()
425 }
426 WidgetUid(0)
427 }
428
429 pub fn widget_to_data(&self, cx: &mut Cx, actions: &WidgetActions, nodes: &mut LiveNodeVec, path: &[LiveId]) -> bool {
430 if let Some(inner) = self.0.borrow_mut().as_mut() {
431 return inner.widget_to_data(cx, actions, nodes, path);
432 }
433 false
434 }
435
436 pub fn data_to_widget(&self, cx: &mut Cx, nodes: &[LiveNode], path: &[LiveId]) {
437 if let Some(inner) = self.0.borrow_mut().as_mut() {
438 inner.data_to_widget(cx, nodes, path);
439 }
440 }
441
442 pub fn find_widgets(
443 &mut self,
444 path: &[LiveId],
445 cached: WidgetCache,
446 results: &mut WidgetSet
447 ) {
448 if let Some(inner) = self.0.borrow_mut().as_mut() {
449 inner.find_widgets(path, cached, results)
450 }
451 }
452
453 pub fn widget(&self, path: &[LiveId]) -> WidgetRef {
454 if let Some(inner) = self.0.borrow_mut().as_mut() {
455 return inner.widget(path);
456 }
457 WidgetRef::empty()
458 }
459
460 pub fn widgets(&self, paths: &[&[LiveId]]) -> WidgetSet {
461 if let Some(inner) = self.0.borrow_mut().as_mut() {
462 return inner.widgets(paths);
463 }
464 WidgetSet::default()
465 }
466
467 pub fn draw_walk_widget(&self, cx: &mut Cx2d, walk: Walk) -> WidgetDraw {
468 if let Some(inner) = self.0.borrow_mut().as_mut() {
469 if let Some(nd) = inner.draw_walk_widget(cx, walk).hook_widget() {
470 if nd.is_empty() {
471 return WidgetDraw::hook(self.clone())
472 }
473 return WidgetDraw::hook(nd);
474 }
475 }
476 WidgetDraw::done()
477 }
478
479 pub fn walk(&self, cx:&mut Cx) -> Walk {
480 if let Some(inner) = self.0.borrow_mut().as_mut() {
481 return inner.walk(cx)
482 }
483 Walk::default()
484 }
485
486 pub fn redraw(&self, cx: &mut Cx) {
488 if let Some(inner) = self.0.borrow_mut().as_mut() {
489 return inner.redraw(cx)
490 }
491 }
492
493
494 pub fn is_visible(&self) -> bool {
495 if let Some(inner) = self.0.borrow().as_ref() {
496 return inner.is_visible()
497 }
498 true
499 }
500
501 pub fn draw_widget_all(&self, cx: &mut Cx2d) {
502 if let Some(inner) = self.0.borrow_mut().as_mut() {
503 return inner.draw_widget_all(cx)
504 }
505 }
506
507 pub fn draw_widget(&self, cx: &mut Cx2d) -> WidgetDraw {
508 if let Some(inner) = self.0.borrow_mut().as_mut() {
509 if let Some(nd) = inner.draw_widget(cx).hook_widget() {
510 if nd.is_empty() {
511 return WidgetDraw::hook(self.clone())
512 }
513 return WidgetDraw::hook(nd);
514 }
515 }
516 WidgetDraw::done()
517 }
518
519 pub fn text(&self) -> String {
520 if let Some(inner) = self.0.borrow_mut().as_mut() {
521 inner.text()
522 }
523 else {
524 String::new()
525 }
526 }
527
528 pub fn set_text(&self, v: &str) {
529 if let Some(inner) = self.0.borrow_mut().as_mut() {
530 inner.set_text(v)
531 }
532 }
533
534 pub fn set_text_and_redraw(&self, cx: &mut Cx, v: &str) {
535 if let Some(inner) = self.0.borrow_mut().as_mut() {
536 inner.set_text_and_redraw(cx, v);
537 }
538 }
539
540 pub fn borrow_mut<T: 'static + Widget>(&self) -> Option<std::cell::RefMut<'_, T >> {
541 if let Ok(ret) = std::cell::RefMut::filter_map(self.0.borrow_mut(), | inner | {
542 if let Some(inner) = inner.as_mut() {
543 inner.cast_mut::<T>()
544 }
545 else {
546 None
547 }
548 }) {
549 Some(ret)
550 }
551 else {
552 None
553 }
554 }
555
556 pub fn borrow<T: 'static + Widget>(&self) -> Option<std::cell::Ref<'_, T >> {
557 if let Ok(ret) = std::cell::Ref::filter_map(self.0.borrow(), | inner | {
558 if let Some(inner) = inner.as_ref() {
559 inner.cast::<T>()
560 }
561 else {
562 None
563 }
564 }) {
565 Some(ret)
566 }
567 else {
568 None
569 }
570 }
571
572 pub fn apply_over(&self, cx: &mut Cx, nodes: &[LiveNode]) {
573 self.apply(cx, ApplyFrom::ApplyOver, 0, nodes);
574 }
575
576 pub fn apply_over_and_redraw(&self, cx: &mut Cx, nodes: &[LiveNode]) {
577 self.apply(cx, ApplyFrom::ApplyOver, 0, nodes);
578 self.redraw(cx);
579 }
580
581 fn apply(&self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
582 let mut inner = self.0.borrow_mut();
583 if let LiveValue::Class {live_type, ..} = nodes[index].value {
584 if let Some(component) = &mut *inner {
585 if component.type_id() != live_type {
586 *inner = None; log!("TYPECHANGE");
588 }
589 else {
590 return component.apply(cx, from, index, nodes);
591 }
592 }
593 if let Some(component) = cx.live_registry.clone().borrow()
594 .components.get::<WidgetRegistry>().new(cx, live_type) {
595 if cx.debug.marker() == 1{
596 panic!()
597 }
598 *inner = Some(component);
599 if let Some(component) = &mut *inner {
600 return component.apply(cx, from, index, nodes);
601 }
602 }
603 else {
604 cx.apply_error_cant_find_target(live_error_origin!(), index, nodes, nodes[index].id);
605 }
606 }
607 else if let Some(component) = &mut *inner {
608 return component.apply(cx, from, index, nodes)
609 }
610 cx.apply_error_cant_find_target(live_error_origin!(), index, nodes, nodes[index].id);
611 nodes.skip_node(index)
612 }
613}
614
615impl LiveHook for WidgetRef {}
616impl LiveApply for WidgetRef {
617 fn apply(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
618 <WidgetRef>::apply(self, cx, from, index, nodes)
619 }
620}
621
622impl LiveNew for WidgetRef {
623 fn new(_cx: &mut Cx) -> Self {
624 Self (Rc::new(RefCell::new(None)))
625 }
626
627 fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
628 LiveTypeInfo {
629 module_id: LiveModuleId::from_str(&module_path!()).unwrap(),
630 live_type: LiveType::of::<dyn Widget>(),
631 fields: Vec::new(),
632 live_ignore: true,
633 type_name: LiveId(0)
634 }
635 }
636}
637
638#[derive(Clone)]
639pub struct WidgetActionItem {
640 pub widget_uid: WidgetUid,
641 pub container_uid: WidgetUid,
642 pub item_uid: WidgetUid,
643 pub action: Box<dyn WidgetAction>
644}
645
646impl Debug for WidgetActionItem {
647 fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
648 write!(f, "WidgetActionItem{{wiget_uid: {:?}, container_uid: {:?}, item_uid:{:?}}}", self.widget_uid, self.container_uid, self.item_uid)
649 }
650}
651
652pub type WidgetActions = Vec<WidgetActionItem>;
653
654pub trait WidgetActionsApi {
655 fn find_single_action(&self, widget_uid: WidgetUid) -> Option<&WidgetActionItem>;
656 fn single_action<T: WidgetAction + 'static >(&self, widget_uid: WidgetUid) -> T where T: Default + Clone;
657 fn not_empty(&self) -> bool;
658}
659
660impl WidgetActionsApi for WidgetActions {
661 fn find_single_action(&self, widget_uid: WidgetUid) -> Option<&WidgetActionItem> {
662 self.iter().find( | v | v.widget_uid == widget_uid)
663 }
664
665 fn single_action<T: WidgetAction + 'static >(&self, widget_uid: WidgetUid) -> T where T: Default + Clone {
666 if let Some(item) = self.find_single_action(widget_uid) {
667 item.action.cast::<T>()
668 }
669 else {
670 T::default()
671 }
672 }
673
674 fn not_empty(&self) -> bool {
675 self.len()>0
676 }
677}
678
679impl WidgetActionItem {
680 pub fn new(action: Box<dyn WidgetAction>, widget_uid: WidgetUid) -> Self {
681 Self {
682 container_uid: WidgetUid(0),
683 item_uid: WidgetUid(0),
684 widget_uid,
685 action
686 }
687 }
688 pub fn with_container(self, container_uid: WidgetUid) -> Self {
689 Self {
690 container_uid,
691 ..self
692 }
693 }
694
695 pub fn with_item(self, item_uid: WidgetUid) -> Self {
696 Self {
697 item_uid,
698 ..self
699 }
700 }
701
702 pub fn action<T: WidgetAction + 'static >(&self) -> T where T: Default + Clone {
703 self.action.cast::<T>()
704 }
705}
706
707
708pub struct DrawStateWrap<T: Clone> {
709 state: Option<T>,
710 redraw_id: u64
711}
712
713impl<T: Clone> Default for DrawStateWrap<T> {
714 fn default() -> Self {
715 Self {
716 state: None,
717 redraw_id: 0
718 }
719 }
720}
721
722impl<T: Clone> DrawStateWrap<T> {
723 pub fn begin(&mut self, cx: &mut Cx2d, init: T) -> bool {
724 if self.redraw_id != cx.redraw_id() {
725 self.redraw_id = cx.redraw_id();
726 self.state = Some(init);
727 true
728 }
729 else {
730 false
731 }
732 }
733
734 pub fn begin_with<F, S>(&mut self, cx: &mut Cx2d, v: &S, init: F) -> bool where F: FnOnce(&mut Cx2d, &S) -> T {
735 if self.redraw_id != cx.redraw_id() {
736 self.redraw_id = cx.redraw_id();
737 self.state = Some(init(cx, v));
738 true
739 }
740 else {
741 false
742 }
743 }
744
745 pub fn get(&self) -> Option<T> {
746 self.state.clone()
747 }
748
749 pub fn as_ref(&self) -> Option<&T> {
750 self.state.as_ref()
751 }
752
753 pub fn as_mut(&mut self) -> Option<&mut T> {
754 self.state.as_mut()
755 }
756
757 pub fn set(&mut self, value: T) {
758 self.state = Some(value);
759 }
760
761 pub fn end(&mut self) {
762 self.state = None;
763 }
764}
765
766#[macro_export]
767macro_rules!register_widget {
768 ( $ cx: ident, $ ty: ty) => {
769 {
770 struct Factory();
771 impl WidgetFactory for Factory {
772 fn new(&self, cx: &mut Cx) -> Box<dyn Widget> {
773 Box::new(< $ ty>::new(cx))
774 }
775 }
776 register_component_factory!( $ cx, WidgetRegistry, $ ty, Factory);
777 }
778 }
779}