Skip to main content

flexbox_sub_layout/
flexbox_sub_layout.rs

1/*!
2    A very simple application that show how to use a flexbox layout.
3
4    Requires the following features: `cargo run --example flexbox --features "flexbox"`
5*/
6
7extern crate native_windows_gui2 as nwg;
8use nwg::NativeUi;
9
10#[derive(Default)]
11pub struct FlexBoxApp {
12    window: nwg::Window,
13    layout: nwg::FlexboxLayout,
14    button1: nwg::Button,
15    layout2: nwg::FlexboxLayout,
16    button2: nwg::Button,
17    button3: nwg::Button,
18}
19
20impl FlexBoxApp {
21    fn exit(&self) {
22        nwg::stop_thread_dispatch();
23    }
24}
25
26//
27// ALL of this stuff is handled by native-windows-derive
28//
29mod flexbox_app_ui {
30    use super::*;
31    use native_windows_gui2 as nwg;
32    use std::cell::RefCell;
33    use std::ops::Deref;
34    use std::rc::Rc;
35
36    pub struct FlexBoxAppUi {
37        inner: Rc<FlexBoxApp>,
38        default_handler: RefCell<Option<nwg::EventHandler>>,
39    }
40
41    impl nwg::NativeUi<FlexBoxAppUi> for FlexBoxApp {
42        fn build_ui(mut data: FlexBoxApp) -> Result<FlexBoxAppUi, nwg::NwgError> {
43            use nwg::Event as E;
44
45            // Controls
46            nwg::Window::builder()
47                .size((500, 500))
48                .position((300, 300))
49                .title("Flexbox example")
50                .build(&mut data.window)?;
51
52            nwg::Button::builder()
53                .text("Btn 1")
54                .parent(&data.window)
55                .focus(true)
56                .build(&mut data.button1)?;
57
58            nwg::Button::builder()
59                .text("Btn 2")
60                .parent(&data.window)
61                .focus(true)
62                .build(&mut data.button2)?;
63
64            nwg::Button::builder()
65                .text("Btn 3")
66                .parent(&data.window)
67                .focus(true)
68                .build(&mut data.button3)?;
69
70            // Wrap-up
71            let ui = FlexBoxAppUi {
72                inner: Rc::new(data),
73                default_handler: Default::default(),
74            };
75
76            // Events
77            let evt_ui = Rc::downgrade(&ui.inner);
78            let handle_events = move |evt, _evt_data, handle| {
79                if let Some(evt_ui) = evt_ui.upgrade() {
80                    match evt {
81                        E::OnWindowClose => {
82                            if &handle == &evt_ui.window {
83                                FlexBoxApp::exit(&evt_ui);
84                            }
85                        }
86                        _ => {}
87                    }
88                }
89            };
90
91            *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(
92                &ui.window.handle,
93                handle_events,
94            ));
95
96            // Layout
97            use nwg::stretch::{
98                geometry::Size,
99                style::{Dimension as D, FlexDirection},
100            };
101
102            nwg::FlexboxLayout::builder()
103                .parent(&ui.window)
104                .flex_direction(FlexDirection::Column)
105                .child(&ui.button2)
106                .child_size(Size {
107                    width: D::Auto,
108                    height: D::Points(200.0),
109                })
110                .child(&ui.button3)
111                .child_flex_grow(2.0)
112                .child_size(Size {
113                    width: D::Auto,
114                    height: D::Auto,
115                })
116                .build_partial(&ui.layout2)?;
117
118            nwg::FlexboxLayout::builder()
119                .parent(&ui.window)
120                .flex_direction(FlexDirection::Row)
121                .child(&ui.button1)
122                .child_flex_grow(2.0)
123                .child_size(Size {
124                    width: D::Auto,
125                    height: D::Auto,
126                })
127                .child_layout(&ui.layout2)
128                .child_size(Size {
129                    width: D::Points(300.0),
130                    height: D::Auto,
131                })
132                .build(&ui.layout)?;
133
134            return Ok(ui);
135        }
136    }
137
138    impl Drop for FlexBoxAppUi {
139        /// To make sure that everything is freed without issues, the default handler must be unbound.
140        fn drop(&mut self) {
141            let handler = self.default_handler.borrow();
142            if handler.is_some() {
143                nwg::unbind_event_handler(handler.as_ref().unwrap());
144            }
145        }
146    }
147
148    impl Deref for FlexBoxAppUi {
149        type Target = FlexBoxApp;
150
151        fn deref(&self) -> &FlexBoxApp {
152            &self.inner
153        }
154    }
155}
156
157fn main() {
158    nwg::init().expect("Failed to init Native Windows GUI");
159    nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
160
161    let _ui = FlexBoxApp::build_ui(Default::default()).expect("Failed to build UI");
162
163    nwg::dispatch_thread_events();
164}