Skip to main content

journey/widgets/
shared.rs

1//! A generic shared-ownership adapter.
2//!
3//! saudade's widget tree takes ownership of each child (`Box<dyn Widget>`),
4//! but the app root needs to keep talking to individual widgets after they're
5//! in the tree — e.g. to push new items into a list when the selection
6//! elsewhere changes. The notepad/picker demos solve this with one bespoke
7//! `SharedFoo` struct per widget type; [`Shared`] collapses that into a single
8//! generic wrapper that forwards every [`Widget`] method to an
9//! `Rc<RefCell<W>>`, so both the tree and the app root can hold a handle.
10
11use std::cell::RefCell;
12use std::rc::Rc;
13
14use saudade::{Event, EventCtx, Painter, PopupRequest, Rect, Theme, Widget};
15
16/// Shared, interior-mutable handle to a widget that lives in the tree.
17pub struct Shared<W>(pub Rc<RefCell<W>>);
18
19impl<W> Shared<W> {
20    pub fn new(inner: Rc<RefCell<W>>) -> Self {
21        Self(inner)
22    }
23
24    /// Clone the underlying handle so the app root can keep a reference.
25    pub fn handle(&self) -> Rc<RefCell<W>> {
26        self.0.clone()
27    }
28}
29
30impl<W: Widget> Widget for Shared<W> {
31    fn bounds(&self) -> Rect {
32        self.0.borrow().bounds()
33    }
34
35    fn paint(&mut self, painter: &mut Painter, theme: &Theme) {
36        self.0.borrow_mut().paint(painter, theme);
37    }
38
39    fn paint_overlay(&mut self, painter: &mut Painter, theme: &Theme) {
40        self.0.borrow_mut().paint_overlay(painter, theme);
41    }
42
43    fn event(&mut self, event: &Event, ctx: &mut EventCtx) {
44        self.0.borrow_mut().event(event, ctx);
45    }
46
47    fn captures_pointer(&self) -> bool {
48        self.0.borrow().captures_pointer()
49    }
50
51    fn focusable(&self) -> bool {
52        self.0.borrow().focusable()
53    }
54
55    fn set_focused(&mut self, focused: bool) {
56        self.0.borrow_mut().set_focused(focused);
57    }
58
59    fn accepts_accelerators(&self) -> bool {
60        self.0.borrow().accepts_accelerators()
61    }
62
63    fn layout(&mut self, bounds: Rect) {
64        self.0.borrow_mut().layout(bounds);
65    }
66
67    fn focus_first(&mut self) -> bool {
68        self.0.borrow_mut().focus_first()
69    }
70
71    fn popup_request(&self) -> Option<PopupRequest> {
72        self.0.borrow().popup_request()
73    }
74
75    fn wants_ticks(&self) -> bool {
76        self.0.borrow().wants_ticks()
77    }
78}