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