start with break point handling
-use crate::{api::prelude::*, proc_macros::*, Grid};
+use std::collections::VecDeque;
+
+use crate::{api::prelude::*, proc_macros::*, shell::WindowRequest, Grid};
// --- KEYS --
static CONTENT_CONTAINER: &str = "id_content_container";
// --- KEYS --
+// Describes operations on the master detail state.
+#[derive(Debug, Clone, PartialEq)]
+enum MasterDetailAction {
+ ShowMaster,
+ ShowDetail,
+}
+
#[derive(Default, Clone, Debug, AsAny)]
pub struct MasterDetailState {
content_container: Entity,
master: Option<Entity>,
detail: Option<Entity>,
+ actions: VecDeque<MasterDetailAction>,
+ expanded: bool,
+}
+
+impl MasterDetailState {
+ /// Shows the master widget. If the master widget is visible nothing will happen.
+ pub fn show_master(&mut self) {
+ self.actions.push_front(MasterDetailAction::ShowMaster);
+ }
+
+ /// Shows the detail widget. If the detail widget is visible nothing will happen.
+ pub fn show_detail(&mut self) {
+ self.actions.push_front(MasterDetailAction::ShowDetail);
+ }
}
impl State for MasterDetailState {
@@ -17,13 +40,9 @@ impl State for MasterDetailState {
self.update(registry, ctx);
}
- fn cleanup(&mut self, _registry: &mut Registry, _ctx: &mut Context) {}
-
fn update(&mut self, _registry: &mut Registry, ctx: &mut Context) {
- if self.master.is_none() && self.detail.is_none() {
- return;
- }
-
+ // register new master and detail widget
+ if self.master.is_some() || self.detail.is_some() {
ctx.clear_children_of(self.content_container);
if let Some(master) = self.master {
@@ -37,7 +56,36 @@ impl State for MasterDetailState {
}
}
- fn update_post_layout(&mut self, _registry: &mut Registry, ctx: &mut Context) {}
+ // handle state actions
+ if let Some(action) = self.actions.pop_front() {
+ match action {
+ MasterDetailAction::ShowMaster => if !self.expanded {},
+ MasterDetailAction::ShowDetail => if !self.expanded {},
+ }
+ }
+ }
+
+ fn update_post_layout(&mut self, _registry: &mut Registry, ctx: &mut Context) {
+ let width = ctx
+ .get_widget(self.content_container)
+ .get::<Rectangle>("bounds")
+ .width();
+ let break_point: f64 = *MasterDetail::break_point_ref(&ctx.widget());
+
+ if self.expanded && width < break_point {
+ // todo collapse
+ // set master to visible and detail to collapsed
+ println!("collapse");
+ self.expanded = false;
+ ctx.send_window_request(WindowRequest::Redraw);
+ } else if !self.expanded && width > break_point {
+ // todo expand
+ // todo set both to visible
+ println!("expand");
+ self.expanded = true;
+ ctx.send_window_request(WindowRequest::Redraw);
+ }
+ }
}
widget!(
@@ -49,11 +97,17 @@ widget!(
);
impl MasterDetail {
+ /// Register a master widget (entity) on the master detail widget.
+ /// Only one master widget can be set. Only the last set widget will
+ /// be the master widget on the master detail widget.
pub fn master(mut self, master: Entity) -> Self {
self.state_mut().master = Some(master);
self
}
+ /// Register a detail widget (entity) on the master detail widget.
+ /// Only one detail widget can be set. Only the last set widget will
+ /// be the detail widget on the master detail widget.
pub fn detail(mut self, detail: Entity) -> Self {
self.state_mut().detail = Some(detail);
self
