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::*, AccessibleRole, BuilderRustScope, BuilderScope,
18 DirectionType, LayoutManager, Orientation, Shortcut, SizeRequestMode, Snapshot, StateFlags,
19 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: WidgetImplExt + ObjectImpl {
114 fn compute_expand(&self, hexpand: &mut bool, vexpand: &mut bool) {
117 self.parent_compute_expand(hexpand, vexpand)
118 }
119
120 fn contains(&self, x: f64, y: f64) -> bool {
133 self.parent_contains(x, y)
134 }
135
136 fn direction_changed(&self, previous_direction: TextDirection) {
139 self.parent_direction_changed(previous_direction)
140 }
141
142 fn focus(&self, direction_type: DirectionType) -> bool {
144 self.parent_focus(direction_type)
145 }
146
147 #[doc(alias = "get_request_mode")]
159 fn request_mode(&self) -> SizeRequestMode {
160 self.parent_request_mode()
161 }
162
163 fn grab_focus(&self) -> bool {
177 self.parent_grab_focus()
178 }
179
180 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
188 #[allow(deprecated)]
189 fn hide(&self) {
190 self.parent_hide()
191 }
192
193 fn keynav_failed(&self, direction_type: DirectionType) -> bool {
230 self.parent_keynav_failed(direction_type)
231 }
232
233 fn map(&self) {
237 self.parent_map()
238 }
239
240 fn measure(&self, orientation: Orientation, for_size: i32) -> (i32, i32, i32, i32) {
274 self.parent_measure(orientation, for_size)
275 }
276
277 fn mnemonic_activate(&self, group_cycling: bool) -> bool {
285 self.parent_mnemonic_activate(group_cycling)
286 }
287
288 fn move_focus(&self, direction_type: DirectionType) {
290 self.parent_move_focus(direction_type)
291 }
292
293 fn query_tooltip(&self, x: i32, y: i32, keyboard_tooltip: bool, tooltip: &Tooltip) -> bool {
297 self.parent_query_tooltip(x, y, keyboard_tooltip, tooltip)
298 }
299
300 fn realize(&self) {
317 self.parent_realize()
318 }
319
320 fn root(&self) {
323 self.parent_root()
324 }
325
326 fn set_focus_child(&self, child: Option<&Widget>) {
335 self.parent_set_focus_child(child)
336 }
337
338 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
353 #[allow(deprecated)]
354 fn show(&self) {
355 self.parent_show()
356 }
357
358 fn size_allocate(&self, width: i32, height: i32, baseline: i32) {
361 self.parent_size_allocate(width, height, baseline)
362 }
363
364 fn snapshot(&self, snapshot: &Snapshot) {
366 self.parent_snapshot(snapshot)
367 }
368
369 fn state_flags_changed(&self, state_flags: &StateFlags) {
372 self.parent_state_flags_changed(state_flags)
373 }
374
375 fn system_setting_changed(&self, settings: &SystemSetting) {
377 self.parent_system_setting_changed(settings)
378 }
379
380 fn unmap(&self) {
384 self.parent_unmap()
385 }
386
387 fn unrealize(&self) {
393 self.parent_unrealize()
394 }
395
396 fn unroot(&self) {
399 self.parent_unroot()
400 }
401}
402
403mod sealed {
404 pub trait Sealed {}
405 impl<T: super::WidgetImplExt> Sealed for T {}
406}
407
408pub trait WidgetImplExt: sealed::Sealed + ObjectSubclass {
409 fn parent_compute_expand(&self, hexpand: &mut bool, vexpand: &mut bool) {
410 unsafe {
411 let data = Self::type_data();
412 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
413 if let Some(f) = (*parent_class).compute_expand {
414 let mut hexpand_glib = hexpand.into_glib();
415 let mut vexpand_glib = vexpand.into_glib();
416 f(
417 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
418 &mut hexpand_glib,
419 &mut vexpand_glib,
420 );
421 *hexpand = from_glib(hexpand_glib);
422 *vexpand = from_glib(vexpand_glib);
423 }
424 }
425 }
426
427 fn parent_contains(&self, x: f64, y: f64) -> bool {
429 unsafe {
430 let data = Self::type_data();
431 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
432 if let Some(f) = (*parent_class).contains {
433 from_glib(f(
434 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
435 x,
436 y,
437 ))
438 } else {
439 false
440 }
441 }
442 }
443
444 fn parent_direction_changed(&self, previous_direction: TextDirection) {
445 unsafe {
446 let data = Self::type_data();
447 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
448 if let Some(f) = (*parent_class).direction_changed {
449 f(
450 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
451 previous_direction.into_glib(),
452 )
453 }
454 }
455 }
456
457 fn parent_focus(&self, direction_type: DirectionType) -> bool {
459 unsafe {
460 let data = Self::type_data();
461 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
462 if let Some(f) = (*parent_class).focus {
463 from_glib(f(
464 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
465 direction_type.into_glib(),
466 ))
467 } else {
468 false
469 }
470 }
471 }
472
473 fn parent_request_mode(&self) -> SizeRequestMode {
474 unsafe {
475 let data = Self::type_data();
476 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
477 let f = (*parent_class)
478 .get_request_mode
479 .expect("No parent class impl for \"get_request_mode\"");
480 from_glib(f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0))
481 }
482 }
483
484 fn parent_grab_focus(&self) -> bool {
486 unsafe {
487 let data = Self::type_data();
488 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
489 if let Some(f) = (*parent_class).grab_focus {
490 from_glib(f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0))
491 } else {
492 false
493 }
494 }
495 }
496
497 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
498 #[allow(deprecated)]
499 fn parent_hide(&self) {
500 unsafe {
501 let data = Self::type_data();
502 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
503 if let Some(f) = (*parent_class).hide {
504 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
505 }
506 }
507 }
508
509 fn parent_keynav_failed(&self, direction_type: DirectionType) -> bool {
513 unsafe {
514 let data = Self::type_data();
515 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
516 if let Some(f) = (*parent_class).keynav_failed {
517 from_glib(f(
518 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
519 direction_type.into_glib(),
520 ))
521 } else {
522 false
523 }
524 }
525 }
526
527 fn parent_map(&self) {
528 unsafe {
529 let data = Self::type_data();
530 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
531 if let Some(f) = (*parent_class).map {
532 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
533 }
534 }
535 }
536
537 fn parent_measure(&self, orientation: Orientation, for_size: i32) -> (i32, i32, i32, i32) {
538 unsafe {
539 let data = Self::type_data();
540 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
541
542 let f = (*parent_class)
543 .measure
544 .expect("No parent class impl for \"measure\"");
545
546 let mut min = 0;
547 let mut nat = 0;
548 let mut min_base = -1;
549 let mut nat_base = -1;
550 f(
551 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
552 orientation.into_glib(),
553 for_size,
554 &mut min,
555 &mut nat,
556 &mut min_base,
557 &mut nat_base,
558 );
559 (min, nat, min_base, nat_base)
560 }
561 }
562
563 fn parent_mnemonic_activate(&self, group_cycling: bool) -> bool {
565 unsafe {
566 let data = Self::type_data();
567 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
568 if let Some(f) = (*parent_class).mnemonic_activate {
569 from_glib(f(
570 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
571 group_cycling.into_glib(),
572 ))
573 } else {
574 false
575 }
576 }
577 }
578
579 fn parent_move_focus(&self, direction_type: DirectionType) {
580 unsafe {
581 let data = Self::type_data();
582 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
583 if let Some(f) = (*parent_class).move_focus {
584 f(
585 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
586 direction_type.into_glib(),
587 )
588 }
589 }
590 }
591
592 fn parent_query_tooltip(
593 &self,
594 x: i32,
595 y: i32,
596 keyboard_tooltip: bool,
597 tooltip: &Tooltip,
598 ) -> bool {
599 unsafe {
600 let data = Self::type_data();
601 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
602 if let Some(f) = (*parent_class).query_tooltip {
603 from_glib(f(
604 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
605 x,
606 y,
607 keyboard_tooltip.into_glib(),
608 tooltip.to_glib_none().0,
609 ))
610 } else {
611 false
612 }
613 }
614 }
615
616 fn parent_realize(&self) {
617 unsafe {
618 let data = Self::type_data();
619 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
620 if let Some(f) = (*parent_class).realize {
621 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
622 }
623 }
624 }
625
626 fn parent_root(&self) {
627 unsafe {
628 let data = Self::type_data();
629 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
630 if let Some(f) = (*parent_class).root {
631 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
632 }
633 }
634 }
635
636 fn parent_set_focus_child(&self, child: Option<&Widget>) {
637 unsafe {
638 let data = Self::type_data();
639 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
640 if let Some(f) = (*parent_class).set_focus_child {
641 f(
642 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
643 child.to_glib_none().0,
644 )
645 }
646 }
647 }
648
649 #[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
650 #[allow(deprecated)]
651 fn parent_show(&self) {
652 unsafe {
653 let data = Self::type_data();
654 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
655 if let Some(f) = (*parent_class).show {
656 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
657 }
658 }
659 }
660
661 fn parent_size_allocate(&self, width: i32, height: i32, baseline: i32) {
662 unsafe {
663 let data = Self::type_data();
664 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
665 if let Some(f) = (*parent_class).size_allocate {
666 f(
667 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
668 width,
669 height,
670 baseline,
671 )
672 }
673 }
674 }
675
676 fn parent_snapshot(&self, snapshot: &Snapshot) {
677 unsafe {
678 let data = Self::type_data();
679 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
680 if let Some(f) = (*parent_class).snapshot {
681 f(
682 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
683 snapshot.to_glib_none().0,
684 )
685 }
686 }
687 }
688
689 fn parent_state_flags_changed(&self, state_flags: &StateFlags) {
690 unsafe {
691 let data = Self::type_data();
692 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
693 if let Some(f) = (*parent_class).state_flags_changed {
694 f(
695 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
696 state_flags.into_glib(),
697 )
698 }
699 }
700 }
701
702 fn parent_system_setting_changed(&self, settings: &SystemSetting) {
703 unsafe {
704 let data = Self::type_data();
705 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
706 if let Some(f) = (*parent_class).system_setting_changed {
707 f(
708 self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0,
709 settings.into_glib(),
710 )
711 }
712 }
713 }
714
715 fn parent_unmap(&self) {
716 unsafe {
717 let data = Self::type_data();
718 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
719 if let Some(f) = (*parent_class).unmap {
720 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
721 }
722 }
723 }
724
725 fn parent_unrealize(&self) {
726 unsafe {
727 let data = Self::type_data();
728 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
729 if let Some(f) = (*parent_class).unrealize {
730 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
731 }
732 }
733 }
734
735 fn parent_unroot(&self) {
736 unsafe {
737 let data = Self::type_data();
738 let parent_class = data.as_ref().parent_class() as *mut ffi::GtkWidgetClass;
739 if let Some(f) = (*parent_class).unroot {
740 f(self.obj().unsafe_cast_ref::<Widget>().to_glib_none().0)
741 }
742 }
743 }
744}
745
746impl<T: WidgetImpl> WidgetImplExt for T {}
747
748unsafe impl<T: WidgetImpl> IsSubclassable<T> for Widget {
749 fn class_init(class: &mut ::glib::Class<Self>) {
750 Self::parent_class_init::<T>(class);
751
752 assert_initialized_main_thread!();
753
754 let klass = class.as_mut();
755 unsafe {
756 let mut data = T::type_data();
757 let data = data.as_mut();
758 data.set_class_data(<T as ObjectSubclassType>::type_(), Internal::default());
760 }
761
762 klass.compute_expand = Some(widget_compute_expand::<T>);
763 klass.contains = Some(widget_contains::<T>);
764 klass.direction_changed = Some(widget_direction_changed::<T>);
765 klass.focus = Some(widget_focus::<T>);
766 klass.get_request_mode = Some(widget_get_request_mode::<T>);
767 klass.grab_focus = Some(widget_grab_focus::<T>);
768 klass.hide = Some(widget_hide::<T>);
769 klass.keynav_failed = Some(widget_keynav_failed::<T>);
770 klass.map = Some(widget_map::<T>);
771 klass.measure = Some(widget_measure::<T>);
772 klass.mnemonic_activate = Some(widget_mnemonic_activate::<T>);
773 klass.move_focus = Some(widget_move_focus::<T>);
774 klass.query_tooltip = Some(widget_query_tooltip::<T>);
775 klass.realize = Some(widget_realize::<T>);
776 klass.root = Some(widget_root::<T>);
777 klass.set_focus_child = Some(widget_set_focus_child::<T>);
778 klass.show = Some(widget_show::<T>);
779 klass.size_allocate = Some(widget_size_allocate::<T>);
780 klass.snapshot = Some(widget_snapshot::<T>);
781 klass.state_flags_changed = Some(widget_state_flags_changed::<T>);
782 klass.system_setting_changed = Some(widget_system_setting_changed::<T>);
783 klass.unmap = Some(widget_unmap::<T>);
784 klass.unrealize = Some(widget_unrealize::<T>);
785 klass.unroot = Some(widget_unroot::<T>);
786 }
787}
788
789unsafe extern "C" fn widget_compute_expand<T: WidgetImpl>(
790 ptr: *mut ffi::GtkWidget,
791 hexpand_ptr: *mut glib::ffi::gboolean,
792 vexpand_ptr: *mut glib::ffi::gboolean,
793) {
794 let instance = &*(ptr as *mut T::Instance);
795 let imp = instance.imp();
796
797 let widget = imp.obj();
798 let widget = widget.unsafe_cast_ref::<Widget>();
799 let mut hexpand: bool = if widget.is_hexpand_set() {
800 widget.hexpands()
801 } else {
802 from_glib(*hexpand_ptr)
803 };
804 let mut vexpand: bool = if widget.is_vexpand_set() {
805 widget.vexpands()
806 } else {
807 from_glib(*vexpand_ptr)
808 };
809
810 imp.compute_expand(&mut hexpand, &mut vexpand);
811
812 *hexpand_ptr = hexpand.into_glib();
813 *vexpand_ptr = vexpand.into_glib();
814}
815
816unsafe extern "C" fn widget_contains<T: WidgetImpl>(
817 ptr: *mut ffi::GtkWidget,
818 x: f64,
819 y: f64,
820) -> glib::ffi::gboolean {
821 let instance = &*(ptr as *mut T::Instance);
822 let imp = instance.imp();
823
824 imp.contains(x, y).into_glib()
825}
826
827unsafe extern "C" fn widget_direction_changed<T: WidgetImpl>(
828 ptr: *mut ffi::GtkWidget,
829 direction_ptr: ffi::GtkTextDirection,
830) {
831 let instance = &*(ptr as *mut T::Instance);
832 let imp = instance.imp();
833 let direction_wrap = from_glib(direction_ptr);
834
835 imp.direction_changed(direction_wrap)
836}
837
838unsafe extern "C" fn widget_focus<T: WidgetImpl>(
839 ptr: *mut ffi::GtkWidget,
840 direction_type_ptr: ffi::GtkDirectionType,
841) -> glib::ffi::gboolean {
842 let instance = &*(ptr as *mut T::Instance);
843 let imp = instance.imp();
844 let direction_type = from_glib(direction_type_ptr);
845
846 imp.focus(direction_type).into_glib()
847}
848
849unsafe extern "C" fn widget_get_request_mode<T: WidgetImpl>(
850 ptr: *mut ffi::GtkWidget,
851) -> ffi::GtkSizeRequestMode {
852 let instance = &*(ptr as *mut T::Instance);
853 let imp = instance.imp();
854
855 imp.request_mode().into_glib()
856}
857
858unsafe extern "C" fn widget_grab_focus<T: WidgetImpl>(
859 ptr: *mut ffi::GtkWidget,
860) -> glib::ffi::gboolean {
861 let instance = &*(ptr as *mut T::Instance);
862 let imp = instance.imp();
863
864 imp.grab_focus().into_glib()
865}
866
867unsafe extern "C" fn widget_hide<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
868 let instance = &*(ptr as *mut T::Instance);
869 let imp = instance.imp();
870
871 imp.hide()
872}
873
874unsafe extern "C" fn widget_keynav_failed<T: WidgetImpl>(
875 ptr: *mut ffi::GtkWidget,
876 direction_type_ptr: ffi::GtkDirectionType,
877) -> glib::ffi::gboolean {
878 let instance = &*(ptr as *mut T::Instance);
879 let imp = instance.imp();
880 let direction_type = from_glib(direction_type_ptr);
881
882 imp.keynav_failed(direction_type).into_glib()
883}
884
885unsafe extern "C" fn widget_map<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
886 let instance = &*(ptr as *mut T::Instance);
887 let imp = instance.imp();
888
889 imp.map()
890}
891
892unsafe extern "C" fn widget_measure<T: WidgetImpl>(
893 ptr: *mut ffi::GtkWidget,
894 orientation_ptr: ffi::GtkOrientation,
895 for_size: i32,
896 min_ptr: *mut libc::c_int,
897 nat_ptr: *mut libc::c_int,
898 min_base_ptr: *mut libc::c_int,
899 nat_base_ptr: *mut libc::c_int,
900) {
901 let instance = &*(ptr as *mut T::Instance);
902 let imp = instance.imp();
903 let orientation = from_glib(orientation_ptr);
904 let (min, nat, min_base, nat_base) = imp.measure(orientation, for_size);
905 if !min_ptr.is_null() {
906 *min_ptr = min;
907 }
908 if !nat_ptr.is_null() {
909 *nat_ptr = nat;
910 }
911 if !min_base_ptr.is_null() {
912 *min_base_ptr = min_base;
913 }
914 if !nat_base_ptr.is_null() {
915 *nat_base_ptr = nat_base;
916 }
917}
918
919unsafe extern "C" fn widget_mnemonic_activate<T: WidgetImpl>(
920 ptr: *mut ffi::GtkWidget,
921 group_cycling_ptr: glib::ffi::gboolean,
922) -> glib::ffi::gboolean {
923 let instance = &*(ptr as *mut T::Instance);
924 let imp = instance.imp();
925 let group_cycling: bool = from_glib(group_cycling_ptr);
926
927 imp.mnemonic_activate(group_cycling).into_glib()
928}
929
930unsafe extern "C" fn widget_move_focus<T: WidgetImpl>(
931 ptr: *mut ffi::GtkWidget,
932 direction_type_ptr: ffi::GtkDirectionType,
933) {
934 let instance = &*(ptr as *mut T::Instance);
935 let imp = instance.imp();
936 let direction_type = from_glib(direction_type_ptr);
937
938 imp.move_focus(direction_type)
939}
940
941unsafe extern "C" fn widget_query_tooltip<T: WidgetImpl>(
942 ptr: *mut ffi::GtkWidget,
943 x: i32,
944 y: i32,
945 keyboard_tooltip_ptr: glib::ffi::gboolean,
946 tooltip_ptr: *mut ffi::GtkTooltip,
947) -> glib::ffi::gboolean {
948 let instance = &*(ptr as *mut T::Instance);
949 let imp = instance.imp();
950
951 let keyboard_tooltip: bool = from_glib(keyboard_tooltip_ptr);
952 let tooltip = from_glib_borrow(tooltip_ptr);
953
954 imp.query_tooltip(x, y, keyboard_tooltip, &tooltip)
955 .into_glib()
956}
957
958unsafe extern "C" fn widget_realize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
959 let instance = &*(ptr as *mut T::Instance);
960 let imp = instance.imp();
961
962 imp.realize()
963}
964
965unsafe extern "C" fn widget_root<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
966 let instance = &*(ptr as *mut T::Instance);
967 let imp = instance.imp();
968
969 imp.root()
970}
971
972unsafe extern "C" fn widget_set_focus_child<T: WidgetImpl>(
973 ptr: *mut ffi::GtkWidget,
974 child_ptr: *mut ffi::GtkWidget,
975) {
976 let instance = &*(ptr as *mut T::Instance);
977 let imp = instance.imp();
978 let child: Borrowed<Option<Widget>> = from_glib_borrow(child_ptr);
979
980 imp.set_focus_child(child.as_ref().as_ref())
981}
982
983unsafe extern "C" fn widget_show<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
984 let instance = &*(ptr as *mut T::Instance);
985 let imp = instance.imp();
986
987 imp.show()
988}
989
990unsafe extern "C" fn widget_size_allocate<T: WidgetImpl>(
991 ptr: *mut ffi::GtkWidget,
992 width: i32,
993 height: i32,
994 baseline: i32,
995) {
996 let instance = &*(ptr as *mut T::Instance);
997 let imp = instance.imp();
998
999 imp.size_allocate(width, height, baseline)
1000}
1001
1002unsafe extern "C" fn widget_snapshot<T: WidgetImpl>(
1003 ptr: *mut ffi::GtkWidget,
1004 snapshot_ptr: *mut ffi::GtkSnapshot,
1005) {
1006 let instance = &*(ptr as *mut T::Instance);
1007 let imp = instance.imp();
1008 let snapshot = from_glib_borrow(snapshot_ptr);
1009
1010 imp.snapshot(&snapshot)
1011}
1012
1013unsafe extern "C" fn widget_state_flags_changed<T: WidgetImpl>(
1014 ptr: *mut ffi::GtkWidget,
1015 state_flags_ptr: ffi::GtkStateFlags,
1016) {
1017 let instance = &*(ptr as *mut T::Instance);
1018 let imp = instance.imp();
1019 let state_flags = from_glib(state_flags_ptr);
1020
1021 imp.state_flags_changed(&state_flags)
1022}
1023
1024unsafe extern "C" fn widget_system_setting_changed<T: WidgetImpl>(
1025 ptr: *mut ffi::GtkWidget,
1026 settings_ptr: ffi::GtkSystemSetting,
1027) {
1028 let instance = &*(ptr as *mut T::Instance);
1029 let imp = instance.imp();
1030 let settings = from_glib(settings_ptr);
1031
1032 imp.system_setting_changed(&settings)
1033}
1034
1035unsafe extern "C" fn widget_unmap<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1036 let instance = &*(ptr as *mut T::Instance);
1037 let imp = instance.imp();
1038
1039 imp.unmap()
1040}
1041
1042unsafe extern "C" fn widget_unrealize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1043 let instance = &*(ptr as *mut T::Instance);
1044 let imp = instance.imp();
1045
1046 imp.unrealize()
1047}
1048
1049unsafe extern "C" fn widget_unroot<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1050 let instance = &*(ptr as *mut T::Instance);
1051 let imp = instance.imp();
1052
1053 imp.unroot()
1054}
1055
1056#[allow(clippy::missing_safety_doc)]
1057pub unsafe trait WidgetClassExt: ClassStruct {
1058 #[doc(alias = "gtk_widget_class_set_template")]
1059 fn set_template_bytes(&mut self, template: &glib::Bytes) {
1060 unsafe {
1061 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1062 ffi::gtk_widget_class_set_template(widget_class, template.to_glib_none().0);
1063 }
1064 }
1065
1066 fn set_template(&mut self, template: &[u8]) {
1077 let template_bytes = glib::Bytes::from(template);
1078 self.set_template_bytes(&template_bytes);
1079 }
1080
1081 fn set_template_static(&mut self, template: &'static [u8]) {
1082 let template_bytes = glib::Bytes::from_static(template);
1083 self.set_template_bytes(&template_bytes);
1084 }
1085
1086 #[doc(alias = "gtk_widget_class_set_template_from_resource")]
1095 fn set_template_from_resource(&mut self, resource_name: &str) {
1096 unsafe {
1097 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1098 ffi::gtk_widget_class_set_template_from_resource(
1099 widget_class,
1100 resource_name.to_glib_none().0,
1101 );
1102 }
1103 }
1104
1105 fn install_action_async<Fut, F>(
1106 &mut self,
1107 action_name: &str,
1108 parameter_type: Option<&glib::VariantTy>,
1109 activate: F,
1110 ) where
1111 F: Fn(
1112 <<Self as ClassStruct>::Type as ObjectSubclass>::Type,
1113 String,
1114 Option<Variant>,
1115 ) -> Fut
1116 + 'static
1117 + Clone,
1118 Fut: Future<Output = ()>,
1119 {
1120 self.install_action(
1121 action_name,
1122 parameter_type,
1123 move |this, action_name, parameter_type| {
1124 let ctx = glib::MainContext::default();
1125 let action_name = action_name.to_owned();
1126 let parameter_type = parameter_type.map(ToOwned::to_owned);
1127 ctx.spawn_local(glib::clone!(
1128 #[strong]
1129 this,
1130 #[strong]
1131 action_name,
1132 #[strong]
1133 parameter_type,
1134 #[strong]
1135 activate,
1136 async move {
1137 activate(this, action_name, parameter_type).await;
1138 }
1139 ));
1140 },
1141 );
1142 }
1143
1144 #[doc(alias = "gtk_widget_class_install_action")]
1158 fn install_action<F>(
1159 &mut self,
1160 action_name: &str,
1161 parameter_type: Option<&glib::VariantTy>,
1162 activate: F,
1163 ) where
1164 F: Fn(&<<Self as ClassStruct>::Type as ObjectSubclass>::Type, &str, Option<&Variant>)
1165 + 'static,
1166 {
1167 unsafe {
1168 let mut data = <Self::Type as ObjectSubclassType>::type_data();
1171 let data = data.as_mut();
1172
1173 let f: Box_<F> = Box_::new(activate);
1174
1175 let internal = data
1176 .class_data_mut::<Internal>(<Self::Type as ObjectSubclassType>::type_())
1177 .expect("Something bad happened at class_init, the internal class_data is missing");
1178 let callback_ptr = Box_::into_raw(f) as glib::ffi::gpointer;
1179 internal
1180 .actions
1181 .insert(action_name.to_string(), callback_ptr);
1182
1183 unsafe extern "C" fn activate_trampoline<F, S>(
1184 this: *mut ffi::GtkWidget,
1185 action_name: *const libc::c_char,
1186 parameter: *mut glib::ffi::GVariant,
1187 ) where
1188 S: ClassStruct,
1189 <S as ClassStruct>::Type: ObjectSubclass,
1190 F: Fn(&<<S as ClassStruct>::Type as ObjectSubclass>::Type, &str, Option<&Variant>)
1191 + 'static,
1192 {
1193 let action_name = GString::from_glib_borrow(action_name);
1194
1195 let data = <S::Type as ObjectSubclassType>::type_data();
1196 let internal = data
1197 .as_ref()
1198 .class_data::<Internal>(<S::Type as ObjectSubclassType>::type_())
1199 .unwrap();
1200 let activate_callback = *internal
1201 .actions
1202 .get(&action_name.to_string())
1203 .unwrap_or_else(|| {
1204 panic!("Action name '{}' was not found", action_name.as_str());
1205 });
1206
1207 let widget = Widget::from_glib_borrow(this);
1208
1209 let f: &F = &*(activate_callback as *const F);
1210 f(
1211 widget.unsafe_cast_ref(),
1212 &action_name,
1213 Option::<Variant>::from_glib_borrow(parameter)
1214 .as_ref()
1215 .as_ref(),
1216 )
1217 }
1218 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1219 let callback = activate_trampoline::<F, Self>;
1220 ffi::gtk_widget_class_install_action(
1221 widget_class,
1222 action_name.to_glib_none().0,
1223 parameter_type.map(|p| p.as_str()).to_glib_none().0,
1224 Some(callback),
1225 );
1226 }
1227 }
1228
1229 #[doc(alias = "gtk_widget_class_query_action")]
1257 fn query_action(&self) -> WidgetActionIter {
1258 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1259 WidgetActionIter(widget_class, 0)
1260 }
1261
1262 #[doc(alias = "gtk_widget_class_set_template_scope")]
1272 fn set_template_scope<S: IsA<BuilderScope>>(&mut self, scope: &S) {
1273 unsafe {
1274 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1275 ffi::gtk_widget_class_set_template_scope(widget_class, scope.as_ref().to_glib_none().0);
1276 }
1277 }
1278
1279 #[doc(alias = "gtk_widget_class_add_binding")]
1299 fn add_binding<
1300 F: Fn(&<<Self as ClassStruct>::Type as ObjectSubclass>::Type) -> glib::Propagation + 'static,
1301 >(
1302 &mut self,
1303 keyval: gdk::Key,
1304 mods: gdk::ModifierType,
1305 callback: F,
1306 ) {
1307 let shortcut = crate::Shortcut::new(
1308 Some(crate::KeyvalTrigger::new(keyval, mods)),
1309 Some(crate::CallbackAction::new(
1310 move |widget, _| -> glib::Propagation {
1311 unsafe { callback(widget.unsafe_cast_ref()) }
1312 },
1313 )),
1314 );
1315 self.add_shortcut(&shortcut);
1316 }
1317
1318 #[doc(alias = "gtk_widget_class_add_binding_action")]
1336 fn add_binding_action(&mut self, keyval: gdk::Key, mods: gdk::ModifierType, action_name: &str) {
1337 let shortcut = crate::Shortcut::new(
1338 Some(crate::KeyvalTrigger::new(keyval, mods)),
1339 Some(crate::NamedAction::new(action_name)),
1340 );
1341 self.add_shortcut(&shortcut);
1342 }
1343
1344 #[doc(alias = "gtk_widget_class_add_binding_signal")]
1362 fn add_binding_signal(&mut self, keyval: gdk::Key, mods: gdk::ModifierType, signal_name: &str) {
1363 let type_ = <Self::Type as ObjectSubclassType>::type_();
1364 assert!(
1365 SignalId::lookup(signal_name, type_).is_some(),
1366 "Signal '{signal_name}' doesn't exists for type '{type_}'",
1367 );
1368
1369 let shortcut = crate::Shortcut::new(
1370 Some(crate::KeyvalTrigger::new(keyval, mods)),
1371 Some(crate::SignalAction::new(signal_name)),
1372 );
1373 self.add_shortcut(&shortcut);
1374 }
1375
1376 #[doc(alias = "gtk_widget_class_add_shortcut")]
1389 fn add_shortcut(&mut self, shortcut: &Shortcut) {
1390 unsafe {
1391 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1392 ffi::gtk_widget_class_add_shortcut(widget_class, shortcut.to_glib_none().0);
1393 }
1394 }
1395
1396 #[doc(alias = "gtk_widget_class_install_property_action")]
1417 fn install_property_action(&mut self, action_name: &str, property_name: &str) {
1418 unsafe {
1419 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1420 ffi::gtk_widget_class_install_property_action(
1421 widget_class,
1422 action_name.to_glib_none().0,
1423 property_name.to_glib_none().0,
1424 );
1425 }
1426 }
1427
1428 #[doc(alias = "gtk_widget_class_get_activate_signal")]
1438 #[doc(alias = "get_activate_signal")]
1439 fn activate_signal(&self) -> Option<SignalId> {
1440 unsafe {
1441 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1442 let signal_id = ffi::gtk_widget_class_get_activate_signal(widget_class);
1443 if signal_id == 0 {
1444 None
1445 } else {
1446 Some(from_glib(signal_id))
1447 }
1448 }
1449 }
1450
1451 #[doc(alias = "gtk_widget_class_set_activate_signal")]
1460 fn set_activate_signal(&mut self, signal_id: SignalId) {
1461 unsafe {
1462 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1463 ffi::gtk_widget_class_set_activate_signal(widget_class, signal_id.into_glib())
1464 }
1465 }
1466
1467 #[doc(alias = "gtk_widget_class_set_activate_signal_from_name")]
1478 fn set_activate_signal_from_name(&mut self, signal_name: &str) {
1479 let type_ = <Self::Type as ObjectSubclassType>::type_();
1480 assert!(
1481 SignalId::lookup(signal_name, type_).is_some(),
1482 "Signal '{signal_name}' doesn't exists for type '{type_}'",
1483 );
1484
1485 unsafe {
1486 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1487 ffi::gtk_widget_class_set_activate_signal_from_name(
1488 widget_class,
1489 signal_name.to_glib_none().0,
1490 );
1491 }
1492 }
1493
1494 #[doc(alias = "gtk_widget_class_set_layout_manager_type")]
1505 fn set_layout_manager_type<T: IsA<LayoutManager>>(&mut self) {
1506 unsafe {
1507 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1508 ffi::gtk_widget_class_set_layout_manager_type(
1509 widget_class,
1510 T::static_type().into_glib(),
1511 );
1512 }
1513 }
1514
1515 #[doc(alias = "gtk_widget_class_get_layout_manager_type")]
1524 #[doc(alias = "get_layout_manager_type")]
1525 fn layout_manager_type(&self) -> glib::Type {
1526 unsafe {
1527 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1528 from_glib(ffi::gtk_widget_class_get_layout_manager_type(widget_class))
1529 }
1530 }
1531
1532 #[doc(alias = "gtk_widget_class_set_css_name")]
1540 fn set_css_name(&mut self, name: &str) {
1541 unsafe {
1542 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1543 ffi::gtk_widget_class_set_css_name(widget_class, name.to_glib_none().0);
1544 }
1545 }
1546
1547 #[doc(alias = "gtk_widget_class_get_css_name")]
1555 #[doc(alias = "get_css_name")]
1556 fn css_name(&self) -> glib::GString {
1557 unsafe {
1558 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1559 from_glib_none(ffi::gtk_widget_class_get_css_name(widget_class))
1560 }
1561 }
1562
1563 #[doc(alias = "gtk_widget_class_set_accessible_role")]
1570 fn set_accessible_role(&mut self, role: AccessibleRole) {
1571 unsafe {
1572 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1573 ffi::gtk_widget_class_set_accessible_role(widget_class, role.into_glib());
1574 }
1575 }
1576
1577 #[doc(alias = "gtk_widget_class_get_accessible_role")]
1588 #[doc(alias = "get_accessible_role")]
1589 fn accessible_role(&self) -> AccessibleRole {
1590 unsafe {
1591 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1592 from_glib(ffi::gtk_widget_class_get_accessible_role(widget_class))
1593 }
1594 }
1595
1596 #[allow(clippy::missing_safety_doc)]
1597 #[doc(alias = "gtk_widget_class_bind_template_child_full")]
1598 unsafe fn bind_template_child_with_offset<T>(
1599 &mut self,
1600 name: &str,
1601 internal: bool,
1602 offset: field_offset::FieldOffset<Self::Type, TemplateChild<T>>,
1603 ) where
1604 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1605 {
1606 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1607 let private_offset = <Self::Type as ObjectSubclassType>::type_data()
1608 .as_ref()
1609 .impl_offset();
1610 ffi::gtk_widget_class_bind_template_child_full(
1611 widget_class,
1612 name.to_glib_none().0,
1613 internal.into_glib(),
1614 private_offset + (offset.get_byte_offset() as isize),
1615 )
1616 }
1617
1618 fn rust_template_scope(&mut self) -> BuilderRustScope {
1619 assert_initialized_main_thread!();
1620 unsafe {
1621 let mut data = <Self::Type as ObjectSubclassType>::type_data();
1622 let internal = data
1623 .as_mut()
1624 .class_data_mut::<Internal>(<Self::Type as ObjectSubclassType>::type_())
1625 .expect("Something bad happened at class_init, the internal class_data is missing");
1626 let scope = internal.scope.get_or_insert_with(|| {
1627 let scope = BuilderRustScope::new();
1628 self.set_template_scope(&scope);
1629 scope.into_glib_ptr()
1630 });
1631 from_glib_none(*scope)
1632 }
1633 }
1634}
1635
1636unsafe impl<T: ClassStruct> WidgetClassExt for T where T::Type: WidgetImpl {}
1637
1638#[derive(Debug, PartialEq, Eq)]
1639#[repr(transparent)]
1640pub struct TemplateChild<T>
1641where
1642 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1643{
1644 ptr: *mut <T as ObjectType>::GlibType,
1645}
1646
1647impl<T: Property> Property for TemplateChild<T>
1648where
1649 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1650{
1651 type Value = T::Value;
1652}
1653
1654impl<T> Default for TemplateChild<T>
1655where
1656 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1657{
1658 fn default() -> Self {
1659 T::static_type();
1660
1661 Self {
1662 ptr: std::ptr::null_mut(),
1663 }
1664 }
1665}
1666
1667impl<T> PropertyGet for TemplateChild<T>
1668where
1669 T: Property + ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1670{
1671 type Value = T;
1672
1673 fn get<R, F: Fn(&Self::Value) -> R>(&self, f: F) -> R {
1674 f(&self.get())
1675 }
1676}
1677
1678impl<T> std::ops::Deref for TemplateChild<T>
1679where
1680 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1681{
1682 type Target = T;
1683
1684 #[inline]
1685 fn deref(&self) -> &Self::Target {
1686 unsafe {
1687 if !self.is_bound() {
1688 let name = Self::name();
1689 panic!("Failed to retrieve template child. Please check that all fields of type `{name}` have been bound and have a #[template_child] attribute.");
1690 }
1691 &*(&self.ptr as *const _ as *const T)
1692 }
1693 }
1694}
1695
1696impl<T> Downgrade for TemplateChild<T>
1697where
1698 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType> + Downgrade,
1699{
1700 type Weak = T::Weak;
1701
1702 fn downgrade(&self) -> Self::Weak {
1703 T::downgrade(&self.get())
1704 }
1705}
1706
1707impl<T> TemplateChild<T>
1708where
1709 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1710{
1711 pub(crate) fn name<'a>() -> &'a str {
1712 T::static_type().name()
1713 }
1714
1715 #[track_caller]
1716 pub fn get(&self) -> T {
1717 self.try_get()
1718 .unwrap_or_else(|| {
1719 let name = Self::name();
1720 panic!("Failed to retrieve template child. Please check that all fields of type `{name}` have been bound and have a #[template_child] attribute.");
1721 })
1722 }
1723
1724 pub fn is_bound(&self) -> bool {
1728 !self.ptr.is_null()
1729 }
1730
1731 pub fn try_get(&self) -> Option<T> {
1734 unsafe { Option::<T>::from_glib_none(self.ptr) }
1735 }
1736}
1737
1738pub trait CompositeTemplate: WidgetImpl {
1744 fn bind_template(klass: &mut Self::Class);
1745 fn check_template_children(widget: &<Self as ObjectSubclass>::Type);
1746}
1747
1748pub trait CompositeTemplateClass {
1753 fn bind_template(&mut self);
1757}
1758
1759impl<T, U> CompositeTemplateClass for T
1760where
1761 T: ClassStruct<Type = U>,
1762 U: ObjectSubclass<Class = T> + CompositeTemplate,
1763{
1764 fn bind_template(&mut self) {
1765 <U as CompositeTemplate>::bind_template(self);
1766 }
1767}
1768
1769pub type TemplateCallback = (&'static str, fn(&[glib::Value]) -> Option<glib::Value>);
1770
1771pub trait CompositeTemplateCallbacks {
1777 const CALLBACKS: &'static [TemplateCallback];
1778
1779 fn bind_template_callbacks<T: WidgetClassExt>(klass: &mut T) {
1783 Self::add_callbacks_to_scope(&klass.rust_template_scope());
1784 }
1785 fn bind_template_callbacks_prefixed<T: WidgetClassExt>(klass: &mut T, prefix: &str) {
1789 Self::add_callbacks_to_scope_prefixed(&klass.rust_template_scope(), prefix);
1790 }
1791 fn add_callbacks_to_scope(scope: &BuilderRustScope) {
1794 for (name, func) in Self::CALLBACKS {
1795 scope.add_callback(*name, func);
1796 }
1797 }
1798 fn add_callbacks_to_scope_prefixed(scope: &BuilderRustScope, prefix: &str) {
1802 for (name, func) in Self::CALLBACKS {
1803 scope.add_callback(format!("{prefix}{name}"), func);
1804 }
1805 }
1806}
1807
1808pub trait CompositeTemplateCallbacksClass {
1813 fn bind_template_callbacks(&mut self);
1817}
1818
1819impl<T, U> CompositeTemplateCallbacksClass for T
1820where
1821 T: ClassStruct<Type = U> + WidgetClassExt,
1822 U: ObjectSubclass<Class = T> + CompositeTemplateCallbacks,
1823{
1824 fn bind_template_callbacks(&mut self) {
1825 <U as CompositeTemplateCallbacks>::bind_template_callbacks(self);
1826 }
1827}
1828
1829pub trait CompositeTemplateInstanceCallbacksClass {
1835 fn bind_template_instance_callbacks(&mut self);
1839}
1840
1841impl<T, U, V> CompositeTemplateInstanceCallbacksClass for T
1842where
1843 T: ClassStruct<Type = U> + WidgetClassExt,
1844 U: ObjectSubclass<Class = T, Type = V>,
1845 V: CompositeTemplateCallbacks,
1846{
1847 fn bind_template_instance_callbacks(&mut self) {
1848 <V as CompositeTemplateCallbacks>::bind_template_callbacks(self);
1849 }
1850}
1851
1852pub trait CompositeTemplateInitializingExt {
1853 fn init_template(&self);
1854}
1855
1856impl<T> CompositeTemplateInitializingExt for glib::subclass::InitializingObject<T>
1857where
1858 T: WidgetImpl + CompositeTemplate,
1859 <T as ObjectSubclass>::Type: IsA<Widget>,
1860{
1861 fn init_template(&self) {
1862 unsafe {
1863 let widget = self
1864 .as_ref()
1865 .unsafe_cast_ref::<<T as ObjectSubclass>::Type>();
1866 ffi::gtk_widget_init_template(widget.as_ref().to_glib_none().0);
1867
1868 <T as CompositeTemplate>::check_template_children(widget);
1869 }
1870 }
1871}
1872
1873pub trait CompositeTemplateDisposeExt {
1874 #[cfg(feature = "v4_8")]
1875 #[cfg_attr(docsrs, doc(cfg(feature = "v4_8")))]
1876 fn dispose_template(&self);
1877}
1878
1879impl<T> CompositeTemplateDisposeExt for T
1880where
1881 T: WidgetImpl + CompositeTemplate,
1882 <T as ObjectSubclass>::Type: IsA<Widget>,
1883{
1884 #[cfg(feature = "v4_8")]
1885 #[cfg_attr(docsrs, doc(cfg(feature = "v4_8")))]
1886 fn dispose_template(&self) {
1887 unsafe {
1888 ffi::gtk_widget_dispose_template(
1889 self.obj().upcast_ref::<Widget>().to_glib_none().0,
1890 <T as ObjectSubclass>::Type::static_type().into_glib(),
1891 );
1892 }
1893 }
1894}