native_windows_gui2/controls/
status_bar.rs1use super::{ControlBase, ControlHandle};
2use crate::win32::base_helper::check_hwnd;
3use crate::win32::window_helper as wh;
4use crate::{Font, NwgError, RawEventHandler, unbind_raw_event_handler};
5use std::cell::RefCell;
6use winapi::shared::minwindef::{LPARAM, WPARAM};
7
8const NOT_BOUND: &'static str = "StatusBar is not yet bound to a winapi object";
9const BAD_HANDLE: &'static str = "INTERNAL ERROR: StatusBar handle is not HWND!";
10
11#[derive(Default)]
40pub struct StatusBar {
41 pub handle: ControlHandle,
42 handler0: RefCell<Option<RawEventHandler>>,
43}
44
45impl StatusBar {
46 pub fn builder<'a>() -> StatusBarBuilder<'a> {
47 StatusBarBuilder {
48 text: "",
49 font: None,
50 parent: None,
51 }
52 }
53
54 pub fn set_min_height(&self, height: u32) {
56 use winapi::um::commctrl::SB_SETMINHEIGHT;
57 use winapi::um::winuser::WM_SIZE;
58
59 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
60 wh::send_message(handle, SB_SETMINHEIGHT, height as WPARAM, 0);
61 wh::send_message(handle, WM_SIZE, 0, 0); }
63
64 pub fn font(&self) -> Option<Font> {
66 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
67 let font_handle = wh::get_window_font(handle);
68 if font_handle.is_null() {
69 None
70 } else {
71 Some(Font {
72 handle: font_handle,
73 })
74 }
75 }
76
77 pub fn set_font(&self, font: Option<&Font>) {
79 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
80
81 wh::set_window_font(handle, font.map(|f| f.handle), true);
82 }
83
84 pub fn text<'a>(&self, index: u8) -> String {
86 use crate::win32::base_helper::from_utf16;
87 use winapi::shared::minwindef::LOWORD;
88 use winapi::um::commctrl::{SB_GETTEXTLENGTHW, SB_GETTEXTW};
89
90 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
91 let result = wh::send_message(handle, SB_GETTEXTLENGTHW, index as WPARAM, 0);
92 let text_length = (LOWORD(result as u32) as usize) + 1; let mut buffer: Vec<u16> = Vec::with_capacity(text_length);
95 unsafe {
96 buffer.set_len(text_length);
97 }
98
99 wh::send_message(
100 handle,
101 SB_GETTEXTW,
102 index as WPARAM,
103 buffer.as_mut_ptr() as LPARAM,
104 );
105
106 from_utf16(&buffer)
107 }
108
109 pub fn set_text<'a>(&self, index: u8, text: &'a str) {
111 use crate::win32::base_helper::to_utf16;
112 use winapi::um::commctrl::SB_SETTEXTW;
113
114 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
115 let text = to_utf16(text);
116 wh::send_message(
117 handle,
118 SB_SETTEXTW,
119 index as WPARAM,
120 text.as_ptr() as LPARAM,
121 );
122 }
123
124 pub fn class_name(&self) -> &'static str {
126 "msctls_statusbar32"
127 }
128
129 pub fn flags(&self) -> u32 {
131 ::winapi::um::winuser::WS_VISIBLE
132 }
133
134 pub fn forced_flags(&self) -> u32 {
136 use winapi::um::winuser::WS_CHILD;
137
138 WS_CHILD
139 }
140
141 pub fn hook_parent_resize(&self) {
144 use crate::bind_raw_event_handler_inner;
145 use winapi::um::winuser::WM_SIZE;
146
147 if self.handle.blank() {
148 panic!("{}", NOT_BOUND);
149 }
150 let handle = self.handle.hwnd().expect(BAD_HANDLE);
151
152 let parent_handle = ControlHandle::Hwnd(wh::get_window_parent(handle));
153 let handler = bind_raw_event_handler_inner(
154 &parent_handle,
155 handle as usize,
156 move |_hwnd, msg, _w, _l| {
157 if msg == WM_SIZE {
158 wh::send_message(handle, WM_SIZE, 0, 0);
159 }
160
161 None
162 },
163 );
164
165 *self.handler0.borrow_mut() = Some(handler.unwrap());
166 }
167}
168
169impl Drop for StatusBar {
170 fn drop(&mut self) {
171 let handler = self.handler0.borrow();
172 if let Some(h) = handler.as_ref() {
173 drop(unbind_raw_event_handler(h));
174 }
175 self.handle.destroy();
176 }
177}
178
179pub struct StatusBarBuilder<'a> {
180 text: &'a str,
181 font: Option<&'a Font>,
182 parent: Option<ControlHandle>,
183}
184
185impl<'a> StatusBarBuilder<'a> {
186 pub fn text(mut self, text: &'a str) -> StatusBarBuilder<'a> {
187 self.text = text;
188 self
189 }
190
191 pub fn font(mut self, font: Option<&'a Font>) -> StatusBarBuilder<'a> {
192 self.font = font;
193 self
194 }
195
196 pub fn parent<C: Into<ControlHandle>>(mut self, p: C) -> StatusBarBuilder<'a> {
197 self.parent = Some(p.into());
198 self
199 }
200
201 pub fn build(self, out: &mut StatusBar) -> Result<(), NwgError> {
202 let parent = match self.parent {
203 Some(p) => Ok(p),
204 None => Err(NwgError::no_parent("StatusBar")),
205 }?;
206
207 *out = Default::default();
208
209 out.handle = ControlBase::build_hwnd()
210 .class_name(out.class_name())
211 .forced_flags(out.forced_flags())
212 .flags(out.flags())
213 .parent(Some(parent))
214 .build()?;
215
216 if self.font.is_some() {
217 out.set_font(self.font);
218 } else {
219 out.set_font(Font::global_default().as_ref());
220 }
221
222 out.set_text(0, self.text);
223 out.hook_parent_resize();
224
225 Ok(())
226 }
227}
228
229impl PartialEq for StatusBar {
230 fn eq(&self, other: &Self) -> bool {
231 self.handle == other.handle
232 }
233}