use super::ControlHandle;
use crate::NwgError;
use crate::win32::window::{build_hwnd_control, build_notice, build_timer};
use winapi::shared::minwindef::DWORD;
use winapi::shared::windef::HWND;
#[cfg(feature = "menu")]
use crate::win32::menu::build_hmenu_control;
#[cfg(feature = "menu")]
use winapi::shared::windef::HMENU;
const NOTICE: u32 = 1;
const TRAY: u32 = 2;
#[derive(Debug, Clone)]
pub struct ControlBase;
impl ControlBase {
pub fn build_hwnd() -> HwndBuilder {
HwndBuilder::default()
}
#[cfg(feature = "menu")]
pub fn build_hmenu() -> HmenuBuilder {
HmenuBuilder::default()
}
pub fn build_timer() -> TimerBuilder {
TimerBuilder::default()
}
pub fn build_notice() -> OtherBuilder {
OtherBuilder {
parent: None,
ty: NOTICE,
}
}
pub fn build_tray_notification() -> OtherBuilder {
OtherBuilder {
parent: None,
ty: TRAY,
}
}
}
#[derive(Default)]
pub struct HwndBuilder {
class_name: String,
text: Option<String>,
size: Option<(i32, i32)>,
pos: Option<(i32, i32)>,
forced_flags: DWORD,
flags: Option<DWORD>,
ex_flags: Option<DWORD>,
parent: Option<HWND>,
}
impl HwndBuilder {
pub fn class_name<'a>(mut self, name: &'a str) -> HwndBuilder {
self.class_name = name.to_string();
self
}
pub fn text<'a>(mut self, text: &'a str) -> HwndBuilder {
self.text = Some(text.to_string());
self
}
pub fn size(mut self, size: (i32, i32)) -> HwndBuilder {
self.size = Some(size);
self
}
pub fn position(mut self, pos: (i32, i32)) -> HwndBuilder {
self.pos = Some(pos);
self
}
pub fn flags(mut self, flags: u32) -> HwndBuilder {
self.flags = Some(flags as DWORD);
self
}
pub fn ex_flags(mut self, flags: u32) -> HwndBuilder {
self.ex_flags = Some(flags as DWORD);
self
}
pub fn forced_flags(mut self, flags: u32) -> HwndBuilder {
self.forced_flags = flags as DWORD;
self
}
pub fn parent(mut self, parent: Option<ControlHandle>) -> HwndBuilder {
match parent {
Some(p) => {
self.parent = p.hwnd();
}
None => {
self.parent = None;
}
}
self
}
pub fn build(self) -> Result<ControlHandle, NwgError> {
let handle = build_hwnd_control(
&self.class_name,
self.text.as_ref().map(|v| v as &str),
self.size,
self.pos,
self.flags,
self.ex_flags,
self.forced_flags,
self.parent,
)?;
Ok(handle)
}
}
#[derive(Default)]
#[cfg(feature = "menu")]
pub struct HmenuBuilder {
text: Option<String>,
item: bool,
separator: bool,
popup: bool,
parent_menu: Option<HMENU>,
parent_window: Option<HWND>,
}
#[cfg(feature = "menu")]
impl HmenuBuilder {
pub fn text<'a>(mut self, text: &'a str) -> HmenuBuilder {
self.text = Some(text.to_string());
self
}
pub fn item(mut self, i: bool) -> HmenuBuilder {
self.item = i;
self
}
pub fn separator(mut self, i: bool) -> HmenuBuilder {
self.separator = i;
self
}
pub fn popup(mut self, i: bool) -> HmenuBuilder {
self.popup = i;
self
}
pub fn parent(mut self, parent: ControlHandle) -> HmenuBuilder {
match parent {
ControlHandle::Hwnd(hwnd) => {
self.parent_window = Some(hwnd);
}
ControlHandle::Menu(_parent, menu) => {
self.parent_menu = Some(menu);
}
ControlHandle::PopMenu(_hwnd, menu) => {
self.parent_menu = Some(menu);
}
_ => {}
}
self
}
pub fn build(self) -> Result<ControlHandle, NwgError> {
let handle = build_hmenu_control(
self.text,
self.item,
self.separator,
self.popup,
self.parent_menu,
self.parent_window,
)?;
Ok(handle)
}
}
#[derive(Default)]
pub struct TimerBuilder {
parent: Option<HWND>,
interval: u32,
stopped: bool,
}
impl TimerBuilder {
pub fn stopped(mut self, v: bool) -> TimerBuilder {
self.stopped = v;
self
}
pub fn interval(mut self, i: u32) -> TimerBuilder {
self.interval = i;
self
}
pub fn parent(mut self, parent: Option<ControlHandle>) -> TimerBuilder {
match parent {
Some(p) => {
self.parent = p.hwnd();
}
None => panic!("Timer parent must be HWND"),
}
self
}
pub fn build(self) -> Result<ControlHandle, NwgError> {
let handle = unsafe {
build_timer(
self.parent
.expect("Internal error. Timer without window parent"),
self.interval,
self.stopped,
)
};
Ok(handle)
}
}
#[derive(Default)]
pub struct OtherBuilder {
parent: Option<HWND>,
ty: u32,
}
impl OtherBuilder {
pub fn parent(mut self, parent: HWND) -> OtherBuilder {
self.parent = Some(parent);
self
}
pub fn build(self) -> Result<ControlHandle, NwgError> {
let handle = self
.parent
.expect("Internal error. Control without window parent");
let base = match self.ty {
NOTICE => build_notice(handle),
TRAY => ControlHandle::SystemTray(handle),
_ => unreachable!(),
};
Ok(base)
}
}