native_windows_gui2/resources/
color_dialog.rs1use crate::NwgError;
2use crate::controls::ControlHandle;
3use std::cell::RefCell;
4use std::pin::Pin;
5use std::{mem, ptr};
6use winapi::shared::{minwindef::DWORD, windef::COLORREF};
7use winapi::um::commdlg::{CC_RGBINIT, CHOOSECOLORW, ChooseColorW};
8use winapi::um::wingdi::{GetBValue, GetGValue, GetRValue, RGB};
9
10struct InnerColorDialog {
11 custom_colors: Pin<Box<[COLORREF; 16]>>,
12 dialog: CHOOSECOLORW,
13}
14
15pub struct ColorDialog {
19 data: RefCell<InnerColorDialog>,
20}
21
22impl ColorDialog {
23 pub fn builder() -> ColorDialogBuilder {
24 ColorDialogBuilder {
25 default_colors: Default::default(),
26 }
27 }
28
29 pub fn run<C: Into<ControlHandle>>(&self, owner: Option<C>) -> bool {
34 if owner.is_some() {
35 let ownder_handle = owner.unwrap().into();
36 self.data.borrow_mut().dialog.hwndOwner = ownder_handle
37 .hwnd()
38 .expect("Color dialog must be a window control");
39 }
40
41 unsafe {
42 let mut data = self.data.borrow_mut();
43 let data_ref = &mut data.dialog;
44 ChooseColorW(data_ref as *mut CHOOSECOLORW) > 0
45 }
46 }
47
48 pub fn color(&self) -> [u8; 3] {
53 let v = self.data.borrow().dialog.rgbResult;
54 [GetRValue(v), GetGValue(v), GetBValue(v)]
55 }
56
57 pub fn set_saved_color(&self, index: usize, color: &[u8; 3]) {
64 if index > 15 {
65 panic!("{:?} is outside the dialog saved color bounds", index);
66 }
67 self.data.borrow_mut().custom_colors[index] = RGB(color[0], color[1], color[2]);
68 }
69
70 pub fn saved_color(&self, index: usize) -> [u8; 3] {
77 if index > 15 {
78 panic!("{:?} is outside the dialog saved color bounds", index);
79 }
80 let v = self.data.borrow().custom_colors[index];
81 [GetRValue(v), GetGValue(v), GetBValue(v)]
82 }
83}
84
85pub struct ColorDialogBuilder {
87 default_colors: [COLORREF; 16],
88}
89
90impl ColorDialogBuilder {
91 pub fn saved_color(mut self, index: usize, color: &[u8; 3]) -> ColorDialogBuilder {
92 self.default_colors[index] = RGB(color[0], color[1], color[2]);
93 self
94 }
95
96 pub fn build(self, out: &mut ColorDialog) -> Result<(), NwgError> {
97 *out.data.borrow_mut().custom_colors.as_mut() = self.default_colors;
98 Ok(())
99 }
100}
101
102impl Default for ColorDialog {
103 fn default() -> ColorDialog {
104 let dialog = CHOOSECOLORW {
105 lStructSize: mem::size_of::<CHOOSECOLORW>() as DWORD,
106 hwndOwner: ptr::null_mut(),
107 hInstance: ptr::null_mut(),
108 rgbResult: 0,
109 lpCustColors: ptr::null_mut(),
110 Flags: CC_RGBINIT,
111 lCustData: 0,
112 lpfnHook: None,
113 lpTemplateName: ptr::null(),
114 };
115
116 let mut inner = InnerColorDialog {
117 custom_colors: Box::pin(Default::default()),
118 dialog,
119 };
120
121 let mut cols = inner.custom_colors.as_mut();
122 let cols_ref: &mut [COLORREF; 16] = &mut cols;
123 inner.dialog.lpCustColors = cols_ref as *mut [COLORREF; 16] as *mut COLORREF;
124
125 ColorDialog {
126 data: RefCell::new(inner),
127 }
128 }
129}