1#[cfg(feature = "v4_10")]
6#[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
7use crate::Accessible;
8use crate::{
9 AccessibleRole, Actionable, Align, Buildable, ConstraintTarget, LayoutManager, Overflow,
10 Widget, ffi,
11};
12use glib::{
13 object::ObjectType as _,
14 prelude::*,
15 signal::{SignalHandlerId, connect_raw},
16 translate::*,
17};
18use std::boxed::Box as Box_;
19
20#[cfg(feature = "v4_10")]
21#[cfg_attr(docsrs, doc(cfg(feature = "v4_10")))]
22glib::wrapper! {
23 #[doc(alias = "GtkButton")]
24 pub struct Button(Object<ffi::GtkButton, ffi::GtkButtonClass>) @extends Widget, @implements Accessible, Buildable, ConstraintTarget, Actionable;
25
26 match fn {
27 type_ => || ffi::gtk_button_get_type(),
28 }
29}
30
31#[cfg(not(feature = "v4_10"))]
32glib::wrapper! {
33 #[doc(alias = "GtkButton")]
34 pub struct Button(Object<ffi::GtkButton, ffi::GtkButtonClass>) @extends Widget, @implements Buildable, ConstraintTarget, Actionable;
35
36 match fn {
37 type_ => || ffi::gtk_button_get_type(),
38 }
39}
40
41impl Button {
42 pub const NONE: Option<&'static Button> = None;
43
44 #[doc(alias = "gtk_button_new")]
45 pub fn new() -> Button {
46 assert_initialized_main_thread!();
47 unsafe { Widget::from_glib_none(ffi::gtk_button_new()).unsafe_cast() }
48 }
49
50 #[doc(alias = "gtk_button_new_from_icon_name")]
51 #[doc(alias = "new_from_icon_name")]
52 pub fn from_icon_name(icon_name: &str) -> Button {
53 assert_initialized_main_thread!();
54 unsafe {
55 Widget::from_glib_none(ffi::gtk_button_new_from_icon_name(
56 icon_name.to_glib_none().0,
57 ))
58 .unsafe_cast()
59 }
60 }
61
62 #[doc(alias = "gtk_button_new_with_label")]
63 #[doc(alias = "new_with_label")]
64 pub fn with_label(label: &str) -> Button {
65 assert_initialized_main_thread!();
66 unsafe {
67 Widget::from_glib_none(ffi::gtk_button_new_with_label(label.to_glib_none().0))
68 .unsafe_cast()
69 }
70 }
71
72 #[doc(alias = "gtk_button_new_with_mnemonic")]
73 #[doc(alias = "new_with_mnemonic")]
74 pub fn with_mnemonic(label: &str) -> Button {
75 assert_initialized_main_thread!();
76 unsafe {
77 Widget::from_glib_none(ffi::gtk_button_new_with_mnemonic(label.to_glib_none().0))
78 .unsafe_cast()
79 }
80 }
81
82 pub fn builder() -> ButtonBuilder {
87 ButtonBuilder::new()
88 }
89}
90
91impl Default for Button {
92 fn default() -> Self {
93 Self::new()
94 }
95}
96
97#[must_use = "The builder must be built to be used"]
102pub struct ButtonBuilder {
103 builder: glib::object::ObjectBuilder<'static, Button>,
104}
105
106impl ButtonBuilder {
107 fn new() -> Self {
108 Self {
109 builder: glib::object::Object::builder(),
110 }
111 }
112
113 #[cfg(feature = "v4_12")]
114 #[cfg_attr(docsrs, doc(cfg(feature = "v4_12")))]
115 pub fn can_shrink(self, can_shrink: bool) -> Self {
116 Self {
117 builder: self.builder.property("can-shrink", can_shrink),
118 }
119 }
120
121 pub fn child(self, child: &impl IsA<Widget>) -> Self {
122 Self {
123 builder: self.builder.property("child", child.clone().upcast()),
124 }
125 }
126
127 pub fn has_frame(self, has_frame: bool) -> Self {
128 Self {
129 builder: self.builder.property("has-frame", has_frame),
130 }
131 }
132
133 pub fn icon_name(self, icon_name: impl Into<glib::GString>) -> Self {
134 Self {
135 builder: self.builder.property("icon-name", icon_name.into()),
136 }
137 }
138
139 pub fn label(self, label: impl Into<glib::GString>) -> Self {
140 Self {
141 builder: self.builder.property("label", label.into()),
142 }
143 }
144
145 pub fn use_underline(self, use_underline: bool) -> Self {
146 Self {
147 builder: self.builder.property("use-underline", use_underline),
148 }
149 }
150
151 pub fn can_focus(self, can_focus: bool) -> Self {
152 Self {
153 builder: self.builder.property("can-focus", can_focus),
154 }
155 }
156
157 pub fn can_target(self, can_target: bool) -> Self {
158 Self {
159 builder: self.builder.property("can-target", can_target),
160 }
161 }
162
163 pub fn css_classes(self, css_classes: impl Into<glib::StrV>) -> Self {
164 Self {
165 builder: self.builder.property("css-classes", css_classes.into()),
166 }
167 }
168
169 pub fn css_name(self, css_name: impl Into<glib::GString>) -> Self {
170 Self {
171 builder: self.builder.property("css-name", css_name.into()),
172 }
173 }
174
175 pub fn cursor(self, cursor: &gdk::Cursor) -> Self {
176 Self {
177 builder: self.builder.property("cursor", cursor.clone()),
178 }
179 }
180
181 pub fn focus_on_click(self, focus_on_click: bool) -> Self {
182 Self {
183 builder: self.builder.property("focus-on-click", focus_on_click),
184 }
185 }
186
187 pub fn focusable(self, focusable: bool) -> Self {
188 Self {
189 builder: self.builder.property("focusable", focusable),
190 }
191 }
192
193 pub fn halign(self, halign: Align) -> Self {
194 Self {
195 builder: self.builder.property("halign", halign),
196 }
197 }
198
199 pub fn has_tooltip(self, has_tooltip: bool) -> Self {
200 Self {
201 builder: self.builder.property("has-tooltip", has_tooltip),
202 }
203 }
204
205 pub fn height_request(self, height_request: i32) -> Self {
206 Self {
207 builder: self.builder.property("height-request", height_request),
208 }
209 }
210
211 pub fn hexpand(self, hexpand: bool) -> Self {
212 Self {
213 builder: self.builder.property("hexpand", hexpand),
214 }
215 }
216
217 pub fn hexpand_set(self, hexpand_set: bool) -> Self {
218 Self {
219 builder: self.builder.property("hexpand-set", hexpand_set),
220 }
221 }
222
223 pub fn layout_manager(self, layout_manager: &impl IsA<LayoutManager>) -> Self {
224 Self {
225 builder: self
226 .builder
227 .property("layout-manager", layout_manager.clone().upcast()),
228 }
229 }
230
231 #[cfg(feature = "v4_18")]
232 #[cfg_attr(docsrs, doc(cfg(feature = "v4_18")))]
233 pub fn limit_events(self, limit_events: bool) -> Self {
234 Self {
235 builder: self.builder.property("limit-events", limit_events),
236 }
237 }
238
239 pub fn margin_bottom(self, margin_bottom: i32) -> Self {
240 Self {
241 builder: self.builder.property("margin-bottom", margin_bottom),
242 }
243 }
244
245 pub fn margin_end(self, margin_end: i32) -> Self {
246 Self {
247 builder: self.builder.property("margin-end", margin_end),
248 }
249 }
250
251 pub fn margin_start(self, margin_start: i32) -> Self {
252 Self {
253 builder: self.builder.property("margin-start", margin_start),
254 }
255 }
256
257 pub fn margin_top(self, margin_top: i32) -> Self {
258 Self {
259 builder: self.builder.property("margin-top", margin_top),
260 }
261 }
262
263 pub fn name(self, name: impl Into<glib::GString>) -> Self {
264 Self {
265 builder: self.builder.property("name", name.into()),
266 }
267 }
268
269 pub fn opacity(self, opacity: f64) -> Self {
270 Self {
271 builder: self.builder.property("opacity", opacity),
272 }
273 }
274
275 pub fn overflow(self, overflow: Overflow) -> Self {
276 Self {
277 builder: self.builder.property("overflow", overflow),
278 }
279 }
280
281 pub fn receives_default(self, receives_default: bool) -> Self {
282 Self {
283 builder: self.builder.property("receives-default", receives_default),
284 }
285 }
286
287 pub fn sensitive(self, sensitive: bool) -> Self {
288 Self {
289 builder: self.builder.property("sensitive", sensitive),
290 }
291 }
292
293 pub fn tooltip_markup(self, tooltip_markup: impl Into<glib::GString>) -> Self {
294 Self {
295 builder: self
296 .builder
297 .property("tooltip-markup", tooltip_markup.into()),
298 }
299 }
300
301 pub fn tooltip_text(self, tooltip_text: impl Into<glib::GString>) -> Self {
302 Self {
303 builder: self.builder.property("tooltip-text", tooltip_text.into()),
304 }
305 }
306
307 pub fn valign(self, valign: Align) -> Self {
308 Self {
309 builder: self.builder.property("valign", valign),
310 }
311 }
312
313 pub fn vexpand(self, vexpand: bool) -> Self {
314 Self {
315 builder: self.builder.property("vexpand", vexpand),
316 }
317 }
318
319 pub fn vexpand_set(self, vexpand_set: bool) -> Self {
320 Self {
321 builder: self.builder.property("vexpand-set", vexpand_set),
322 }
323 }
324
325 pub fn visible(self, visible: bool) -> Self {
326 Self {
327 builder: self.builder.property("visible", visible),
328 }
329 }
330
331 pub fn width_request(self, width_request: i32) -> Self {
332 Self {
333 builder: self.builder.property("width-request", width_request),
334 }
335 }
336
337 pub fn accessible_role(self, accessible_role: AccessibleRole) -> Self {
338 Self {
339 builder: self.builder.property("accessible-role", accessible_role),
340 }
341 }
342
343 pub fn action_name(self, action_name: impl Into<glib::GString>) -> Self {
344 Self {
345 builder: self.builder.property("action-name", action_name.into()),
346 }
347 }
348
349 pub fn action_target(self, action_target: &glib::Variant) -> Self {
350 Self {
351 builder: self
352 .builder
353 .property("action-target", action_target.clone()),
354 }
355 }
356
357 #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
360 pub fn build(self) -> Button {
361 assert_initialized_main_thread!();
362 self.builder.build()
363 }
364}
365
366pub trait ButtonExt: IsA<Button> + 'static {
367 #[cfg(feature = "v4_12")]
368 #[cfg_attr(docsrs, doc(cfg(feature = "v4_12")))]
369 #[doc(alias = "gtk_button_get_can_shrink")]
370 #[doc(alias = "get_can_shrink")]
371 #[doc(alias = "can-shrink")]
372 fn can_shrink(&self) -> bool {
373 unsafe {
374 from_glib(ffi::gtk_button_get_can_shrink(
375 self.as_ref().to_glib_none().0,
376 ))
377 }
378 }
379
380 #[doc(alias = "gtk_button_get_child")]
381 #[doc(alias = "get_child")]
382 fn child(&self) -> Option<Widget> {
383 unsafe { from_glib_none(ffi::gtk_button_get_child(self.as_ref().to_glib_none().0)) }
384 }
385
386 #[doc(alias = "gtk_button_get_has_frame")]
387 #[doc(alias = "get_has_frame")]
388 #[doc(alias = "has-frame")]
389 fn has_frame(&self) -> bool {
390 unsafe {
391 from_glib(ffi::gtk_button_get_has_frame(
392 self.as_ref().to_glib_none().0,
393 ))
394 }
395 }
396
397 #[doc(alias = "gtk_button_get_icon_name")]
398 #[doc(alias = "get_icon_name")]
399 #[doc(alias = "icon-name")]
400 fn icon_name(&self) -> Option<glib::GString> {
401 unsafe {
402 from_glib_none(ffi::gtk_button_get_icon_name(
403 self.as_ref().to_glib_none().0,
404 ))
405 }
406 }
407
408 #[doc(alias = "gtk_button_get_label")]
409 #[doc(alias = "get_label")]
410 fn label(&self) -> Option<glib::GString> {
411 unsafe { from_glib_none(ffi::gtk_button_get_label(self.as_ref().to_glib_none().0)) }
412 }
413
414 #[doc(alias = "gtk_button_get_use_underline")]
415 #[doc(alias = "get_use_underline")]
416 #[doc(alias = "use-underline")]
417 fn uses_underline(&self) -> bool {
418 unsafe {
419 from_glib(ffi::gtk_button_get_use_underline(
420 self.as_ref().to_glib_none().0,
421 ))
422 }
423 }
424
425 #[cfg(feature = "v4_12")]
426 #[cfg_attr(docsrs, doc(cfg(feature = "v4_12")))]
427 #[doc(alias = "gtk_button_set_can_shrink")]
428 #[doc(alias = "can-shrink")]
429 fn set_can_shrink(&self, can_shrink: bool) {
430 unsafe {
431 ffi::gtk_button_set_can_shrink(self.as_ref().to_glib_none().0, can_shrink.into_glib());
432 }
433 }
434
435 #[doc(alias = "gtk_button_set_child")]
436 #[doc(alias = "child")]
437 fn set_child(&self, child: Option<&impl IsA<Widget>>) {
438 unsafe {
439 ffi::gtk_button_set_child(
440 self.as_ref().to_glib_none().0,
441 child.map(|p| p.as_ref()).to_glib_none().0,
442 );
443 }
444 }
445
446 #[doc(alias = "gtk_button_set_has_frame")]
447 #[doc(alias = "has-frame")]
448 fn set_has_frame(&self, has_frame: bool) {
449 unsafe {
450 ffi::gtk_button_set_has_frame(self.as_ref().to_glib_none().0, has_frame.into_glib());
451 }
452 }
453
454 #[doc(alias = "gtk_button_set_icon_name")]
455 #[doc(alias = "icon-name")]
456 fn set_icon_name(&self, icon_name: &str) {
457 unsafe {
458 ffi::gtk_button_set_icon_name(
459 self.as_ref().to_glib_none().0,
460 icon_name.to_glib_none().0,
461 );
462 }
463 }
464
465 #[doc(alias = "gtk_button_set_label")]
466 #[doc(alias = "label")]
467 fn set_label(&self, label: &str) {
468 unsafe {
469 ffi::gtk_button_set_label(self.as_ref().to_glib_none().0, label.to_glib_none().0);
470 }
471 }
472
473 #[doc(alias = "gtk_button_set_use_underline")]
474 #[doc(alias = "use-underline")]
475 fn set_use_underline(&self, use_underline: bool) {
476 unsafe {
477 ffi::gtk_button_set_use_underline(
478 self.as_ref().to_glib_none().0,
479 use_underline.into_glib(),
480 );
481 }
482 }
483
484 #[doc(alias = "activate")]
485 fn connect_activate<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
486 unsafe extern "C" fn activate_trampoline<P: IsA<Button>, F: Fn(&P) + 'static>(
487 this: *mut ffi::GtkButton,
488 f: glib::ffi::gpointer,
489 ) {
490 unsafe {
491 let f: &F = &*(f as *const F);
492 f(Button::from_glib_borrow(this).unsafe_cast_ref())
493 }
494 }
495 unsafe {
496 let f: Box_<F> = Box_::new(f);
497 connect_raw(
498 self.as_ptr() as *mut _,
499 c"activate".as_ptr(),
500 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
501 activate_trampoline::<Self, F> as *const (),
502 )),
503 Box_::into_raw(f),
504 )
505 }
506 }
507
508 fn emit_activate(&self) {
509 self.emit_by_name::<()>("activate", &[]);
510 }
511
512 #[doc(alias = "clicked")]
513 fn connect_clicked<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
514 unsafe extern "C" fn clicked_trampoline<P: IsA<Button>, F: Fn(&P) + 'static>(
515 this: *mut ffi::GtkButton,
516 f: glib::ffi::gpointer,
517 ) {
518 unsafe {
519 let f: &F = &*(f as *const F);
520 f(Button::from_glib_borrow(this).unsafe_cast_ref())
521 }
522 }
523 unsafe {
524 let f: Box_<F> = Box_::new(f);
525 connect_raw(
526 self.as_ptr() as *mut _,
527 c"clicked".as_ptr(),
528 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
529 clicked_trampoline::<Self, F> as *const (),
530 )),
531 Box_::into_raw(f),
532 )
533 }
534 }
535
536 fn emit_clicked(&self) {
537 self.emit_by_name::<()>("clicked", &[]);
538 }
539
540 #[cfg(feature = "v4_12")]
541 #[cfg_attr(docsrs, doc(cfg(feature = "v4_12")))]
542 #[doc(alias = "can-shrink")]
543 fn connect_can_shrink_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
544 unsafe extern "C" fn notify_can_shrink_trampoline<P: IsA<Button>, F: Fn(&P) + 'static>(
545 this: *mut ffi::GtkButton,
546 _param_spec: glib::ffi::gpointer,
547 f: glib::ffi::gpointer,
548 ) {
549 unsafe {
550 let f: &F = &*(f as *const F);
551 f(Button::from_glib_borrow(this).unsafe_cast_ref())
552 }
553 }
554 unsafe {
555 let f: Box_<F> = Box_::new(f);
556 connect_raw(
557 self.as_ptr() as *mut _,
558 c"notify::can-shrink".as_ptr(),
559 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
560 notify_can_shrink_trampoline::<Self, F> as *const (),
561 )),
562 Box_::into_raw(f),
563 )
564 }
565 }
566
567 #[doc(alias = "child")]
568 fn connect_child_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
569 unsafe extern "C" fn notify_child_trampoline<P: IsA<Button>, F: Fn(&P) + 'static>(
570 this: *mut ffi::GtkButton,
571 _param_spec: glib::ffi::gpointer,
572 f: glib::ffi::gpointer,
573 ) {
574 unsafe {
575 let f: &F = &*(f as *const F);
576 f(Button::from_glib_borrow(this).unsafe_cast_ref())
577 }
578 }
579 unsafe {
580 let f: Box_<F> = Box_::new(f);
581 connect_raw(
582 self.as_ptr() as *mut _,
583 c"notify::child".as_ptr(),
584 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
585 notify_child_trampoline::<Self, F> as *const (),
586 )),
587 Box_::into_raw(f),
588 )
589 }
590 }
591
592 #[doc(alias = "has-frame")]
593 fn connect_has_frame_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
594 unsafe extern "C" fn notify_has_frame_trampoline<P: IsA<Button>, F: Fn(&P) + 'static>(
595 this: *mut ffi::GtkButton,
596 _param_spec: glib::ffi::gpointer,
597 f: glib::ffi::gpointer,
598 ) {
599 unsafe {
600 let f: &F = &*(f as *const F);
601 f(Button::from_glib_borrow(this).unsafe_cast_ref())
602 }
603 }
604 unsafe {
605 let f: Box_<F> = Box_::new(f);
606 connect_raw(
607 self.as_ptr() as *mut _,
608 c"notify::has-frame".as_ptr(),
609 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
610 notify_has_frame_trampoline::<Self, F> as *const (),
611 )),
612 Box_::into_raw(f),
613 )
614 }
615 }
616
617 #[doc(alias = "icon-name")]
618 fn connect_icon_name_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
619 unsafe extern "C" fn notify_icon_name_trampoline<P: IsA<Button>, F: Fn(&P) + 'static>(
620 this: *mut ffi::GtkButton,
621 _param_spec: glib::ffi::gpointer,
622 f: glib::ffi::gpointer,
623 ) {
624 unsafe {
625 let f: &F = &*(f as *const F);
626 f(Button::from_glib_borrow(this).unsafe_cast_ref())
627 }
628 }
629 unsafe {
630 let f: Box_<F> = Box_::new(f);
631 connect_raw(
632 self.as_ptr() as *mut _,
633 c"notify::icon-name".as_ptr(),
634 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
635 notify_icon_name_trampoline::<Self, F> as *const (),
636 )),
637 Box_::into_raw(f),
638 )
639 }
640 }
641
642 #[doc(alias = "label")]
643 fn connect_label_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
644 unsafe extern "C" fn notify_label_trampoline<P: IsA<Button>, F: Fn(&P) + 'static>(
645 this: *mut ffi::GtkButton,
646 _param_spec: glib::ffi::gpointer,
647 f: glib::ffi::gpointer,
648 ) {
649 unsafe {
650 let f: &F = &*(f as *const F);
651 f(Button::from_glib_borrow(this).unsafe_cast_ref())
652 }
653 }
654 unsafe {
655 let f: Box_<F> = Box_::new(f);
656 connect_raw(
657 self.as_ptr() as *mut _,
658 c"notify::label".as_ptr(),
659 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
660 notify_label_trampoline::<Self, F> as *const (),
661 )),
662 Box_::into_raw(f),
663 )
664 }
665 }
666
667 #[doc(alias = "use-underline")]
668 fn connect_use_underline_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
669 unsafe extern "C" fn notify_use_underline_trampoline<
670 P: IsA<Button>,
671 F: Fn(&P) + 'static,
672 >(
673 this: *mut ffi::GtkButton,
674 _param_spec: glib::ffi::gpointer,
675 f: glib::ffi::gpointer,
676 ) {
677 unsafe {
678 let f: &F = &*(f as *const F);
679 f(Button::from_glib_borrow(this).unsafe_cast_ref())
680 }
681 }
682 unsafe {
683 let f: Box_<F> = Box_::new(f);
684 connect_raw(
685 self.as_ptr() as *mut _,
686 c"notify::use-underline".as_ptr(),
687 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
688 notify_use_underline_trampoline::<Self, F> as *const (),
689 )),
690 Box_::into_raw(f),
691 )
692 }
693 }
694}
695
696impl<O: IsA<Button>> ButtonExt for O {}