native_windows_gui2/resources/
font_dialog.rs1use super::FontInfo;
2use crate::NwgError;
3use crate::controls::ControlHandle;
4use std::cell::RefCell;
5use std::pin::Pin;
6use std::{mem, ptr};
7use winapi::shared::minwindef::DWORD;
8use winapi::um::commdlg::{CHOOSEFONTW, ChooseFontW};
9use winapi::um::wingdi::LOGFONTW;
10
11struct InnerFontDialog {
12 font: Pin<Box<LOGFONTW>>,
13 dialog: CHOOSEFONTW,
14}
15
16pub struct FontDialog {
20 data: RefCell<InnerFontDialog>,
21}
22
23impl FontDialog {
24 pub fn builder() -> FontDialogBuilder {
25 FontDialogBuilder {}
26 }
27
28 pub fn run<C: Into<ControlHandle>>(&self, owner: Option<C>) -> bool {
31 if owner.is_some() {
32 let ownder_handle = owner.unwrap().into();
33 self.data.borrow_mut().dialog.hwndOwner = ownder_handle
34 .hwnd()
35 .expect("Color dialog must be a window control");
36 }
37
38 unsafe {
39 let mut data = self.data.borrow_mut();
40 let data_ref = &mut data.dialog;
41 ChooseFontW(data_ref as *mut CHOOSEFONTW) > 0
42 }
43 }
44
45 pub fn font(&self) -> FontInfo {
47 let data: &InnerFontDialog = &self.data.borrow();
48 let font: &LOGFONTW = &data.font;
49
50 let end = font.lfFaceName.iter().position(|&c| c == 0).unwrap_or(0);
51 let name = String::from_utf16(&font.lfFaceName[0..end]).unwrap_or("ERROR".to_string());
52
53 FontInfo {
54 point_size: data.dialog.iPointSize as u32,
55 height: font.lfHeight as i32,
56 width: font.lfWidth as i32,
57 escapement: font.lfEscapement as i32,
58 orientation: font.lfOrientation as i32,
59 weight: font.lfWeight as i32,
60 italic: font.lfItalic == 1,
61 underline: font.lfUnderline == 1,
62 strike_out: font.lfStrikeOut == 1,
63 char_set: font.lfCharSet as u8,
64 out_precision: font.lfOutPrecision as u8,
65 clip_precision: font.lfClipPrecision as u8,
66 quality: font.lfQuality as u8,
67 pitch_and_family: font.lfPitchAndFamily as u8,
68 name,
69 }
70 }
71}
72
73pub struct FontDialogBuilder {}
75
76impl FontDialogBuilder {
77 pub fn build(self, _out: &mut FontDialog) -> Result<(), NwgError> {
78 Ok(())
79 }
80}
81
82impl Default for FontDialog {
83 fn default() -> FontDialog {
84 let dialog = CHOOSEFONTW {
85 lStructSize: mem::size_of::<CHOOSEFONTW>() as DWORD,
86 hwndOwner: ptr::null_mut(),
87 hDC: ptr::null_mut(),
88 lpLogFont: ptr::null_mut(),
89 iPointSize: 0,
90 Flags: 0,
91 rgbColors: 0,
92 lCustData: 0,
93 lpfnHook: None,
94 lpTemplateName: ptr::null(),
95 hInstance: ptr::null_mut(),
96 lpszStyle: ptr::null_mut(),
97 nFontType: 0,
98 ___MISSING_ALIGNMENT__: 0,
99 nSizeMin: 0,
100 nSizeMax: 0,
101 };
102
103 let font: LOGFONTW = unsafe { mem::zeroed() };
104
105 let mut inner = InnerFontDialog {
106 font: Box::pin(font),
107 dialog,
108 };
109
110 let mut font = inner.font.as_mut();
111 let cols_ref: &mut LOGFONTW = &mut font;
112 inner.dialog.lpLogFont = cols_ref as *mut LOGFONTW;
113
114 FontDialog {
115 data: RefCell::new(inner),
116 }
117 }
118}