iris_ui/
tabbed_panel.rs

1use crate::Action;
2use crate::geom::Bounds;
3use crate::layouts::layout_tabbed_panel;
4use crate::scene::Scene;
5use crate::toggle_group::{input_toggle_group, make_toggle_group};
6use crate::view::{Flex, View, ViewId};
7use alloc::boxed::Box;
8use alloc::string::{String, ToString};
9use alloc::vec;
10use alloc::vec::Vec;
11use hashbrown::HashMap;
12use log::info;
13
14pub struct LayoutPanelState {
15    data: Vec<String>,
16    contents: HashMap<String, ViewId>,
17}
18
19impl LayoutPanelState {
20    pub fn register_panel(&mut self, tab_name: &str, content_id: &ViewId) {
21        info!("registering panel {tab_name} with content {content_id}");
22        self.data.push(tab_name.into());
23        self.contents.insert(tab_name.into(), *content_id);
24    }
25}
26
27pub fn make_tabbed_panel(
28    name: &ViewId,
29    data: Vec<&str>,
30    selected: usize,
31    scene: &mut Scene,
32) -> View {
33    let state = LayoutPanelState {
34        data: vec![],
35        contents: HashMap::new(),
36    };
37
38    let tabs_id = ViewId::new("tabs");
39    let mut tabs = make_toggle_group(&tabs_id, data, selected);
40    tabs.input = Some(|e| {
41        info!("got input");
42        let container = ViewId::new("tabbed-panel");
43        let res = input_toggle_group(e);
44        if let Some(action) = res {
45            info!("action is {:?}", action);
46
47            // hide all the children
48            for kid in e.scene.get_children_ids(&container) {
49                if kid.as_str() != "tabs" {
50                    e.scene.hide_view(&kid);
51                }
52            }
53
54            // then make the newly selected one visible
55            match action {
56                Action::Generic => {}
57                Action::Command(cmd) => {
58                    let panel_name = if let Some(state) =
59                        e.scene.get_view_state::<LayoutPanelState>(&container)
60                    {
61                        if let Some(panel) = state.contents.get(&cmd) {
62                            Some(panel.clone())
63                        } else {
64                            None
65                        }
66                    } else {
67                        None
68                    };
69                    info!("found the panel name {panel_name:?}");
70                    if let Some(panel) = panel_name {
71                        info!("setting the panel {}", panel);
72                        e.scene.show_view(&panel);
73                    }
74                }
75            }
76        }
77        return None;
78    });
79    scene.add_view_to_parent(tabs, name);
80
81    View {
82        name: *name,
83        bounds: Bounds::new(10, 10, 320 - 20, 180),
84        h_flex: Flex::Intrinsic,
85        v_flex: Flex::Intrinsic,
86        draw: Some(|e| {
87            e.ctx.fill_rect(&e.view.bounds, &e.theme.bg);
88            e.ctx.stroke_rect(&e.view.bounds, &e.theme.fg);
89        }),
90        state: Some(Box::new(state)),
91        layout: Some(layout_tabbed_panel),
92        ..Default::default()
93    }
94}