Closed arslivinski closed 2 years ago
Native-windows-gui doesn't handle layout within layout very well. That's mostly because defining gui layouts is very verbose. That said, if you don't mind the verbosity, you can achieve that using partials:
use native_windows_gui as nwg;
use native_windows_derive as nwd;
use nwd::{NwgUi, NwgPartial};
use nwg::NativeUi;
use nwg::stretch::{style::*, geometry::*};
const ZERO: Dimension = Dimension::Points(0.0);
const NULL_PADDING: Rect<Dimension> = Rect { start: ZERO, end: ZERO, top: ZERO, bottom: ZERO };
// A "Label: Button" field
#[derive(Default, NwgPartial)]
pub struct ButtonPanelField {
label_text: &'static str,
#[nwg_layout(flex_direction: FlexDirection::Row)]
layout: nwg::FlexboxLayout,
#[nwg_control(text: data.label_text)]
#[nwg_layout_item(
layout: layout,
size: Size { width: Dimension::Percent(0.5), height: Dimension::Points(30.0) },
flex_grow: 1.0
)]
label: nwg::Label,
#[nwg_control(text: "Go")]
#[nwg_layout_item(
layout: layout,
size: Size { width: Dimension::Points(100.0), height: Dimension::Points(30.0) },
)]
button: nwg::Button,
}
// A "Label: Label" field
#[derive(Default, NwgPartial)]
pub struct TextPanelField {
label_text: &'static str,
#[nwg_layout(flex_direction: FlexDirection::Row)]
layout: nwg::FlexboxLayout,
#[nwg_control(text: data.label_text)]
#[nwg_layout_item(
layout: layout,
size: Size { width: Dimension::Percent(0.5), height: Dimension::Points(30.0) },
flex_grow: 1.0
)]
label: nwg::Label,
#[nwg_control(text: "TEST", h_align: nwg::HTextAlign::Right)]
#[nwg_layout_item(
layout: layout,
size: Size { width: Dimension::Points(100.0), height: Dimension::Points(30.0) },
)]
button: nwg::Label,
}
#[derive(Default, NwgPartial)]
pub struct ResultsPanel {
#[nwg_layout(flex_direction: FlexDirection::Column, padding: NULL_PADDING )]
layout: nwg::FlexboxLayout,
#[nwg_control(flags: "VISIBLE")]
#[nwg_layout_item(layout: layout, size: Size { height: Dimension::Points(40.0), ..Default::default() })]
f1: nwg::Frame,
#[nwg_partial(parent: f1)]
file: TextPanelField,
#[nwg_control(flags: "VISIBLE")]
#[nwg_layout_item(layout: layout, size: Size { height: Dimension::Points(40.0), ..Default::default() })]
f2: nwg::Frame,
#[nwg_partial(parent: f2)]
crc: TextPanelField,
#[nwg_control(flags: "VISIBLE")]
#[nwg_layout_item(layout: layout, size: Size { height: Dimension::Points(40.0), ..Default::default() })]
f3: nwg::Frame,
#[nwg_partial(parent: f3)]
md5: TextPanelField,
#[nwg_control(flags: "VISIBLE")]
#[nwg_layout_item(layout: layout, size: Size { height: Dimension::Points(40.0), ..Default::default() })]
f4: nwg::Frame,
#[nwg_partial(parent: f4)]
info: TextPanelField,
}
#[derive(Default, NwgPartial)]
pub struct ActionsPanel {
#[nwg_layout(flex_direction: FlexDirection::Column, padding: NULL_PADDING )]
layout: nwg::FlexboxLayout,
#[nwg_control(flags: "VISIBLE")]
#[nwg_layout_item(layout: layout, size: Size { height: Dimension::Points(40.0), ..Default::default() })]
f1: nwg::Frame,
#[nwg_partial(parent: f1)]
action1: ButtonPanelField,
#[nwg_control(flags: "VISIBLE")]
#[nwg_layout_item(layout: layout, size: Size { height: Dimension::Points(40.0), ..Default::default() })]
f2: nwg::Frame,
#[nwg_partial(parent: f2)]
action2: ButtonPanelField,
#[nwg_control(flags: "VISIBLE")]
#[nwg_layout_item(layout: layout, size: Size { height: Dimension::Points(40.0), ..Default::default() })]
f3: nwg::Frame,
#[nwg_partial(parent: f3)]
action3: ButtonPanelField,
}
#[derive(Default, NwgUi)]
pub struct App {
#[nwg_control(size: (600, 300), position: (300, 300), title: "Layout example")]
#[nwg_events( OnWindowClose: [App::exit] )]
window: nwg::Window,
#[nwg_layout(parent: window, flex_direction: FlexDirection::Row)]
layout1: nwg::FlexboxLayout,
#[nwg_control(parent: window)]
#[nwg_layout_item(layout: layout1, size: Size { width: Dimension::Percent(0.6), height: Dimension::Auto } )]
group1: nwg::Frame,
#[nwg_partial(parent: group1)]
results: ResultsPanel,
#[nwg_control(parent: window)]
#[nwg_layout_item(layout: layout1, size: Size { width: Dimension::Percent(0.4), height: Dimension::Auto } )]
group2: nwg::Frame,
#[nwg_partial(parent: group2)]
actions: ActionsPanel,
}
impl App {
fn exit(&self) {
nwg::stop_thread_dispatch();
}
}
fn main() {
nwg::init().expect("Failed to init Native Windows GUI");
nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
let app = App {
actions: ActionsPanel {
action1: ButtonPanelField { label_text: "Action 1", ..Default::default() },
action2: ButtonPanelField { label_text: "Action 2", ..Default::default() },
action3: ButtonPanelField { label_text: "Action 3", ..Default::default() },
..Default::default()
},
results: ResultsPanel {
file: TextPanelField { label_text: "File:", ..Default::default() },
crc: TextPanelField { label_text: "CR:", ..Default::default() },
md5: TextPanelField { label_text: "MD5:", ..Default::default() },
info: TextPanelField { label_text: "Info:", ..Default::default() },
..Default::default()
},
..Default::default()
};
let _app = App::build_ui(app).expect("Failed to build UI");
nwg::dispatch_thread_events();
}
This example will give you this:
I'm trying to replicate this layout:
But I'm unable to find a component that let me to create the Results and Actions fieldsets at the bottom. There's a way to do that with NWG?