winio_ui_win32/ui/
progress.rs

1use inherit_methods_macro::inherit_methods;
2use windows_sys::Win32::UI::{
3    Controls::{
4        PBM_GETPOS, PBM_GETRANGE, PBM_SETMARQUEE, PBM_SETPOS, PBM_SETRANGE32, PBS_MARQUEE,
5        PBS_SMOOTHREVERSE, PROGRESS_CLASSW,
6    },
7    HiDpi::GetSystemMetricsForDpi,
8    WindowsAndMessaging::{SM_CYVSCROLL, USER_DEFAULT_SCREEN_DPI, WS_CHILD, WS_VISIBLE},
9};
10use winio_handle::AsWindow;
11use winio_primitive::{Point, Size};
12
13use crate::ui::Widget;
14
15#[derive(Debug)]
16pub struct Progress {
17    handle: Widget,
18}
19
20#[inherit_methods(from = "self.handle")]
21impl Progress {
22    pub fn new(parent: impl AsWindow) -> Self {
23        let mut handle = Widget::new(
24            PROGRESS_CLASSW,
25            WS_CHILD | WS_VISIBLE | PBS_SMOOTHREVERSE,
26            0,
27            parent.as_window().as_win32(),
28        );
29        handle.set_size(handle.size_d2l((100, 15)));
30        Self { handle }
31    }
32
33    pub fn is_visible(&self) -> bool;
34
35    pub fn set_visible(&mut self, v: bool);
36
37    pub fn is_enabled(&self) -> bool;
38
39    pub fn set_enabled(&mut self, v: bool);
40
41    pub fn preferred_size(&self) -> Size {
42        let height = unsafe { GetSystemMetricsForDpi(SM_CYVSCROLL, USER_DEFAULT_SCREEN_DPI) };
43        Size::new(0.0, height as _)
44    }
45
46    pub fn loc(&self) -> Point;
47
48    pub fn set_loc(&mut self, p: Point);
49
50    pub fn size(&self) -> Size;
51
52    pub fn set_size(&mut self, v: Size);
53
54    pub fn range(&self) -> (usize, usize) {
55        let min = self.handle.send_message(PBM_GETRANGE, 1, 0) as usize;
56        let max = self.handle.send_message(PBM_GETRANGE, 0, 0) as usize;
57        (min, max)
58    }
59
60    pub fn set_range(&mut self, min: usize, max: usize) {
61        self.handle.send_message(PBM_SETRANGE32, min as _, max as _);
62    }
63
64    pub fn pos(&self) -> usize {
65        self.handle.send_message(PBM_GETPOS, 0, 0) as _
66    }
67
68    pub fn set_pos(&mut self, pos: usize) {
69        self.handle.send_message(PBM_SETPOS, pos as _, 0);
70    }
71
72    pub fn is_indeterminate(&self) -> bool {
73        (self.handle.style() & PBS_MARQUEE) != 0
74    }
75
76    pub fn set_indeterminate(&mut self, v: bool) {
77        let mut style = self.handle.style();
78        if v {
79            style |= PBS_MARQUEE;
80        } else {
81            style &= !PBS_MARQUEE;
82        }
83        self.handle.set_style(style);
84        self.handle
85            .send_message(PBM_SETMARQUEE, if v { 1 } else { 0 }, 0);
86    }
87}
88
89winio_handle::impl_as_widget!(Progress, handle);