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