split_layout/
split_layout.rs

1use gtk::prelude::*;
2use relm4::adw::prelude::*;
3use relm4::prelude::*;
4
5#[derive(Debug)]
6enum AppMsg {
7    ToggleSidebar,
8    SetVisibleSidebar,
9}
10
11#[tracker::track]
12struct AppModel {
13    sidebar_width: i32,
14    sidebar_visible: bool,
15}
16
17#[relm4::component]
18impl SimpleComponent for AppModel {
19    type Init = ();
20    type Input = AppMsg;
21    type Output = ();
22
23    view! {
24        adw::ApplicationWindow {
25            set_default_width: 600,
26            set_default_height: 400,
27
28            #[wrap(Some)]
29            set_content = &adw::OverlaySplitView
30            {
31                #[track(model.changed(AppModel::sidebar_visible()))]
32                set_show_sidebar: model.sidebar_visible,
33                #[wrap(Some)]
34                set_sidebar = &gtk::Box {
35                    #[track(model.changed(AppModel::sidebar_width()))]
36                    set_width_request: model.sidebar_width,
37                    set_orientation: gtk::Orientation::Vertical,
38                    set_spacing: 12,
39                    set_margin_all: 12,
40                    append = &gtk::Button
41                    {
42                        set_label: "Resize of Sidebar",
43                        connect_clicked[sender] => move |_| {
44                            sender.input(AppMsg::ToggleSidebar);
45                        }
46                    },
47                },
48                #[wrap(Some)]
49                set_content = &adw::ToolbarView
50                {
51                    add_top_bar = &adw::HeaderBar
52                    {
53                        set_show_title: false,
54                    },
55                    #[wrap(Some)]
56                    set_content = &gtk::Box {
57                        set_orientation: gtk::Orientation::Vertical,
58                        append =  &gtk::Button
59                        {
60                            set_label: "Set Visible of Sidebar",
61                            connect_clicked[sender] => move |_| {
62                                sender.input(AppMsg::SetVisibleSidebar);
63                            },
64                            set_halign: gtk::Align::Center,
65                            set_hexpand: false,
66                            set_width_request: 150,
67                        }
68                    }
69                },
70
71            }
72        }
73    }
74    fn update(&mut self, msg: AppMsg, _sender: ComponentSender<Self>) {
75        // reset tracker value of the model
76        self.reset();
77        match msg {
78            AppMsg::ToggleSidebar => {
79                self.set_sidebar_width(if self.sidebar_width == 200 { 50 } else { 200 });
80                // if current width is 200 -> set to 50, otherwise set to 200
81            }
82            AppMsg::SetVisibleSidebar => {
83                self.set_sidebar_visible(!self.sidebar_visible);
84                // if visible -> hide, if hidden -> show
85            }
86        }
87    }
88
89    fn init(
90        _: Self::Init,
91        root: Self::Root,
92        sender: ComponentSender<Self>,
93    ) -> ComponentParts<Self> {
94        let model = AppModel {
95            sidebar_width: 200,
96            sidebar_visible: true,
97            tracker: 0,
98        };
99
100        let widgets = view_output!();
101
102        ComponentParts { model, widgets }
103    }
104}
105
106fn main() {
107    let app = RelmApp::new("relm4.example.split_layout");
108    app.run::<AppModel>(());
109}