1use {
2 crate::{
3 Color, Context, DrawCh, DrawChs2D, DrawRegion, DrawUpdate, DynLocation, DynLocationSet,
4 DynVal, Element, ElementID, ElementOrganizer, Event, EventResponses, Pane, Parent,
5 ReceivableEvents, Size, Style, ZIndex,
6 },
7 std::collections::HashMap,
8 std::{
9 ops::Deref,
10 {
11 cell::{Ref, RefCell, RefMut},
12 rc::Rc,
13 },
14 },
15};
16
17#[derive(Clone)]
26pub struct ParentPane {
27 pub pane: Pane,
28 pub eo: ElementOrganizer,
29 pub el_store: Rc<RefCell<HashMap<String, Vec<u8>>>>,
30}
31
32#[yeehaw_derive::impl_pane_basics_from(pane)]
33impl ParentPane {
34 pub fn new(ctx: &Context, kind: &'static str) -> Self {
35 let pane = Pane::new(ctx, kind).with_focused(true);
36 ParentPane {
37 pane,
38 eo: ElementOrganizer::default(),
39 el_store: Rc::new(RefCell::new(HashMap::new())),
40 }
41 }
42
43 pub fn at<D: Into<DynVal>, D2: Into<DynVal>>(self, x: D, y: D2) -> Self {
44 self.set_at(x.into(), y.into());
45 self
46 }
47
48 pub fn with_kind(self, kind: &'static str) -> Self {
49 self.pane.set_kind(kind);
50 self
51 }
52
53 pub fn focused(self) -> Self {
54 *self.pane.focused.borrow_mut() = true;
55 self
56 }
57
58 pub fn unfocused(self) -> Self {
59 *self.pane.focused.borrow_mut() = false;
60 self
61 }
62
63 pub fn with_element(self, el: Box<dyn Element>) -> Self {
64 self.add_element(el); self
66 }
67
68 pub fn add_element(&self, el: Box<dyn Element>) {
69 self.eo.add_element(el, Some(Box::new(self.clone())))
70 }
71
72 pub fn remove_element(&self, el_id: &ElementID) {
73 self.eo.remove_element(el_id)
74 }
75
76 pub fn clear_elements(&self) {
77 self.eo.clear_elements()
78 }
79
80 pub fn has_elements(&self) -> bool {
81 !self.eo.els.borrow().is_empty()
82 }
83
84 pub fn get_element(&self, el_id: &ElementID) -> Option<Box<dyn Element>> {
88 self.eo.get_element(el_id)
89 }
90
91 pub fn get_element_attribute(&self, el_id: &ElementID, key: &str) -> Option<Vec<u8>> {
92 self.eo.get_element_attribute(el_id, key)
93 }
94
95 pub fn update_el_z_index(&self, el_id: &ElementID, z: ZIndex) {
96 self.eo.update_el_z_index(el_id, z);
97 }
98
99 pub fn send_responses_upward(&self, ctx: &Context, resps: EventResponses) {
101 self.pane.send_responses_upward(ctx, resps);
102 }
103
104 pub fn focus(&self) {
105 self.set_focused(true);
106 }
107
108 pub fn unfocus(&self) {
109 self.set_focused(false);
110 }
111
112 #[must_use]
114 pub fn send_event_to_el(&self, ctx: &Context, el_id: &ElementID, ev: Event) -> EventResponses {
115 self.eo
116 .send_event_to_el(ctx, el_id, ev, Box::new(self.clone()))
117 }
118}
119
120#[yeehaw_derive::impl_element_from(pane)]
121impl Element for ParentPane {
122 fn can_receive(&self, ev: &Event) -> bool {
123 self.get_focused() && (self.pane.can_receive(ev) || self.eo.can_receive(ev))
124 }
125
126 fn receivable(&self) -> Vec<Rc<RefCell<ReceivableEvents>>> {
127 let mut rec = self.eo.receivable();
128 rec.extend(self.pane.receivable());
129 rec
130 }
131
132 fn receive_event(&self, ctx: &Context, ev: Event) -> (bool, EventResponses) {
134 self.eo.event_process(ctx, ev, Box::new(self.clone()))
135 }
136
137 fn drawing(&self, ctx: &Context, dr: &DrawRegion, force_update: bool) -> Vec<DrawUpdate> {
138 if !self.get_visible() {
139 return Vec::with_capacity(0);
140 }
141 let mut out = self.pane.drawing(ctx, dr, force_update);
142 out.extend(self.eo.all_drawing_updates(ctx, dr, force_update));
143 out
144 }
145}
146
147impl Parent for ParentPane {
148 fn propagate_responses_upward(
175 &self, ctx: &Context, child_el_id: &ElementID, mut resps: EventResponses,
176 ) {
177 let b: Box<dyn Parent> = Box::new(self.clone());
178 self.eo
179 .partially_process_ev_resps(ctx, child_el_id, &mut resps, &b);
180 if let Some(parent) = self.pane.parent.borrow_mut().deref() {
181 parent.propagate_responses_upward(ctx, &self.id(), resps);
182 }
183 }
184
185 fn get_store_item(&self, key: &str) -> Option<Vec<u8>> {
186 self.el_store.borrow().get(key).cloned()
187 }
188
189 fn set_store_item(&self, key: &str, value: Vec<u8>) {
190 self.el_store.borrow_mut().insert(key.to_string(), value);
191 }
192
193 fn get_parent_focused(&self) -> bool {
194 self.pane.get_focused()
195 }
196
197 fn get_id(&self) -> ElementID {
198 self.pane.id()
199 }
200}