gabdube / native-windows-gui

A light windows GUI toolkit for rust
https://gabdube.github.io/native-windows-gui/
MIT License
1.96k stars 127 forks source link

question: using partial's parent in child partial #231

Closed guilherme-gm closed 2 years ago

guilherme-gm commented 2 years ago

Hello, first of all thanks for this lib, it is awesome!

I would like to know if it is possible to use a partial's parent as the parent of another partial that is a child of this one. for example:

#[derive(Default, NwgPartial)]
struct SecondPartial {
    #[nwg_control(text: "Hello World", position: (10, 10), size: (100, 20))]
    some_label: Label,
}

#[derive(Default, NwgPartial)]
pub struct FirstPartial {
    #[nwg_partial(parent: /* put something here? */)]
    child_partial: SecondPartial,
}

#[derive(Default, NwgUi)]
pub struct MyApp {
    #[nwg_control(size: (300, 300))]
    window: nwg::Window,

    #[nwg_partial(parent: window)]
    sub_area: FirstPartial,
}

I am trying to do that because I want to have a part of my window changing between two states (which includes a few controls), so I was thinking about the first partial holding 2 partials, one for each state, and being able to toggle between them, but the SecondPartial panics, as far as I can tell, because it doesn't have a parent:

thread 'main' panicked at 'called Option::unwrap() on a None value', ... partial_second_partial_ui::impl$0::build_partial<ref$ >

Is it possible to give it the parent? Or if I am going in the wrong way, do you have any suggestion of a better way to do that?

Thanks

gabdube commented 2 years ago

Sorry for the late response, you can embed partial using a frame control. Try this for example:

/*!
    A very simple application that show your name in a message box.
    See `basic` for the version without the derive macro
*/

extern crate native_windows_gui as nwg;
extern crate native_windows_derive as nwd;

use nwd::{NwgUi, NwgPartial};
use nwg::NativeUi;

use nwg::stretch::style::FlexDirection;

#[derive(Default, NwgPartial)]
pub struct Partial2 {
  #[nwg_layout(flex_direction: FlexDirection::Column)]
  layout: nwg::FlexboxLayout,

  #[nwg_control(text: "Button 1")]
  #[nwg_layout_item(layout: layout)]
  btn1: nwg::Button, 

  #[nwg_control(text: "Button 2")]
  #[nwg_layout_item(layout: layout)]
  btn2: nwg::Button, 

  #[nwg_control(text: "Button 3")]
  #[nwg_layout_item(layout: layout)]
  btn3: nwg::Button, 

  #[nwg_control(text: "Button 4")]
  #[nwg_layout_item(layout: layout)]
  btn4: nwg::Button, 

  #[nwg_control(text: "Button 5")]
  #[nwg_layout_item(layout: layout)]
  btn5: nwg::Button, 
}

#[derive(Default, NwgPartial)]
pub struct Partial1 {
  #[nwg_layout]
  layout: nwg::FlexboxLayout,

  #[nwg_control(text: "Test")]
  #[nwg_layout_item(layout: layout)]
  test_btn: nwg::Button,

  #[nwg_control]
  #[nwg_layout_item(layout: layout)]
  frame: nwg::Frame,

  #[nwg_partial(parent: frame)]
  people_ui: Partial2,
}

#[derive(Default, NwgUi)]
pub struct PartialDemo {
    #[nwg_control(size: (500, 500), position: (300, 300), title: "Many UI")]
    #[nwg_events( OnWindowClose: [PartialDemo::exit] )]
    window: nwg::Window,

    #[nwg_layout(parent: window)]
    layout: nwg::FlexboxLayout,

    #[nwg_control]
    #[nwg_layout_item(layout: layout)]
    frame: nwg::Frame,

    #[nwg_partial(parent: frame)]
    people_ui: Partial1,
}

impl PartialDemo {

  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 _ui = PartialDemo::build_ui(Default::default()).expect("Failed to build UI");

  nwg::dispatch_thread_events();
}
guilherme-gm commented 2 years ago

Thank you! I didn't know about the frame control, this helped me a lot!