77#[ cfg( any( dialog_open, dialog_save) ) ]
88use std:: path:: { Path , PathBuf } ;
99
10+ use crate :: { Runtime , Window } ;
11+
1012#[ cfg( not( target_os = "linux" ) ) ]
1113macro_rules! run_dialog {
1214 ( $e: expr, $h: ident) => { {
@@ -30,6 +32,48 @@ macro_rules! run_dialog {
3032 } } ;
3133}
3234
35+ /// Window parent definition.
36+ #[ cfg( any( windows, target_os = "macos" ) ) ]
37+ #[ cfg_attr( doc_cfg, doc( cfg( any( windows, target_os = "macos" ) ) ) ) ]
38+ pub struct WindowParent {
39+ #[ cfg( windows) ]
40+ hwnd : * mut std:: ffi:: c_void ,
41+ #[ cfg( target_os = "macos" ) ]
42+ ns_window : * mut std:: ffi:: c_void ,
43+ }
44+
45+ #[ cfg( any( windows, target_os = "macos" ) ) ]
46+ unsafe impl raw_window_handle:: HasRawWindowHandle for WindowParent {
47+ #[ cfg( windows) ]
48+ fn raw_window_handle ( & self ) -> raw_window_handle:: RawWindowHandle {
49+ let mut handle = raw_window_handle:: windows:: WindowsHandle :: empty ( ) ;
50+ handle. hwnd = self . hwnd ;
51+ raw_window_handle:: RawWindowHandle :: Windows ( handle)
52+ }
53+
54+ #[ cfg( target_os = "macos" ) ]
55+ fn raw_window_handle ( & self ) -> raw_window_handle:: RawWindowHandle {
56+ let mut handle = raw_window_handle:: macos:: MacOSHandle :: empty ( ) ;
57+ handle. ns_window = self . ns_window ;
58+ raw_window_handle:: RawWindowHandle :: MacOS ( handle)
59+ }
60+ }
61+
62+ #[ cfg( any( windows, target_os = "macos" ) ) ]
63+ #[ cfg_attr( doc_cfg, doc( cfg( any( windows, target_os = "macos" ) ) ) ) ]
64+ #[ doc( hidden) ]
65+ pub fn window_parent < R : Runtime > ( window : & Window < R > ) -> crate :: Result < WindowParent > {
66+ #[ cfg( windows) ]
67+ let w = WindowParent {
68+ hwnd : window. hwnd ( ) ?,
69+ } ;
70+ #[ cfg( target_os = "macos" ) ]
71+ let w = WindowParent {
72+ ns_window : window. ns_window ( ) ?,
73+ } ;
74+ Ok ( w)
75+ }
76+
3377/// The file dialog builder.
3478///
3579/// Constructs file picker dialogs that can select single/multiple files or directories.
@@ -62,7 +106,6 @@ impl FileDialogBuilder {
62106 self
63107 }
64108
65- #[ cfg( windows) ]
66109 /// Sets the parent window of the dialog.
67110 pub fn set_parent < W : raw_window_handle:: HasRawWindowHandle > ( mut self , parent : & W ) -> Self {
68111 self . 0 = self . 0 . set_parent ( parent) ;
@@ -91,36 +134,60 @@ impl FileDialogBuilder {
91134}
92135
93136/// Displays a dialog with a message and an optional title with a "yes" and a "no" button.
94- pub fn ask < F : FnOnce ( bool ) + Send + ' static > (
137+ #[ allow( unused_variables) ]
138+ pub fn ask < R : Runtime , F : FnOnce ( bool ) + Send + ' static > (
139+ parent_window : Option < & Window < R > > ,
95140 title : impl AsRef < str > ,
96141 message : impl AsRef < str > ,
97142 f : F ,
98143) {
99144 let title = title. as_ref ( ) . to_string ( ) ;
100145 let message = message. as_ref ( ) . to_string ( ) ;
101- run_dialog ! (
102- rfd:: MessageDialog :: new( )
103- . set_title( & title)
104- . set_description( & message)
105- . set_buttons( rfd:: MessageButtons :: YesNo )
106- . set_level( rfd:: MessageLevel :: Info )
107- . show( ) ,
108- f
109- )
146+ #[ allow( unused_mut) ]
147+ let mut builder = rfd:: MessageDialog :: new ( )
148+ . set_title ( & title)
149+ . set_description ( & message)
150+ . set_buttons ( rfd:: MessageButtons :: YesNo )
151+ . set_level ( rfd:: MessageLevel :: Info ) ;
152+
153+ #[ cfg( any( windows, target_os = "macos" ) ) ]
154+ {
155+ if let Some ( window) = parent_window {
156+ if let Ok ( parent) = window_parent ( window) {
157+ builder = builder. set_parent ( & parent) ;
158+ }
159+ }
160+ }
161+
162+ run_dialog ! ( builder. show( ) , f)
110163}
111164
112165/// Displays a message dialog.
113- pub fn message ( title : impl AsRef < str > , message : impl AsRef < str > ) {
166+ #[ allow( unused_variables) ]
167+ pub fn message < R : Runtime > (
168+ parent_window : Option < & Window < R > > ,
169+ title : impl AsRef < str > ,
170+ message : impl AsRef < str > ,
171+ ) {
114172 let title = title. as_ref ( ) . to_string ( ) ;
115173 let message = message. as_ref ( ) . to_string ( ) ;
116174 let cb = |_| { } ;
117- run_dialog ! (
118- rfd:: MessageDialog :: new( )
119- . set_title( & title)
120- . set_description( & message)
121- . set_buttons( rfd:: MessageButtons :: Ok )
122- . set_level( rfd:: MessageLevel :: Info )
123- . show( ) ,
124- cb
125- )
175+
176+ #[ allow( unused_mut) ]
177+ let mut builder = rfd:: MessageDialog :: new ( )
178+ . set_title ( & title)
179+ . set_description ( & message)
180+ . set_buttons ( rfd:: MessageButtons :: Ok )
181+ . set_level ( rfd:: MessageLevel :: Info ) ;
182+
183+ #[ cfg( any( windows, target_os = "macos" ) ) ]
184+ {
185+ if let Some ( window) = parent_window {
186+ if let Ok ( parent) = window_parent ( window) {
187+ builder = builder. set_parent ( & parent) ;
188+ }
189+ }
190+ }
191+
192+ run_dialog ! ( builder. show( ) , cb)
126193}
0 commit comments