#![allow(unsafe_op_in_unsafe_fn)]
use windows_sys::Win32::Foundation::{HWND, RECT};
use windows_sys::Win32::System::LibraryLoader::GetModuleHandleW;
use windows_sys::Win32::UI::Controls::{PBS_SMOOTH, PROGRESS_CLASSW};
use windows_sys::Win32::UI::WindowsAndMessaging::{
CreateWindowExW, SetWindowPos, SWP_NOZORDER, WS_CHILD, WS_VISIBLE,
SendMessageW, WM_SETFONT, HMENU,
};
use windows_sys::Win32::Graphics::Gdi::HFONT;
use super::base::Component;
use crate::utils::to_wstring;
pub struct StatusBarIds {
pub label_id: u16,
pub progress_id: u16,
}
pub struct StatusBar {
hwnd_label: HWND,
hwnd_progress: HWND,
label_id: u16,
progress_id: u16,
x: i32,
y: i32,
width: i32,
}
impl StatusBar {
pub fn new(ids: StatusBarIds) -> Self {
Self {
hwnd_label: std::ptr::null_mut(),
hwnd_progress: std::ptr::null_mut(),
label_id: ids.label_id,
progress_id: ids.progress_id,
x: 0,
y: 0,
width: 0,
}
}
#[inline]
pub fn label_hwnd(&self) -> HWND {
self.hwnd_label
}
#[inline]
pub fn progress_hwnd(&self) -> HWND {
self.hwnd_progress
}
pub unsafe fn set_font(&self, hfont: HFONT) {
let wparam = hfont as usize;
let lparam = 1;
SendMessageW(self.hwnd_label, WM_SETFONT, wparam, lparam);
}
}
impl Component for StatusBar {
unsafe fn create(&mut self, parent: HWND) -> Result<(), String> {
unsafe {
let instance = GetModuleHandleW(std::ptr::null());
let label_text = to_wstring("Drag and drop files or folders, or use 'Files'/'Folder' buttons. Then click 'Process All'.");
let static_cls = to_wstring("STATIC");
self.hwnd_label = CreateWindowExW(
0,
static_cls.as_ptr(),
label_text.as_ptr(),
WS_CHILD | WS_VISIBLE,
10,
10,
860,
25,
parent,
self.label_id as usize as HMENU,
instance,
std::ptr::null(),
);
if self.hwnd_label == std::ptr::null_mut() {
return Err("Failed to create status label".to_string());
}
let empty_text = to_wstring("");
self.hwnd_progress = CreateWindowExW(
0,
PROGRESS_CLASSW,
empty_text.as_ptr(),
WS_VISIBLE | WS_CHILD | PBS_SMOOTH,
10,
430,
860,
20,
parent,
self.progress_id as usize as HMENU,
instance,
std::ptr::null(),
);
if self.hwnd_progress == std::ptr::null_mut() {
return Err("Failed to create progress bar".to_string());
}
Ok(())
}
}
fn hwnd(&self) -> Option<HWND> {
Some(self.hwnd_progress)
}
unsafe fn on_resize(&mut self, parent_rect: &RECT) {
unsafe {
let width = parent_rect.right - parent_rect.left;
let height = parent_rect.bottom - parent_rect.top;
let padding = 10;
let header_height = 25;
let progress_height = 25;
let btn_height = 30;
let lbl_height = 18;
let list_height = height - header_height - progress_height - btn_height - lbl_height - (padding * 5);
self.x = padding;
self.width = width - padding * 2;
let label_y = padding;
SetWindowPos(
self.hwnd_label,
std::ptr::null_mut(),
padding,
label_y,
width - padding - 120,
header_height,
SWP_NOZORDER,
);
let progress_y = padding + header_height + padding + list_height + padding;
self.y = progress_y;
SetWindowPos(
self.hwnd_progress,
std::ptr::null_mut(),
padding,
progress_y,
width - padding * 2,
progress_height,
SWP_NOZORDER,
);
}
}
unsafe fn on_theme_change(&mut self, _is_dark: bool) {
unsafe {
if self.hwnd_progress != std::ptr::null_mut() {
const PBM_SETSTATE: u32 = 1040;
SendMessageW(self.hwnd_progress, PBM_SETSTATE, 1, 0);
const PBM_SETBARCOLOR: u32 = 1033;
SendMessageW(self.hwnd_progress, PBM_SETBARCOLOR, 0, 0x0000FF00);
}
}
}
}