use winapi::um::winuser::{WS_VISIBLE, WS_DISABLED, WS_BORDER, WS_CHILD, WS_CLIPCHILDREN, WS_EX_CONTROLPARENT};
use crate::win32::window_helper as wh;
use crate::win32::base_helper::check_hwnd;
use crate::NwgError;
use super::{ControlBase, ControlHandle};
const NOT_BOUND: &'static str = "Frame is not yet bound to a winapi object";
const BAD_HANDLE: &'static str = "INTERNAL ERROR: Frame handle is not HWND!";
bitflags! {
pub struct FrameFlags: u32 {
const NONE = 0;
const VISIBLE = WS_VISIBLE;
const DISABLED = WS_DISABLED;
const BORDER = WS_BORDER;
}
}
#[derive(Default, PartialEq, Eq)]
pub struct Frame {
pub handle: ControlHandle
}
impl Frame {
pub fn builder() -> FrameBuilder {
FrameBuilder {
size: (100, 25),
position: (0, 0),
enabled: true,
flags: None,
ex_flags: 0,
parent: None,
}
}
pub fn focus(&self) -> bool {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::get_focus(handle) }
}
pub fn set_focus(&self) {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::set_focus(handle); }
}
pub fn enabled(&self) -> bool {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::get_window_enabled(handle) }
}
pub fn set_enabled(&self, v: bool) {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::set_window_enabled(handle, v) }
}
pub fn visible(&self) -> bool {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::get_window_visibility(handle) }
}
pub fn set_visible(&self, v: bool) {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::set_window_visibility(handle, v) }
}
pub fn size(&self) -> (u32, u32) {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::get_window_size(handle) }
}
pub fn set_size(&self, x: u32, y: u32) {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::set_window_size(handle, x, y, false) }
}
pub fn position(&self) -> (i32, i32) {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::get_window_position(handle) }
}
pub fn set_position(&self, x: i32, y: i32) {
let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
unsafe { wh::set_window_position(handle, x, y) }
}
pub fn class_name(&self) -> &'static str {
"NWG_FRAME"
}
pub fn flags(&self) -> u32 {
WS_VISIBLE | WS_BORDER
}
pub fn forced_flags(&self) -> u32 {
WS_CHILD | WS_CLIPCHILDREN
}
}
impl Drop for Frame {
fn drop(&mut self) {
self.handle.destroy();
}
}
pub struct FrameBuilder {
size: (i32, i32),
position: (i32, i32),
enabled: bool,
flags: Option<FrameFlags>,
ex_flags: u32,
parent: Option<ControlHandle>
}
impl FrameBuilder {
pub fn flags(mut self, flags: FrameFlags) -> FrameBuilder {
self.flags = Some(flags);
self
}
pub fn ex_flags(mut self, flags: u32) -> FrameBuilder {
self.ex_flags = flags;
self
}
pub fn size(mut self, size: (i32, i32)) -> FrameBuilder {
self.size = size;
self
}
pub fn position(mut self, pos: (i32, i32)) -> FrameBuilder {
self.position = pos;
self
}
pub fn enabled(mut self, e: bool) -> FrameBuilder {
self.enabled = e;
self
}
pub fn parent<C: Into<ControlHandle>>(mut self, p: C) -> FrameBuilder {
self.parent = Some(p.into());
self
}
pub fn build(self, out: &mut Frame) -> Result<(), NwgError> {
let flags = self.flags.map(|f| f.bits()).unwrap_or(out.flags());
let parent = match self.parent {
Some(p) => Ok(p),
None => Err(NwgError::no_parent("Frame"))
}?;
*out = Default::default();
out.handle = ControlBase::build_hwnd()
.class_name(out.class_name())
.forced_flags(out.forced_flags())
.flags(flags)
.ex_flags(WS_EX_CONTROLPARENT | self.ex_flags)
.size(self.size)
.position(self.position)
.parent(Some(parent))
.build()?;
out.set_enabled(self.enabled);
Ok(())
}
}