1use std::fmt::Display;
20use std::str::FromStr;
21
22use crate::{
23 ErrorKind,
24 errors::FormError,
25 files::common::Properties,
26 language::{
27 Color, VB_BUTTON_FACE, VB_BUTTON_TEXT,
28 controls::{
29 Activation, Appearance, CausesValidation, DragMode, Font, JustifyAlignment,
30 MousePointer, OLEDropMode, ReferenceOrValue, Style, TabStop, TextDirection,
31 UseMaskColor, Visibility,
32 },
33 },
34};
35
36use image::DynamicImage;
37use num_enum::TryFromPrimitive;
38use serde::Serialize;
39
40#[derive(
45 Debug, PartialEq, Eq, Clone, Serialize, TryFromPrimitive, Default, Copy, Hash, PartialOrd, Ord,
46)]
47#[repr(i32)]
48pub enum CheckBoxValue {
49 #[default]
53 Unchecked = 0,
54 Checked = 1,
56 Grayed = 2,
58}
59
60impl Display for CheckBoxValue {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 let text = match self {
63 CheckBoxValue::Unchecked => "Unchecked",
64 CheckBoxValue::Checked => "Checked",
65 CheckBoxValue::Grayed => "Grayed",
66 };
67 write!(f, "{text}")
68 }
69}
70
71impl FromStr for CheckBoxValue {
72 type Err = ErrorKind;
73
74 fn from_str(s: &str) -> Result<Self, Self::Err> {
75 match s {
76 "0" | "Unchecked" => Ok(CheckBoxValue::Unchecked),
77 "1" | "Checked" => Ok(CheckBoxValue::Checked),
78 "2" | "Grayed" => Ok(CheckBoxValue::Grayed),
79 _ => Err(ErrorKind::Form(FormError::InvalidCheckBoxValue {
80 value: s.to_string(),
81 })),
82 }
83 }
84}
85
86impl TryFrom<&str> for CheckBoxValue {
87 type Error = ErrorKind;
88
89 fn try_from(value: &str) -> Result<Self, Self::Error> {
90 CheckBoxValue::from_str(value)
91 }
92}
93
94#[derive(Debug, PartialEq, Clone)]
101pub struct CheckBoxProperties {
102 pub alignment: JustifyAlignment,
104 pub appearance: Appearance,
106 pub back_color: Color,
108 pub caption: String,
110 pub causes_validation: CausesValidation,
112 pub data_field: String,
114 pub data_format: String,
116 pub data_member: String,
118 pub data_source: String,
120 pub disabled_picture: Option<ReferenceOrValue<DynamicImage>>,
122 pub down_picture: Option<ReferenceOrValue<DynamicImage>>,
124 pub drag_icon: Option<ReferenceOrValue<DynamicImage>>,
126 pub drag_mode: DragMode,
128 pub enabled: Activation,
130 pub font: Option<Font>,
132 pub fore_color: Color,
134 pub height: i32,
136 pub help_context_id: i32,
138 pub left: i32,
140 pub mask_color: Color,
142 pub mouse_icon: Option<ReferenceOrValue<DynamicImage>>,
144 pub mouse_pointer: MousePointer,
146 pub ole_drop_mode: OLEDropMode,
148 pub picture: Option<ReferenceOrValue<DynamicImage>>,
150 pub right_to_left: TextDirection,
152 pub style: Style,
154 pub tab_index: i32,
156 pub tab_stop: TabStop,
158 pub tool_tip_text: String,
160 pub top: i32,
162 pub use_mask_color: UseMaskColor,
164 pub value: CheckBoxValue,
166 pub visible: Visibility,
168 pub whats_this_help_id: i32,
170 pub width: i32,
172}
173
174impl Default for CheckBoxProperties {
175 fn default() -> Self {
176 CheckBoxProperties {
177 alignment: JustifyAlignment::LeftJustify,
178 appearance: Appearance::ThreeD,
179 back_color: VB_BUTTON_FACE,
180 caption: String::new(),
181 causes_validation: CausesValidation::Yes,
182 data_field: String::new(),
183 data_format: String::new(),
184 data_member: String::new(),
185 data_source: String::new(),
186 disabled_picture: None,
187 down_picture: None,
188 drag_icon: None,
189 drag_mode: DragMode::Manual,
190 enabled: Activation::Enabled,
191 font: Some(Font::default()),
192 fore_color: VB_BUTTON_TEXT,
193 height: 30,
194 help_context_id: 0,
195 left: 30,
196 mask_color: Color::new(0xC0, 0xC0, 0xC0),
197 mouse_icon: None,
198 mouse_pointer: MousePointer::Default,
199 ole_drop_mode: OLEDropMode::default(),
200 picture: None,
201 right_to_left: TextDirection::LeftToRight,
202 style: Style::Standard,
203 tab_index: 0,
204 tab_stop: TabStop::Included,
205 tool_tip_text: String::new(),
206 top: 30,
207 use_mask_color: UseMaskColor::DoNotUseMaskColor,
208 value: CheckBoxValue::Unchecked,
209 visible: Visibility::Visible,
210 whats_this_help_id: 0,
211 width: 100,
212 }
213 }
214}
215
216impl Serialize for CheckBoxProperties {
217 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
218 where
219 S: serde::ser::Serializer,
220 {
221 use serde::ser::SerializeStruct;
222
223 let mut state = serializer.serialize_struct("CheckBoxProperties", 29)?;
224 state.serialize_field("alignment", &self.alignment)?;
225 state.serialize_field("appearance", &self.appearance)?;
226 state.serialize_field("back_color", &self.back_color)?;
227 state.serialize_field("caption", &self.caption)?;
228 state.serialize_field("causes_validation", &self.causes_validation)?;
229 state.serialize_field("data_field", &self.data_field)?;
230 state.serialize_field("data_format", &self.data_format)?;
231 state.serialize_field("data_member", &self.data_member)?;
232 state.serialize_field("data_source", &self.data_source)?;
233
234 let option_text = self.disabled_picture.as_ref().map(|_| "Some(DynamicImage)");
235
236 state.serialize_field("disabled_picture", &option_text)?;
237
238 let option_text = self.down_picture.as_ref().map(|_| "Some(DynamicImage)");
239
240 state.serialize_field("down_picture", &option_text)?;
241
242 let option_text = self.drag_icon.as_ref().map(|_| "Some(DynamicImage)");
243
244 state.serialize_field("drag_icon", &option_text)?;
245 state.serialize_field("drag_mode", &self.drag_mode)?;
246 state.serialize_field("enabled", &self.enabled)?;
247 state.serialize_field("fore_color", &self.fore_color)?;
248 state.serialize_field("height", &self.height)?;
249 state.serialize_field("help_context_id", &self.help_context_id)?;
250 state.serialize_field("left", &self.left)?;
251 state.serialize_field("mask_color", &self.mask_color)?;
252
253 let option_text = self.mouse_icon.as_ref().map(|_| "Some(DynamicImage)");
254
255 state.serialize_field("mouse_icon", &option_text)?;
256 state.serialize_field("mouse_pointer", &self.mouse_pointer)?;
257 state.serialize_field("ole_drop_mode", &self.ole_drop_mode)?;
258
259 let option_text = self.picture.as_ref().map(|_| "Some(DynamicImage)");
260
261 state.serialize_field("picture", &option_text)?;
262 state.serialize_field("right_to_left", &self.right_to_left)?;
263 state.serialize_field("style", &self.style)?;
264 state.serialize_field("tab_index", &self.tab_index)?;
265 state.serialize_field("tab_stop", &self.tab_stop)?;
266 state.serialize_field("tool_tip_text", &self.tool_tip_text)?;
267 state.serialize_field("top", &self.top)?;
268 state.serialize_field("use_mask_color", &self.use_mask_color)?;
269 state.serialize_field("value", &self.value)?;
270 state.serialize_field("visible", &self.visible)?;
271 state.serialize_field("whats_this_help_id", &self.whats_this_help_id)?;
272 state.serialize_field("width", &self.width)?;
273
274 state.end()
275 }
276}
277
278impl From<Properties> for CheckBoxProperties {
279 fn from(prop: Properties) -> Self {
280 let mut checkbox_prop = CheckBoxProperties::default();
281
282 checkbox_prop.alignment = prop.get_property("Alignment", checkbox_prop.alignment);
283 checkbox_prop.appearance = prop.get_property("Appearance", checkbox_prop.appearance);
284 checkbox_prop.back_color = prop.get_color("BackColor", checkbox_prop.back_color);
285 checkbox_prop.caption = match prop.get("Caption") {
286 Some(caption) => caption.into(),
287 None => checkbox_prop.caption,
288 };
289 checkbox_prop.causes_validation =
290 prop.get_property("CausesValidation", checkbox_prop.causes_validation);
291 checkbox_prop.data_field = match prop.get("DataField") {
292 Some(data_field) => data_field.into(),
293 None => checkbox_prop.data_field,
294 };
295 checkbox_prop.data_format = match prop.get("DataFormat") {
296 Some(data_format) => data_format.into(),
297 None => checkbox_prop.data_format,
298 };
299 checkbox_prop.data_member = match prop.get("DataMember") {
300 Some(data_member) => data_member.into(),
301 None => checkbox_prop.data_member,
302 };
303 checkbox_prop.data_source = match prop.get("DataSource") {
304 Some(data_source) => data_source.into(),
305 None => checkbox_prop.data_source,
306 };
307 checkbox_prop.drag_mode = prop.get_property("DragMode", checkbox_prop.drag_mode);
312 checkbox_prop.enabled = prop.get_property("Enabled", checkbox_prop.enabled);
313 checkbox_prop.fore_color = prop.get_color("ForeColor", checkbox_prop.fore_color);
314 checkbox_prop.height = prop.get_i32("Height", checkbox_prop.height);
315 checkbox_prop.help_context_id =
316 prop.get_i32("HelpContextID", checkbox_prop.help_context_id);
317 checkbox_prop.left = prop.get_i32("Left", checkbox_prop.left);
318 checkbox_prop.mask_color = prop.get_color("MaskColor", checkbox_prop.mask_color);
319
320 checkbox_prop.mouse_pointer =
323 prop.get_property("MousePointer", checkbox_prop.mouse_pointer);
324 checkbox_prop.ole_drop_mode = prop.get_property("OLEDropMode", checkbox_prop.ole_drop_mode);
325
326 checkbox_prop.right_to_left = prop.get_property("RightToLeft", checkbox_prop.right_to_left);
329 checkbox_prop.style = prop.get_property("Style", checkbox_prop.style);
330 checkbox_prop.tab_index = prop.get_i32("TabIndex", checkbox_prop.tab_index);
331 checkbox_prop.tab_stop = prop.get_property("TabStop", checkbox_prop.tab_stop);
332 checkbox_prop.tool_tip_text = match prop.get("ToolTipText") {
333 Some(tool_tip_text) => tool_tip_text.into(),
334 None => checkbox_prop.tool_tip_text,
335 };
336 checkbox_prop.top = prop.get_i32("Top", checkbox_prop.top);
337 checkbox_prop.use_mask_color =
338 prop.get_property("UseMaskColor", checkbox_prop.use_mask_color);
339 checkbox_prop.value = prop.get_property("Value", checkbox_prop.value);
340 checkbox_prop.visible = prop.get_property("Visible", checkbox_prop.visible);
341 checkbox_prop.whats_this_help_id =
342 prop.get_i32("WhatsThisHelp", checkbox_prop.whats_this_help_id);
343 checkbox_prop.width = prop.get_i32("Width", checkbox_prop.width);
344
345 checkbox_prop
346 }
347}