1use std::{boxed::Box as Box_, collections::HashMap, fmt, future::Future};
7
8use glib::{
9 clone::Downgrade,
10 property::{Property, PropertyGet},
11 subclass::SignalId,
12 translate::*,
13 GString, Variant,
14};
15
16use crate::{
17 ffi, prelude::*, subclass::prelude::*, Accessible, AccessibleRole, Buildable, BuilderRustScope,
18 BuilderScope, ConstraintTarget, DirectionType, LayoutManager, Orientation, Shortcut,
19 SizeRequestMode, Snapshot, StateFlags, SystemSetting, TextDirection, Tooltip, Widget,
20};
21
22#[derive(Debug, Default)]
23struct Internal {
24 pub(crate) actions: HashMap<String, glib::ffi::gpointer>,
25 pub(crate) scope: Option<*mut <<BuilderRustScope as glib::object::ObjectSubclassIs>::Subclass as ObjectSubclass>::Instance>,
26}
27unsafe impl Sync for Internal {}
28unsafe impl Send for Internal {}
29
30pub struct WidgetActionIter(*mut ffi::GtkWidgetClass, u32);
31
32pub struct WidgetAction(
33 glib::Type,
34 GString,
35 Option<glib::VariantType>,
36 Option<GString>,
37);
38
39impl WidgetAction {
40 pub fn owner(&self) -> glib::Type {
43 self.0
44 }
45
46 pub fn name(&self) -> &str {
49 self.1.as_ref()
50 }
51
52 pub fn parameter_type(&self) -> Option<&glib::VariantType> {
55 self.2.as_ref()
56 }
57
58 pub fn property_name(&self) -> Option<&str> {
61 self.3.as_ref().map(|s| s.as_ref())
62 }
63}
64
65impl fmt::Debug for WidgetAction {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.debug_struct("WidgetAction")
68 .field("owner", &self.owner())
69 .field("name", &self.name())
70 .field("parameter_type", &self.parameter_type())
71 .field("property_name", &self.property_name())
72 .finish()
73 }
74}
75
76impl Iterator for WidgetActionIter {
77 type Item = WidgetAction;
78
79 fn next(&mut self) -> Option<Self::Item> {
80 unsafe {
81 let mut owner = std::mem::MaybeUninit::uninit();
82 let mut action_name_ptr = std::ptr::null();
83 let mut parameter_type = std::ptr::null();
84 let mut property_name_ptr = std::ptr::null();
85 let found: bool = from_glib(ffi::gtk_widget_class_query_action(
86 self.0,
87 self.1,
88 owner.as_mut_ptr(),
89 &mut action_name_ptr,
90 &mut parameter_type,
91 &mut property_name_ptr,
92 ));
93 if found {
94 self.1 += 1;
95 let property_name: Option<GString> = from_glib_none(property_name_ptr);
96 let action_name: GString = from_glib_none(action_name_ptr);
97
98 Some(WidgetAction(
99 from_glib(owner.assume_init()),
100 action_name,
101 from_glib_none(parameter_type),
102 property_name,
103 ))
104 } else {
105 None
106 }
107 }
108 }
109}
110
111impl std::iter::FusedIterator for WidgetActionIter {}
112
113pub trait WidgetImpl:
114 ObjectImpl
115 + ObjectSubclass<Type: IsA<Widget> + IsA<Accessible> + IsA<Buildable> + IsA<ConstraintTarget>>
116{
117 fn compute_expand(&self, hexpand: &mut bool, vexpand: &mut bool) {
120 self.parent_compute_expand(hexpand, vexpand)
121 }
122
123 fn contains(&self, x: f64, y: f64) -> bool {
136 self.parent_contains(x, y)
137 }
138
139 fn direction_changed(&self, previous_direction: TextDirection) {
142 self.parent_direction_changed(previous_direction)
143 }
144
145 fn focus(&self, direction_type: DirectionType) -> bool {
147 self.parent_focus(direction_type)
148 }
149
150 #[doc(alias = "get_request_mode")]
162 fn request_mode(&self) -> SizeRequestMode {
163 self.parent_request_mode()
164 }
165
166 fn grab_focus(&self) -> bool {
180 self.parent_grab_focus()
181 }
182
183 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
191 #[allow(deprecated)]
192 fn hide(&self) {
193 self.parent_hide()
194 }
195
196 fn keynav_failed(&self, direction_type: DirectionType) -> bool {
233 self.parent_keynav_failed(direction_type)
234 }
235
236 fn map(&self) {
240 self.parent_map()
241 }
242
243 fn measure(&self, orientation: Orientation, for_size: i32) -> (i32, i32, i32, i32) {
277 self.parent_measure(orientation, for_size)
278 }
279
280 fn mnemonic_activate(&self, group_cycling: bool) -> bool {
288 self.parent_mnemonic_activate(group_cycling)
289 }
290
291 fn move_focus(&self, direction_type: DirectionType) {
293 self.parent_move_focus(direction_type)
294 }
295
296 fn query_tooltip(&self, x: i32, y: i32, keyboard_tooltip: bool, tooltip: &Tooltip) -> bool {
300 self.parent_query_tooltip(x, y, keyboard_tooltip, tooltip)
301 }
302
303 fn realize(&self) {
320 self.parent_realize()
321 }
322
323 fn root(&self) {
326 self.parent_root()
327 }
328
329 fn set_focus_child(&self, child: Option<&Widget>) {
338 self.parent_set_focus_child(child)
339 }
340
341 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
356 #[allow(deprecated)]
357 fn show(&self) {
358 self.parent_show()
359 }
360
361 fn size_allocate(&self, width: i32, height: i32, baseline: i32) {
364 self.parent_size_allocate(width, height, baseline)
365 }
366
367 fn snapshot(&self, snapshot: &Snapshot) {
369 self.parent_snapshot(snapshot)
370 }
371
372 fn state_flags_changed(&self, state_flags: &StateFlags) {
375 self.parent_state_flags_changed(state_flags)
376 }
377
378 fn system_setting_changed(&self, settings: &SystemSetting) {
380 self.parent_system_setting_changed(settings)
381 }
382
383 fn unmap(&self) {
387 self.parent_unmap()
388 }
389
390 fn unrealize(&self) {
396 self.parent_unrealize()
397 }
398
399 fn unroot(&self) {
402 self.parent_unroot()
403 }
404}
405
406pub trait WidgetImplExt: WidgetImpl {
407 fn parent_compute_expand(&self, hexpand: &mut bool, vexpand: &mut bool) {
408 unsafe {
409 let data = Self::type_data();
410 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
411 if let Some(f) = (*parent_class).compute_expand {
412 let mut hexpand_glib = hexpand.into_glib();
413 let mut vexpand_glib = vexpand.into_glib();
414 f(
415 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
416 &mut hexpand_glib,
417 &mut vexpand_glib,
418 );
419 *hexpand = from_glib(hexpand_glib);
420 *vexpand = from_glib(vexpand_glib);
421 }
422 }
423 }
424
425 fn parent_contains(&self, x: f64, y: f64) -> bool {
427 unsafe {
428 let data = Self::type_data();
429 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
430 if let Some(f) = (*parent_class).contains {
431 from_glib(f(
432 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
433 x,
434 y,
435 ))
436 } else {
437 false
438 }
439 }
440 }
441
442 fn parent_direction_changed(&self, previous_direction: TextDirection) {
443 unsafe {
444 let data = Self::type_data();
445 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
446 if let Some(f) = (*parent_class).direction_changed {
447 f(
448 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
449 previous_direction.into_glib(),
450 )
451 }
452 }
453 }
454
455 fn parent_focus(&self, direction_type: DirectionType) -> bool {
457 unsafe {
458 let data = Self::type_data();
459 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
460 if let Some(f) = (*parent_class).focus {
461 from_glib(f(
462 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
463 direction_type.into_glib(),
464 ))
465 } else {
466 false
467 }
468 }
469 }
470
471 fn parent_request_mode(&self) -> SizeRequestMode {
472 unsafe {
473 let data = Self::type_data();
474 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
475 let f = (*parent_class)
476 .get_request_mode
477 .expect("No parent class impl for \"get_request_mode\"");
478 from_glib(f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0))
479 }
480 }
481
482 fn parent_grab_focus(&self) -> bool {
484 unsafe {
485 let data = Self::type_data();
486 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
487 if let Some(f) = (*parent_class).grab_focus {
488 from_glib(f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0))
489 } else {
490 false
491 }
492 }
493 }
494
495 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
496 #[allow(deprecated)]
497 fn parent_hide(&self) {
498 unsafe {
499 let data = Self::type_data();
500 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
501 if let Some(f) = (*parent_class).hide {
502 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
503 }
504 }
505 }
506
507 fn parent_keynav_failed(&self, direction_type: DirectionType) -> bool {
511 unsafe {
512 let data = Self::type_data();
513 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
514 if let Some(f) = (*parent_class).keynav_failed {
515 from_glib(f(
516 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
517 direction_type.into_glib(),
518 ))
519 } else {
520 false
521 }
522 }
523 }
524
525 fn parent_map(&self) {
526 unsafe {
527 let data = Self::type_data();
528 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
529 if let Some(f) = (*parent_class).map {
530 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
531 }
532 }
533 }
534
535 fn parent_measure(&self, orientation: Orientation, for_size: i32) -> (i32, i32, i32, i32) {
536 unsafe {
537 let data = Self::type_data();
538 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
539
540 let f = (*parent_class)
541 .measure
542 .expect("No parent class impl for \"measure\"");
543
544 let mut min = 0;
545 let mut nat = 0;
546 let mut min_base = -1;
547 let mut nat_base = -1;
548 f(
549 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
550 orientation.into_glib(),
551 for_size,
552 &mut min,
553 &mut nat,
554 &mut min_base,
555 &mut nat_base,
556 );
557 (min, nat, min_base, nat_base)
558 }
559 }
560
561 fn parent_mnemonic_activate(&self, group_cycling: bool) -> bool {
563 unsafe {
564 let data = Self::type_data();
565 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
566 if let Some(f) = (*parent_class).mnemonic_activate {
567 from_glib(f(
568 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
569 group_cycling.into_glib(),
570 ))
571 } else {
572 false
573 }
574 }
575 }
576
577 fn parent_move_focus(&self, direction_type: DirectionType) {
578 unsafe {
579 let data = Self::type_data();
580 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
581 if let Some(f) = (*parent_class).move_focus {
582 f(
583 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
584 direction_type.into_glib(),
585 )
586 }
587 }
588 }
589
590 fn parent_query_tooltip(
591 &self,
592 x: i32,
593 y: i32,
594 keyboard_tooltip: bool,
595 tooltip: &Tooltip,
596 ) -> bool {
597 unsafe {
598 let data = Self::type_data();
599 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
600 if let Some(f) = (*parent_class).query_tooltip {
601 from_glib(f(
602 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
603 x,
604 y,
605 keyboard_tooltip.into_glib(),
606 tooltip.to_glib_none().0,
607 ))
608 } else {
609 false
610 }
611 }
612 }
613
614 fn parent_realize(&self) {
615 unsafe {
616 let data = Self::type_data();
617 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
618 if let Some(f) = (*parent_class).realize {
619 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
620 }
621 }
622 }
623
624 fn parent_root(&self) {
625 unsafe {
626 let data = Self::type_data();
627 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
628 if let Some(f) = (*parent_class).root {
629 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
630 }
631 }
632 }
633
634 fn parent_set_focus_child(&self, child: Option<&Widget>) {
635 unsafe {
636 let data = Self::type_data();
637 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
638 if let Some(f) = (*parent_class).set_focus_child {
639 f(
640 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
641 child.to_glib_none().0,
642 )
643 }
644 }
645 }
646
647 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
648 #[allow(deprecated)]
649 fn parent_show(&self) {
650 unsafe {
651 let data = Self::type_data();
652 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
653 if let Some(f) = (*parent_class).show {
654 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
655 }
656 }
657 }
658
659 fn parent_size_allocate(&self, width: i32, height: i32, baseline: i32) {
660 unsafe {
661 let data = Self::type_data();
662 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
663 if let Some(f) = (*parent_class).size_allocate {
664 f(
665 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
666 width,
667 height,
668 baseline,
669 )
670 }
671 }
672 }
673
674 fn parent_snapshot(&self, snapshot: &Snapshot) {
675 unsafe {
676 let data = Self::type_data();
677 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
678 if let Some(f) = (*parent_class).snapshot {
679 f(
680 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
681 snapshot.to_glib_none().0,
682 )
683 }
684 }
685 }
686
687 fn parent_state_flags_changed(&self, state_flags: &StateFlags) {
688 unsafe {
689 let data = Self::type_data();
690 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
691 if let Some(f) = (*parent_class).state_flags_changed {
692 f(
693 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
694 state_flags.into_glib(),
695 )
696 }
697 }
698 }
699
700 fn parent_system_setting_changed(&self, settings: &SystemSetting) {
701 unsafe {
702 let data = Self::type_data();
703 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
704 if let Some(f) = (*parent_class).system_setting_changed {
705 f(
706 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
707 settings.into_glib(),
708 )
709 }
710 }
711 }
712
713 fn parent_unmap(&self) {
714 unsafe {
715 let data = Self::type_data();
716 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
717 if let Some(f) = (*parent_class).unmap {
718 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
719 }
720 }
721 }
722
723 fn parent_unrealize(&self) {
724 unsafe {
725 let data = Self::type_data();
726 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
727 if let Some(f) = (*parent_class).unrealize {
728 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
729 }
730 }
731 }
732
733 fn parent_unroot(&self) {
734 unsafe {
735 let data = Self::type_data();
736 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
737 if let Some(f) = (*parent_class).unroot {
738 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
739 }
740 }
741 }
742}
743
744impl<T: WidgetImpl> WidgetImplExt for T {}
745
746unsafe impl<T: WidgetImpl> IsSubclassable<T> for Widget {
747 fn class_init(class: &mut ::glib::Class<Self>) {
748 Self::parent_class_init::<T>(class);
749
750 assert_initialized_main_thread!();
751
752 let klass = class.as_mut();
753 unsafe {
754 let mut data = T::type_data();
755 let data = data.as_mut();
756 data.set_class_data(<T as ObjectSubclassType>::type_(), Internal::default());
758 }
759
760 klass.compute_expand = Some(widget_compute_expand::<T>);
761 klass.contains = Some(widget_contains::<T>);
762 klass.direction_changed = Some(widget_direction_changed::<T>);
763 klass.focus = Some(widget_focus::<T>);
764 klass.get_request_mode = Some(widget_get_request_mode::<T>);
765 klass.grab_focus = Some(widget_grab_focus::<T>);
766 klass.hide = Some(widget_hide::<T>);
767 klass.keynav_failed = Some(widget_keynav_failed::<T>);
768 klass.map = Some(widget_map::<T>);
769 klass.measure = Some(widget_measure::<T>);
770 klass.mnemonic_activate = Some(widget_mnemonic_activate::<T>);
771 klass.move_focus = Some(widget_move_focus::<T>);
772 klass.query_tooltip = Some(widget_query_tooltip::<T>);
773 klass.realize = Some(widget_realize::<T>);
774 klass.root = Some(widget_root::<T>);
775 klass.set_focus_child = Some(widget_set_focus_child::<T>);
776 klass.show = Some(widget_show::<T>);
777 klass.size_allocate = Some(widget_size_allocate::<T>);
778 klass.snapshot = Some(widget_snapshot::<T>);
779 klass.state_flags_changed = Some(widget_state_flags_changed::<T>);
780 klass.system_setting_changed = Some(widget_system_setting_changed::<T>);
781 klass.unmap = Some(widget_unmap::<T>);
782 klass.unrealize = Some(widget_unrealize::<T>);
783 klass.unroot = Some(widget_unroot::<T>);
784 }
785}
786
787unsafe extern "C" fn widget_compute_expand<T: WidgetImpl>(
788 ptr: *mut ffi::GtkWidget,
789 hexpand_ptr: *mut glib::ffi::gboolean,
790 vexpand_ptr: *mut glib::ffi::gboolean,
791) {
792 let instance = &*(ptr as *mut T::Instance);
793 let imp = instance.imp();
794
795 let widget = imp.obj();
796 let widget = widget.unsafe_cast_ref::<Widget>();
797 let mut hexpand: bool = if widget.is_hexpand_set() {
798 widget.hexpands()
799 } else {
800 from_glib(*hexpand_ptr)
801 };
802 let mut vexpand: bool = if widget.is_vexpand_set() {
803 widget.vexpands()
804 } else {
805 from_glib(*vexpand_ptr)
806 };
807
808 imp.compute_expand(&mut hexpand, &mut vexpand);
809
810 *hexpand_ptr = hexpand.into_glib();
811 *vexpand_ptr = vexpand.into_glib();
812}
813
814unsafe extern "C" fn widget_contains<T: WidgetImpl>(
815 ptr: *mut ffi::GtkWidget,
816 x: f64,
817 y: f64,
818) -> glib::ffi::gboolean {
819 let instance = &*(ptr as *mut T::Instance);
820 let imp = instance.imp();
821
822 imp.contains(x, y).into_glib()
823}
824
825unsafe extern "C" fn widget_direction_changed<T: WidgetImpl>(
826 ptr: *mut ffi::GtkWidget,
827 direction_ptr: ffi::GtkTextDirection,
828) {
829 let instance = &*(ptr as *mut T::Instance);
830 let imp = instance.imp();
831 let direction_wrap = from_glib(direction_ptr);
832
833 imp.direction_changed(direction_wrap)
834}
835
836unsafe extern "C" fn widget_focus<T: WidgetImpl>(
837 ptr: *mut ffi::GtkWidget,
838 direction_type_ptr: ffi::GtkDirectionType,
839) -> glib::ffi::gboolean {
840 let instance = &*(ptr as *mut T::Instance);
841 let imp = instance.imp();
842 let direction_type = from_glib(direction_type_ptr);
843
844 imp.focus(direction_type).into_glib()
845}
846
847unsafe extern "C" fn widget_get_request_mode<T: WidgetImpl>(
848 ptr: *mut ffi::GtkWidget,
849) -> ffi::GtkSizeRequestMode {
850 let instance = &*(ptr as *mut T::Instance);
851 let imp = instance.imp();
852
853 imp.request_mode().into_glib()
854}
855
856unsafe extern "C" fn widget_grab_focus<T: WidgetImpl>(
857 ptr: *mut ffi::GtkWidget,
858) -> glib::ffi::gboolean {
859 let instance = &*(ptr as *mut T::Instance);
860 let imp = instance.imp();
861
862 imp.grab_focus().into_glib()
863}
864
865unsafe extern "C" fn widget_hide<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
866 let instance = &*(ptr as *mut T::Instance);
867 let imp = instance.imp();
868
869 imp.hide()
870}
871
872unsafe extern "C" fn widget_keynav_failed<T: WidgetImpl>(
873 ptr: *mut ffi::GtkWidget,
874 direction_type_ptr: ffi::GtkDirectionType,
875) -> glib::ffi::gboolean {
876 let instance = &*(ptr as *mut T::Instance);
877 let imp = instance.imp();
878 let direction_type = from_glib(direction_type_ptr);
879
880 imp.keynav_failed(direction_type).into_glib()
881}
882
883unsafe extern "C" fn widget_map<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
884 let instance = &*(ptr as *mut T::Instance);
885 let imp = instance.imp();
886
887 imp.map()
888}
889
890unsafe extern "C" fn widget_measure<T: WidgetImpl>(
891 ptr: *mut ffi::GtkWidget,
892 orientation_ptr: ffi::GtkOrientation,
893 for_size: i32,
894 min_ptr: *mut libc::c_int,
895 nat_ptr: *mut libc::c_int,
896 min_base_ptr: *mut libc::c_int,
897 nat_base_ptr: *mut libc::c_int,
898) {
899 let instance = &*(ptr as *mut T::Instance);
900 let imp = instance.imp();
901 let orientation = from_glib(orientation_ptr);
902 let (min, nat, min_base, nat_base) = imp.measure(orientation, for_size);
903 if !min_ptr.is_null() {
904 *min_ptr = min;
905 }
906 if !nat_ptr.is_null() {
907 *nat_ptr = nat;
908 }
909 if !min_base_ptr.is_null() {
910 *min_base_ptr = min_base;
911 }
912 if !nat_base_ptr.is_null() {
913 *nat_base_ptr = nat_base;
914 }
915}
916
917unsafe extern "C" fn widget_mnemonic_activate<T: WidgetImpl>(
918 ptr: *mut ffi::GtkWidget,
919 group_cycling_ptr: glib::ffi::gboolean,
920) -> glib::ffi::gboolean {
921 let instance = &*(ptr as *mut T::Instance);
922 let imp = instance.imp();
923 let group_cycling: bool = from_glib(group_cycling_ptr);
924
925 imp.mnemonic_activate(group_cycling).into_glib()
926}
927
928unsafe extern "C" fn widget_move_focus<T: WidgetImpl>(
929 ptr: *mut ffi::GtkWidget,
930 direction_type_ptr: ffi::GtkDirectionType,
931) {
932 let instance = &*(ptr as *mut T::Instance);
933 let imp = instance.imp();
934 let direction_type = from_glib(direction_type_ptr);
935
936 imp.move_focus(direction_type)
937}
938
939unsafe extern "C" fn widget_query_tooltip<T: WidgetImpl>(
940 ptr: *mut ffi::GtkWidget,
941 x: i32,
942 y: i32,
943 keyboard_tooltip_ptr: glib::ffi::gboolean,
944 tooltip_ptr: *mut ffi::GtkTooltip,
945) -> glib::ffi::gboolean {
946 let instance = &*(ptr as *mut T::Instance);
947 let imp = instance.imp();
948
949 let keyboard_tooltip: bool = from_glib(keyboard_tooltip_ptr);
950 let tooltip = from_glib_borrow(tooltip_ptr);
951
952 imp.query_tooltip(x, y, keyboard_tooltip, &tooltip)
953 .into_glib()
954}
955
956unsafe extern "C" fn widget_realize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
957 let instance = &*(ptr as *mut T::Instance);
958 let imp = instance.imp();
959
960 imp.realize()
961}
962
963unsafe extern "C" fn widget_root<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
964 let instance = &*(ptr as *mut T::Instance);
965 let imp = instance.imp();
966
967 imp.root()
968}
969
970unsafe extern "C" fn widget_set_focus_child<T: WidgetImpl>(
971 ptr: *mut ffi::GtkWidget,
972 child_ptr: *mut ffi::GtkWidget,
973) {
974 let instance = &*(ptr as *mut T::Instance);
975 let imp = instance.imp();
976 let child: Borrowed<Option<Widget>> = from_glib_borrow(child_ptr);
977
978 imp.set_focus_child(child.as_ref().as_ref())
979}
980
981unsafe extern "C" fn widget_show<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
982 let instance = &*(ptr as *mut T::Instance);
983 let imp = instance.imp();
984
985 imp.show()
986}
987
988unsafe extern "C" fn widget_size_allocate<T: WidgetImpl>(
989 ptr: *mut ffi::GtkWidget,
990 width: i32,
991 height: i32,
992 baseline: i32,
993) {
994 let instance = &*(ptr as *mut T::Instance);
995 let imp = instance.imp();
996
997 imp.size_allocate(width, height, baseline)
998}
999
1000unsafe extern "C" fn widget_snapshot<T: WidgetImpl>(
1001 ptr: *mut ffi::GtkWidget,
1002 snapshot_ptr: *mut ffi::GtkSnapshot,
1003) {
1004 let instance = &*(ptr as *mut T::Instance);
1005 let imp = instance.imp();
1006 let snapshot = from_glib_borrow(snapshot_ptr);
1007
1008 imp.snapshot(&snapshot)
1009}
1010
1011unsafe extern "C" fn widget_state_flags_changed<T: WidgetImpl>(
1012 ptr: *mut ffi::GtkWidget,
1013 state_flags_ptr: ffi::GtkStateFlags,
1014) {
1015 let instance = &*(ptr as *mut T::Instance);
1016 let imp = instance.imp();
1017 let state_flags = from_glib(state_flags_ptr);
1018
1019 imp.state_flags_changed(&state_flags)
1020}
1021
1022unsafe extern "C" fn widget_system_setting_changed<T: WidgetImpl>(
1023 ptr: *mut ffi::GtkWidget,
1024 settings_ptr: ffi::GtkSystemSetting,
1025) {
1026 let instance = &*(ptr as *mut T::Instance);
1027 let imp = instance.imp();
1028 let settings = from_glib(settings_ptr);
1029
1030 imp.system_setting_changed(&settings)
1031}
1032
1033unsafe extern "C" fn widget_unmap<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1034 let instance = &*(ptr as *mut T::Instance);
1035 let imp = instance.imp();
1036
1037 imp.unmap()
1038}
1039
1040unsafe extern "C" fn widget_unrealize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1041 let instance = &*(ptr as *mut T::Instance);
1042 let imp = instance.imp();
1043
1044 imp.unrealize()
1045}
1046
1047unsafe extern "C" fn widget_unroot<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1048 let instance = &*(ptr as *mut T::Instance);
1049 let imp = instance.imp();
1050
1051 imp.unroot()
1052}
1053
1054#[allow(clippy::missing_safety_doc)]
1055pub unsafe trait WidgetClassExt: ClassStruct {
1056 #[doc(alias = "gtk_widget_class_set_template")]
1057 fn set_template_bytes(&mut self, template: &glib::Bytes) {
1058 unsafe {
1059 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1060 ffi::gtk_widget_class_set_template(widget_class, template.to_glib_none().0);
1061 }
1062 }
1063
1064 fn set_template(&mut self, template: &[u8]) {
1075 let template_bytes = glib::Bytes::from(template);
1076 self.set_template_bytes(&template_bytes);
1077 }
1078
1079 fn set_template_static(&mut self, template: &'static [u8]) {
1080 let template_bytes = glib::Bytes::from_static(template);
1081 self.set_template_bytes(&template_bytes);
1082 }
1083
1084 #[doc(alias = "gtk_widget_class_set_template_from_resource")]
1093 fn set_template_from_resource(&mut self, resource_name: &str) {
1094 unsafe {
1095 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1096 ffi::gtk_widget_class_set_template_from_resource(
1097 widget_class,
1098 resource_name.to_glib_none().0,
1099 );
1100 }
1101 }
1102
1103 fn install_action_async<Fut, F>(
1104 &mut self,
1105 action_name: &str,
1106 parameter_type: Option<&glib::VariantTy>,
1107 activate: F,
1108 ) where
1109 F: Fn(
1110 <<Self as ClassStruct>::Type as ObjectSubclass>::Type,
1111 String,
1112 Option<Variant>,
1113 ) -> Fut
1114 + 'static
1115 + Clone,
1116 Fut: Future<Output = ()>,
1117 {
1118 self.install_action(
1119 action_name,
1120 parameter_type,
1121 move |this, action_name, parameter_type| {
1122 let ctx = glib::MainContext::default();
1123 let action_name = action_name.to_owned();
1124 let parameter_type = parameter_type.map(ToOwned::to_owned);
1125 ctx.spawn_local(glib::clone!(
1126 #[strong]
1127 this,
1128 #[strong]
1129 action_name,
1130 #[strong]
1131 parameter_type,
1132 #[strong]
1133 activate,
1134 async move {
1135 activate(this, action_name, parameter_type).await;
1136 }
1137 ));
1138 },
1139 );
1140 }
1141
1142 #[doc(alias = "gtk_widget_class_install_action")]
1156 fn install_action<F>(
1157 &mut self,
1158 action_name: &str,
1159 parameter_type: Option<&glib::VariantTy>,
1160 activate: F,
1161 ) where
1162 F: Fn(&<<Self as ClassStruct>::Type as ObjectSubclass>::Type, &str, Option<&Variant>)
1163 + 'static,
1164 {
1165 unsafe {
1166 let mut data = <Self::Type as ObjectSubclassType>::type_data();
1169 let data = data.as_mut();
1170
1171 let f: Box_<F> = Box_::new(activate);
1172
1173 let internal = data
1174 .class_data_mut::<Internal>(<Self::Type as ObjectSubclassType>::type_())
1175 .expect("Something bad happened at class_init, the internal class_data is missing");
1176 let callback_ptr = Box_::into_raw(f) as glib::ffi::gpointer;
1177 internal
1178 .actions
1179 .insert(action_name.to_string(), callback_ptr);
1180
1181 unsafe extern "C" fn activate_trampoline<F, S>(
1182 this: *mut ffi::GtkWidget,
1183 action_name: *const libc::c_char,
1184 parameter: *mut glib::ffi::GVariant,
1185 ) where
1186 S: ClassStruct,
1187 <S as ClassStruct>::Type: ObjectSubclass,
1188 F: Fn(&<<S as ClassStruct>::Type as ObjectSubclass>::Type, &str, Option<&Variant>)
1189 + 'static,
1190 {
1191 let action_name = GString::from_glib_borrow(action_name);
1192
1193 let data = <S::Type as ObjectSubclassType>::type_data();
1194 let internal = data
1195 .as_ref()
1196 .class_data::<Internal>(<S::Type as ObjectSubclassType>::type_())
1197 .unwrap();
1198 let activate_callback = *internal
1199 .actions
1200 .get(&action_name.to_string())
1201 .unwrap_or_else(|| {
1202 panic!("Action name '{}' was not found", action_name.as_str());
1203 });
1204
1205 let widget = Widget::from_glib_borrow(this);
1206
1207 let f: &F = &*(activate_callback as *const F);
1208 f(
1209 widget.unsafe_cast_ref(),
1210 &action_name,
1211 Option::<Variant>::from_glib_borrow(parameter)
1212 .as_ref()
1213 .as_ref(),
1214 )
1215 }
1216 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1217 let callback = activate_trampoline::<F, Self>;
1218 ffi::gtk_widget_class_install_action(
1219 widget_class,
1220 action_name.to_glib_none().0,
1221 parameter_type.map(|p| p.as_str()).to_glib_none().0,
1222 Some(callback),
1223 );
1224 }
1225 }
1226
1227 #[doc(alias = "gtk_widget_class_query_action")]
1255 fn query_action(&self) -> WidgetActionIter {
1256 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1257 WidgetActionIter(widget_class, 0)
1258 }
1259
1260 #[doc(alias = "gtk_widget_class_set_template_scope")]
1270 fn set_template_scope<S: IsA<BuilderScope>>(&mut self, scope: &S) {
1271 unsafe {
1272 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1273 ffi::gtk_widget_class_set_template_scope(widget_class, scope.as_ref().to_glib_none().0);
1274 }
1275 }
1276
1277 #[doc(alias = "gtk_widget_class_add_binding")]
1297 fn add_binding<
1298 F: Fn(&<<Self as ClassStruct>::Type as ObjectSubclass>::Type) -> glib::Propagation + 'static,
1299 >(
1300 &mut self,
1301 keyval: gdk::Key,
1302 mods: gdk::ModifierType,
1303 callback: F,
1304 ) {
1305 let shortcut = crate::Shortcut::new(
1306 Some(crate::KeyvalTrigger::new(keyval, mods)),
1307 Some(crate::CallbackAction::new(
1308 move |widget, _| -> glib::Propagation {
1309 unsafe { callback(widget.unsafe_cast_ref()) }
1310 },
1311 )),
1312 );
1313 self.add_shortcut(&shortcut);
1314 }
1315
1316 #[doc(alias = "gtk_widget_class_add_binding_action")]
1334 fn add_binding_action(&mut self, keyval: gdk::Key, mods: gdk::ModifierType, action_name: &str) {
1335 let shortcut = crate::Shortcut::new(
1336 Some(crate::KeyvalTrigger::new(keyval, mods)),
1337 Some(crate::NamedAction::new(action_name)),
1338 );
1339 self.add_shortcut(&shortcut);
1340 }
1341
1342 #[doc(alias = "gtk_widget_class_add_binding_signal")]
1360 fn add_binding_signal(&mut self, keyval: gdk::Key, mods: gdk::ModifierType, signal_name: &str) {
1361 let type_ = <Self::Type as ObjectSubclassType>::type_();
1362 assert!(
1363 SignalId::lookup(signal_name, type_).is_some(),
1364 "Signal '{signal_name}' doesn't exists for type '{type_}'",
1365 );
1366
1367 let shortcut = crate::Shortcut::new(
1368 Some(crate::KeyvalTrigger::new(keyval, mods)),
1369 Some(crate::SignalAction::new(signal_name)),
1370 );
1371 self.add_shortcut(&shortcut);
1372 }
1373
1374 #[doc(alias = "gtk_widget_class_add_shortcut")]
1387 fn add_shortcut(&mut self, shortcut: &Shortcut) {
1388 unsafe {
1389 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1390 ffi::gtk_widget_class_add_shortcut(widget_class, shortcut.to_glib_none().0);
1391 }
1392 }
1393
1394 #[doc(alias = "gtk_widget_class_install_property_action")]
1415 fn install_property_action(&mut self, action_name: &str, property_name: &str) {
1416 unsafe {
1417 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1418 ffi::gtk_widget_class_install_property_action(
1419 widget_class,
1420 action_name.to_glib_none().0,
1421 property_name.to_glib_none().0,
1422 );
1423 }
1424 }
1425
1426 #[doc(alias = "gtk_widget_class_get_activate_signal")]
1436 #[doc(alias = "get_activate_signal")]
1437 fn activate_signal(&self) -> Option<SignalId> {
1438 unsafe {
1439 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1440 let signal_id = ffi::gtk_widget_class_get_activate_signal(widget_class);
1441 if signal_id == 0 {
1442 None
1443 } else {
1444 Some(from_glib(signal_id))
1445 }
1446 }
1447 }
1448
1449 #[doc(alias = "gtk_widget_class_set_activate_signal")]
1458 fn set_activate_signal(&mut self, signal_id: SignalId) {
1459 unsafe {
1460 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1461 ffi::gtk_widget_class_set_activate_signal(widget_class, signal_id.into_glib())
1462 }
1463 }
1464
1465 #[doc(alias = "gtk_widget_class_set_activate_signal_from_name")]
1476 fn set_activate_signal_from_name(&mut self, signal_name: &str) {
1477 let type_ = <Self::Type as ObjectSubclassType>::type_();
1478 assert!(
1479 SignalId::lookup(signal_name, type_).is_some(),
1480 "Signal '{signal_name}' doesn't exists for type '{type_}'",
1481 );
1482
1483 unsafe {
1484 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1485 ffi::gtk_widget_class_set_activate_signal_from_name(
1486 widget_class,
1487 signal_name.to_glib_none().0,
1488 );
1489 }
1490 }
1491
1492 #[doc(alias = "gtk_widget_class_set_layout_manager_type")]
1503 fn set_layout_manager_type<T: IsA<LayoutManager>>(&mut self) {
1504 unsafe {
1505 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1506 ffi::gtk_widget_class_set_layout_manager_type(
1507 widget_class,
1508 T::static_type().into_glib(),
1509 );
1510 }
1511 }
1512
1513 #[doc(alias = "gtk_widget_class_get_layout_manager_type")]
1522 #[doc(alias = "get_layout_manager_type")]
1523 fn layout_manager_type(&self) -> glib::Type {
1524 unsafe {
1525 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1526 from_glib(ffi::gtk_widget_class_get_layout_manager_type(widget_class))
1527 }
1528 }
1529
1530 #[doc(alias = "gtk_widget_class_set_css_name")]
1538 fn set_css_name(&mut self, name: &str) {
1539 unsafe {
1540 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1541 ffi::gtk_widget_class_set_css_name(widget_class, name.to_glib_none().0);
1542 }
1543 }
1544
1545 #[doc(alias = "gtk_widget_class_get_css_name")]
1553 #[doc(alias = "get_css_name")]
1554 fn css_name(&self) -> glib::GString {
1555 unsafe {
1556 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1557 from_glib_none(ffi::gtk_widget_class_get_css_name(widget_class))
1558 }
1559 }
1560
1561 #[doc(alias = "gtk_widget_class_set_accessible_role")]
1568 fn set_accessible_role(&mut self, role: AccessibleRole) {
1569 unsafe {
1570 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1571 ffi::gtk_widget_class_set_accessible_role(widget_class, role.into_glib());
1572 }
1573 }
1574
1575 #[doc(alias = "gtk_widget_class_get_accessible_role")]
1586 #[doc(alias = "get_accessible_role")]
1587 fn accessible_role(&self) -> AccessibleRole {
1588 unsafe {
1589 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1590 from_glib(ffi::gtk_widget_class_get_accessible_role(widget_class))
1591 }
1592 }
1593
1594 #[allow(clippy::missing_safety_doc)]
1595 #[doc(alias = "gtk_widget_class_bind_template_child_full")]
1596 unsafe fn bind_template_child_with_offset<T>(
1597 &mut self,
1598 name: &str,
1599 internal: bool,
1600 offset: field_offset::FieldOffset<Self::Type, TemplateChild<T>>,
1601 ) where
1602 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1603 {
1604 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1605 let private_offset = <Self::Type as ObjectSubclassType>::type_data()
1606 .as_ref()
1607 .impl_offset();
1608 ffi::gtk_widget_class_bind_template_child_full(
1609 widget_class,
1610 name.to_glib_none().0,
1611 internal.into_glib(),
1612 private_offset + (offset.get_byte_offset() as isize),
1613 )
1614 }
1615
1616 fn rust_template_scope(&mut self) -> BuilderRustScope {
1617 assert_initialized_main_thread!();
1618 unsafe {
1619 let mut data = <Self::Type as ObjectSubclassType>::type_data();
1620 let internal = data
1621 .as_mut()
1622 .class_data_mut::<Internal>(<Self::Type as ObjectSubclassType>::type_())
1623 .expect("Something bad happened at class_init, the internal class_data is missing");
1624 let scope = internal.scope.get_or_insert_with(|| {
1625 let scope = BuilderRustScope::new();
1626 self.set_template_scope(&scope);
1627 scope.into_glib_ptr()
1628 });
1629 from_glib_none(*scope)
1630 }
1631 }
1632}
1633
1634unsafe impl<T: ClassStruct> WidgetClassExt for T where T::Type: WidgetImpl {}
1635
1636#[derive(Debug, PartialEq, Eq)]
1637#[repr(transparent)]
1638pub struct TemplateChild<T>
1639where
1640 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1641{
1642 ptr: *mut <T as ObjectType>::GlibType,
1643}
1644
1645impl<T: Property> Property for TemplateChild<T>
1646where
1647 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1648{
1649 type Value = T::Value;
1650}
1651
1652impl<T> Default for TemplateChild<T>
1653where
1654 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1655{
1656 fn default() -> Self {
1657 T::static_type();
1658
1659 Self {
1660 ptr: std::ptr::null_mut(),
1661 }
1662 }
1663}
1664
1665impl<T> PropertyGet for TemplateChild<T>
1666where
1667 T: Property + ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1668{
1669 type Value = T;
1670
1671 fn get<R, F: Fn(&Self::Value) -> R>(&self, f: F) -> R {
1672 f(&self.get())
1673 }
1674}
1675
1676impl<T> std::ops::Deref for TemplateChild<T>
1677where
1678 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1679{
1680 type Target = T;
1681
1682 #[inline]
1683 fn deref(&self) -> &Self::Target {
1684 unsafe {
1685 if !self.is_bound() {
1686 let name = Self::name();
1687 panic!("Failed to retrieve template child. Please check that all fields of type `{name}` have been bound and have a #[template_child] attribute.");
1688 }
1689 &*(&self.ptr as *const _ as *const T)
1690 }
1691 }
1692}
1693
1694impl<T> Downgrade for TemplateChild<T>
1695where
1696 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType> + Downgrade,
1697{
1698 type Weak = T::Weak;
1699
1700 fn downgrade(&self) -> Self::Weak {
1701 T::downgrade(&self.get())
1702 }
1703}
1704
1705impl<T> TemplateChild<T>
1706where
1707 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1708{
1709 pub(crate) fn name<'a>() -> &'a str {
1710 T::static_type().name()
1711 }
1712
1713 #[track_caller]
1714 pub fn get(&self) -> T {
1715 self.try_get()
1716 .unwrap_or_else(|| {
1717 let name = Self::name();
1718 panic!("Failed to retrieve template child. Please check that all fields of type `{name}` have been bound and have a #[template_child] attribute.");
1719 })
1720 }
1721
1722 pub fn is_bound(&self) -> bool {
1726 !self.ptr.is_null()
1727 }
1728
1729 pub fn try_get(&self) -> Option<T> {
1732 unsafe { Option::<T>::from_glib_none(self.ptr) }
1733 }
1734}
1735
1736pub trait CompositeTemplate: WidgetImpl {
1742 fn bind_template(klass: &mut Self::Class);
1743 fn check_template_children(widget: &<Self as ObjectSubclass>::Type);
1744}
1745
1746pub trait CompositeTemplateClass {
1751 fn bind_template(&mut self);
1755}
1756
1757impl<T, U> CompositeTemplateClass for T
1758where
1759 T: ClassStruct<Type = U>,
1760 U: ObjectSubclass<Class = T> + CompositeTemplate,
1761{
1762 fn bind_template(&mut self) {
1763 <U as CompositeTemplate>::bind_template(self);
1764 }
1765}
1766
1767pub type TemplateCallback = (&'static str, fn(&[glib::Value]) -> Option<glib::Value>);
1768
1769pub trait CompositeTemplateCallbacks {
1775 const CALLBACKS: &'static [TemplateCallback];
1776
1777 fn bind_template_callbacks<T: WidgetClassExt>(klass: &mut T) {
1781 Self::add_callbacks_to_scope(&klass.rust_template_scope());
1782 }
1783 fn bind_template_callbacks_prefixed<T: WidgetClassExt>(klass: &mut T, prefix: &str) {
1787 Self::add_callbacks_to_scope_prefixed(&klass.rust_template_scope(), prefix);
1788 }
1789 fn add_callbacks_to_scope(scope: &BuilderRustScope) {
1792 for (name, func) in Self::CALLBACKS {
1793 scope.add_callback(*name, func);
1794 }
1795 }
1796 fn add_callbacks_to_scope_prefixed(scope: &BuilderRustScope, prefix: &str) {
1800 for (name, func) in Self::CALLBACKS {
1801 scope.add_callback(format!("{prefix}{name}"), func);
1802 }
1803 }
1804}
1805
1806pub trait CompositeTemplateCallbacksClass {
1811 fn bind_template_callbacks(&mut self);
1815}
1816
1817impl<T, U> CompositeTemplateCallbacksClass for T
1818where
1819 T: ClassStruct<Type = U> + WidgetClassExt,
1820 U: ObjectSubclass<Class = T> + CompositeTemplateCallbacks,
1821{
1822 fn bind_template_callbacks(&mut self) {
1823 <U as CompositeTemplateCallbacks>::bind_template_callbacks(self);
1824 }
1825}
1826
1827pub trait CompositeTemplateInstanceCallbacksClass {
1833 fn bind_template_instance_callbacks(&mut self);
1837}
1838
1839impl<T, U, V> CompositeTemplateInstanceCallbacksClass for T
1840where
1841 T: ClassStruct<Type = U> + WidgetClassExt,
1842 U: ObjectSubclass<Class = T, Type = V>,
1843 V: CompositeTemplateCallbacks,
1844{
1845 fn bind_template_instance_callbacks(&mut self) {
1846 <V as CompositeTemplateCallbacks>::bind_template_callbacks(self);
1847 }
1848}
1849
1850pub trait CompositeTemplateInitializingExt {
1851 fn init_template(&self);
1852}
1853
1854impl<T: WidgetImpl + CompositeTemplate> CompositeTemplateInitializingExt
1855 for glib::subclass::InitializingObject<T>
1856{
1857 fn init_template(&self) {
1858 unsafe {
1859 let widget = self
1860 .as_ref()
1861 .unsafe_cast_ref::<<T as ObjectSubclass>::Type>();
1862 ffi::gtk_widget_init_template(AsRef::<Widget>::as_ref(widget).to_glib_none().0);
1863
1864 <T as CompositeTemplate>::check_template_children(widget);
1865 }
1866 }
1867}
1868
1869pub trait CompositeTemplateDisposeExt {
1870 #[cfg(feature = "v4_8")]
1871 #[cfg_attr(docsrs, doc(cfg(feature = "v4_8")))]
1872 fn dispose_template(&self);
1873}
1874
1875impl<T: WidgetImpl + CompositeTemplate> CompositeTemplateDisposeExt for T {
1876 #[cfg(feature = "v4_8")]
1877 #[cfg_attr(docsrs, doc(cfg(feature = "v4_8")))]
1878 fn dispose_template(&self) {
1879 unsafe {
1880 ffi::gtk_widget_dispose_template(
1881 self.obj().upcast_ref::<Widget>().to_glib_none().0,
1882 <T as ObjectSubclass>::Type::static_type().into_glib(),
1883 );
1884 }
1885 }
1886}