1use crate::{ffi, Window};
6use glib::{
7 prelude::*,
8 signal::{connect_raw, SignalHandlerId},
9 translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14 #[doc(alias = "GtkColorDialog")]
51 pub struct ColorDialog(Object<ffi::GtkColorDialog, ffi::GtkColorDialogClass>);
52
53 match fn {
54 type_ => || ffi::gtk_color_dialog_get_type(),
55 }
56}
57
58impl ColorDialog {
59 #[doc(alias = "gtk_color_dialog_new")]
65 pub fn new() -> ColorDialog {
66 assert_initialized_main_thread!();
67 unsafe { from_glib_full(ffi::gtk_color_dialog_new()) }
68 }
69
70 pub fn builder() -> ColorDialogBuilder {
75 ColorDialogBuilder::new()
76 }
77
78 #[doc(alias = "gtk_color_dialog_choose_rgba")]
89 pub fn choose_rgba<P: FnOnce(Result<gdk::RGBA, glib::Error>) + 'static>(
90 &self,
91 parent: Option<&impl IsA<Window>>,
92 initial_color: Option<&gdk::RGBA>,
93 cancellable: Option<&impl IsA<gio::Cancellable>>,
94 callback: P,
95 ) {
96 let main_context = glib::MainContext::ref_thread_default();
97 let is_main_context_owner = main_context.is_owner();
98 let has_acquired_main_context = (!is_main_context_owner)
99 .then(|| main_context.acquire().ok())
100 .flatten();
101 assert!(
102 is_main_context_owner || has_acquired_main_context.is_some(),
103 "Async operations only allowed if the thread is owning the MainContext"
104 );
105
106 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
107 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
108 unsafe extern "C" fn choose_rgba_trampoline<
109 P: FnOnce(Result<gdk::RGBA, glib::Error>) + 'static,
110 >(
111 _source_object: *mut glib::gobject_ffi::GObject,
112 res: *mut gio::ffi::GAsyncResult,
113 user_data: glib::ffi::gpointer,
114 ) {
115 let mut error = std::ptr::null_mut();
116 let ret =
117 ffi::gtk_color_dialog_choose_rgba_finish(_source_object as *mut _, res, &mut error);
118 let result = if error.is_null() {
119 Ok(from_glib_full(ret))
120 } else {
121 Err(from_glib_full(error))
122 };
123 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
124 Box_::from_raw(user_data as *mut _);
125 let callback: P = callback.into_inner();
126 callback(result);
127 }
128 let callback = choose_rgba_trampoline::<P>;
129 unsafe {
130 ffi::gtk_color_dialog_choose_rgba(
131 self.to_glib_none().0,
132 parent.map(|p| p.as_ref()).to_glib_none().0,
133 initial_color.to_glib_none().0,
134 cancellable.map(|p| p.as_ref()).to_glib_none().0,
135 Some(callback),
136 Box_::into_raw(user_data) as *mut _,
137 );
138 }
139 }
140
141 pub fn choose_rgba_future(
142 &self,
143 parent: Option<&(impl IsA<Window> + Clone + 'static)>,
144 initial_color: Option<&gdk::RGBA>,
145 ) -> Pin<Box_<dyn std::future::Future<Output = Result<gdk::RGBA, glib::Error>> + 'static>> {
146 let parent = parent.map(ToOwned::to_owned);
147 let initial_color = initial_color.map(ToOwned::to_owned);
148 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
149 obj.choose_rgba(
150 parent.as_ref().map(::std::borrow::Borrow::borrow),
151 initial_color.as_ref().map(::std::borrow::Borrow::borrow),
152 Some(cancellable),
153 move |res| {
154 send.resolve(res);
155 },
156 );
157 }))
158 }
159
160 #[doc(alias = "gtk_color_dialog_get_modal")]
168 #[doc(alias = "get_modal")]
169 #[doc(alias = "modal")]
170 pub fn is_modal(&self) -> bool {
171 unsafe { from_glib(ffi::gtk_color_dialog_get_modal(self.to_glib_none().0)) }
172 }
173
174 #[doc(alias = "gtk_color_dialog_get_title")]
181 #[doc(alias = "get_title")]
182 pub fn title(&self) -> glib::GString {
183 unsafe { from_glib_none(ffi::gtk_color_dialog_get_title(self.to_glib_none().0)) }
184 }
185
186 #[doc(alias = "gtk_color_dialog_get_with_alpha")]
192 #[doc(alias = "get_with_alpha")]
193 #[doc(alias = "with-alpha")]
194 pub fn is_with_alpha(&self) -> bool {
195 unsafe { from_glib(ffi::gtk_color_dialog_get_with_alpha(self.to_glib_none().0)) }
196 }
197
198 #[doc(alias = "gtk_color_dialog_set_modal")]
204 #[doc(alias = "modal")]
205 pub fn set_modal(&self, modal: bool) {
206 unsafe {
207 ffi::gtk_color_dialog_set_modal(self.to_glib_none().0, modal.into_glib());
208 }
209 }
210
211 #[doc(alias = "gtk_color_dialog_set_title")]
216 #[doc(alias = "title")]
217 pub fn set_title(&self, title: &str) {
218 unsafe {
219 ffi::gtk_color_dialog_set_title(self.to_glib_none().0, title.to_glib_none().0);
220 }
221 }
222
223 #[doc(alias = "gtk_color_dialog_set_with_alpha")]
227 #[doc(alias = "with-alpha")]
228 pub fn set_with_alpha(&self, with_alpha: bool) {
229 unsafe {
230 ffi::gtk_color_dialog_set_with_alpha(self.to_glib_none().0, with_alpha.into_glib());
231 }
232 }
233
234 #[cfg(feature = "v4_10")]
235 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
236 #[doc(alias = "modal")]
237 pub fn connect_modal_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
238 unsafe extern "C" fn notify_modal_trampoline<F: Fn(&ColorDialog) + 'static>(
239 this: *mut ffi::GtkColorDialog,
240 _param_spec: glib::ffi::gpointer,
241 f: glib::ffi::gpointer,
242 ) {
243 let f: &F = &*(f as *const F);
244 f(&from_glib_borrow(this))
245 }
246 unsafe {
247 let f: Box_<F> = Box_::new(f);
248 connect_raw(
249 self.as_ptr() as *mut _,
250 b"notify::modal\0".as_ptr() as *const _,
251 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
252 notify_modal_trampoline::<F> as *const (),
253 )),
254 Box_::into_raw(f),
255 )
256 }
257 }
258
259 #[cfg(feature = "v4_10")]
260 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
261 #[doc(alias = "title")]
262 pub fn connect_title_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
263 unsafe extern "C" fn notify_title_trampoline<F: Fn(&ColorDialog) + 'static>(
264 this: *mut ffi::GtkColorDialog,
265 _param_spec: glib::ffi::gpointer,
266 f: glib::ffi::gpointer,
267 ) {
268 let f: &F = &*(f as *const F);
269 f(&from_glib_borrow(this))
270 }
271 unsafe {
272 let f: Box_<F> = Box_::new(f);
273 connect_raw(
274 self.as_ptr() as *mut _,
275 b"notify::title\0".as_ptr() as *const _,
276 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
277 notify_title_trampoline::<F> as *const (),
278 )),
279 Box_::into_raw(f),
280 )
281 }
282 }
283
284 #[cfg(feature = "v4_10")]
285 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
286 #[doc(alias = "with-alpha")]
287 pub fn connect_with_alpha_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
288 unsafe extern "C" fn notify_with_alpha_trampoline<F: Fn(&ColorDialog) + 'static>(
289 this: *mut ffi::GtkColorDialog,
290 _param_spec: glib::ffi::gpointer,
291 f: glib::ffi::gpointer,
292 ) {
293 let f: &F = &*(f as *const F);
294 f(&from_glib_borrow(this))
295 }
296 unsafe {
297 let f: Box_<F> = Box_::new(f);
298 connect_raw(
299 self.as_ptr() as *mut _,
300 b"notify::with-alpha\0".as_ptr() as *const _,
301 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
302 notify_with_alpha_trampoline::<F> as *const (),
303 )),
304 Box_::into_raw(f),
305 )
306 }
307 }
308}
309
310#[cfg(feature = "v4_10")]
311#[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
312impl Default for ColorDialog {
313 fn default() -> Self {
314 Self::new()
315 }
316}
317
318#[must_use = "The builder must be built to be used"]
323pub struct ColorDialogBuilder {
324 builder: glib::object::ObjectBuilder<'static, ColorDialog>,
325}
326
327impl ColorDialogBuilder {
328 fn new() -> Self {
329 Self {
330 builder: glib::object::Object::builder(),
331 }
332 }
333
334 #[cfg(feature = "v4_10")]
336 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
337 pub fn modal(self, modal: bool) -> Self {
338 Self {
339 builder: self.builder.property("modal", modal),
340 }
341 }
342
343 #[cfg(feature = "v4_10")]
345 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
346 pub fn title(self, title: impl Into<glib::GString>) -> Self {
347 Self {
348 builder: self.builder.property("title", title.into()),
349 }
350 }
351
352 #[cfg(feature = "v4_10")]
357 #[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
358 pub fn with_alpha(self, with_alpha: bool) -> Self {
359 Self {
360 builder: self.builder.property("with-alpha", with_alpha),
361 }
362 }
363
364 #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
367 pub fn build(self) -> ColorDialog {
368 assert_initialized_main_thread!();
369 self.builder.build()
370 }
371}