Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: tab control #50

Closed
Hawk777 opened this issue Dec 1, 2022 · 5 comments
Closed

Feature request: tab control #50

Hawk777 opened this issue Dec 1, 2022 · 5 comments
Assignees
Labels
enhancement New feature or request gui Something within the gui module

Comments

@Hawk777
Copy link

Hawk777 commented Dec 1, 2022

It would be nice to have a wrapper in the gui module for the tab common control.

@rodrigocfd rodrigocfd added the enhancement New feature or request label Dec 1, 2022
@rodrigocfd rodrigocfd self-assigned this Dec 1, 2022
rodrigocfd added a commit that referenced this issue Dec 30, 2022
rodrigocfd added a commit that referenced this issue Dec 31, 2022
rodrigocfd added a commit that referenced this issue Jan 2, 2023
rodrigocfd added a commit that referenced this issue Jan 5, 2023
rodrigocfd added a commit that referenced this issue Jan 5, 2023
@rodrigocfd
Copy link
Owner

Here's an example, main window:

use winsafe::{prelude::*, self as w, gui, co};

use crate::tab_container1::TabContainer1;
use crate::tab_container2::TabContainer2;

#[derive(Clone)]
pub struct MyWindow {
	wnd:      gui::WindowMain,
	tab_ctrl: gui::Tab,
}

impl MyWindow {
	pub fn new() -> Self {
		let wnd = gui::WindowMain::new(
			gui::WindowMainOpts {
				title: "Tabs".to_owned(),
				class_icon: gui::Icon::Id(101),
				size: w::SIZE::new(300, 150),
				style: gui::WindowMainOpts::default().style | co::WS::MINIMIZEBOX, // add a minimize button
				..Default::default()
			},
		);

		let tab_ctrl = gui::Tab::new(
			&wnd,
			gui::TabOpts {
				position: w::POINT::new(10, 10),
				size: w::SIZE::new(280, 130),
				items: vec![
					("First".to_owned(), Box::new(TabContainer1::new(&wnd))), // create the 2 tabs
					("Second".to_owned(), Box::new(TabContainer2::new(&wnd))),
				],
				..Default::default()
			},
		);

		let new_self = Self { wnd, tab_ctrl };
		new_self.events();
		new_self
	}

	pub fn run(&self) -> gui::MsgResult<i32> {
		self.wnd.run_main(None)
	}

	fn events(&self) {

	}
}

First tab:

use winsafe::{prelude::*, self as w, gui, co};

#[derive(Clone)]
pub struct TabContainer1 {
	wnd: gui::WindowControl,
	txt: gui::Edit,
	btn: gui::Button,
}

impl GuiTab for TabContainer1 { // we must implement GuiTab so this window can be used as a tab
	fn as_ctrl(&self) -> &gui::WindowControl {
		&self.wnd
	}
}

impl TabContainer1 {
	pub fn new(parent: &impl GuiParent) -> Self {
		let wnd = gui::WindowControl::new(
			parent,
			gui::WindowControlOpts {
				ex_style: co::WS_EX::CONTROLPARENT, // so the focus rotation works properly
				..Default::default()
			},
		);

		let txt = gui::Edit::new(
			&wnd,
			gui::EditOpts {
				position: w::POINT::new(20, 20),
				width: 180,
				..Default::default()
			},
		);

		let btn = gui::Button::new(
			&wnd,
			gui::ButtonOpts {
				position: w::POINT::new(20, 52),
				text: "&Hello".to_owned(),
				..Default::default()
			},
		);

		let new_self = Self { wnd, txt, btn };
		new_self.events();
		new_self
	}

	fn events(&self) {
		let self2 = self.clone();
		self.btn.on().bn_clicked(move || {
			w::task_dlg::info(
				&self2.wnd.hwnd().GetParent()?, "Hello", None, &self2.txt.text())?;
			Ok(())
		});
	}
}

Second tab:

use winsafe::{prelude::*, self as w, gui, co};

#[derive(Clone)]
pub struct TabContainer2 {
	wnd: gui::WindowControl,
}

impl GuiTab for TabContainer2 { // we must implement GuiTab so this window can be used as a tab
	fn as_ctrl(&self) -> &gui::WindowControl {
		&self.wnd
	}
}

impl TabContainer2 {
	pub fn new(parent: &impl GuiParent) -> Self {
		let wnd = gui::WindowControl::new(
			parent,
			gui::WindowControlOpts {
				ex_style: co::WS_EX::CONTROLPARENT, // so the focus rotation works properly
				..Default::default()
			},
		);

		let new_self = Self { wnd };
		new_self.events();
		new_self
	}

	fn events(&self) {

	}
}

This example will soon be in the examples repo.

@rodrigocfd rodrigocfd added the gui Something within the gui module label Jan 25, 2023
@rodrigocfd
Copy link
Owner

Just to let you know: the tab example is now live.

@Hawk777
Copy link
Author

Hawk777 commented Feb 6, 2023

I’m already using it in my own program, thanks! (not finished yet, but will be open source once it is)

@rodrigocfd
Copy link
Owner

That's great, please let me know when it's ready.

@rodrigocfd
Copy link
Owner

Heads-up: I simplified the trait implementation, so instead of GuiTab, now you just need impl AsRef.

Examples repo has been updated.

This change will be in v0.0.21.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request gui Something within the gui module
Projects
None yet
Development

No branches or pull requests

2 participants