1use std::{boxed::Box as Box_, collections::HashMap, fmt, future::Future};
7
8use glib::{
9 GString, Variant,
10 clone::Downgrade,
11 property::{Property, PropertyGet},
12 subclass::SignalId,
13 translate::*,
14};
15
16use crate::{
17 Accessible, AccessibleRole, Buildable, BuilderRustScope, BuilderScope, ConstraintTarget,
18 DirectionType, LayoutManager, Orientation, Shortcut, SizeRequestMode, Snapshot, StateFlags,
19 SystemSetting, TextDirection, Tooltip, Widget, ffi, prelude::*, subclass::prelude::*,
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 unsafe {
793 let instance = &*(ptr as *mut T::Instance);
794 let imp = instance.imp();
795
796 let widget = imp.obj();
797 let widget = widget.unsafe_cast_ref::<Widget>();
798 let mut hexpand: bool = if widget.is_hexpand_set() {
799 widget.hexpands()
800 } else {
801 from_glib(*hexpand_ptr)
802 };
803 let mut vexpand: bool = if widget.is_vexpand_set() {
804 widget.vexpands()
805 } else {
806 from_glib(*vexpand_ptr)
807 };
808
809 imp.compute_expand(&mut hexpand, &mut vexpand);
810
811 *hexpand_ptr = hexpand.into_glib();
812 *vexpand_ptr = vexpand.into_glib();
813 }
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 unsafe {
822 let instance = &*(ptr as *mut T::Instance);
823 let imp = instance.imp();
824
825 imp.contains(x, y).into_glib()
826 }
827}
828
829unsafe extern "C" fn widget_direction_changed<T: WidgetImpl>(
830 ptr: *mut ffi::GtkWidget,
831 direction_ptr: ffi::GtkTextDirection,
832) {
833 unsafe {
834 let instance = &*(ptr as *mut T::Instance);
835 let imp = instance.imp();
836 let direction_wrap = from_glib(direction_ptr);
837
838 imp.direction_changed(direction_wrap)
839 }
840}
841
842unsafe extern "C" fn widget_focus<T: WidgetImpl>(
843 ptr: *mut ffi::GtkWidget,
844 direction_type_ptr: ffi::GtkDirectionType,
845) -> glib::ffi::gboolean {
846 unsafe {
847 let instance = &*(ptr as *mut T::Instance);
848 let imp = instance.imp();
849 let direction_type = from_glib(direction_type_ptr);
850
851 imp.focus(direction_type).into_glib()
852 }
853}
854
855unsafe extern "C" fn widget_get_request_mode<T: WidgetImpl>(
856 ptr: *mut ffi::GtkWidget,
857) -> ffi::GtkSizeRequestMode {
858 unsafe {
859 let instance = &*(ptr as *mut T::Instance);
860 let imp = instance.imp();
861
862 imp.request_mode().into_glib()
863 }
864}
865
866unsafe extern "C" fn widget_grab_focus<T: WidgetImpl>(
867 ptr: *mut ffi::GtkWidget,
868) -> glib::ffi::gboolean {
869 unsafe {
870 let instance = &*(ptr as *mut T::Instance);
871 let imp = instance.imp();
872
873 imp.grab_focus().into_glib()
874 }
875}
876
877unsafe extern "C" fn widget_hide<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
878 unsafe {
879 let instance = &*(ptr as *mut T::Instance);
880 let imp = instance.imp();
881
882 imp.hide()
883 }
884}
885
886unsafe extern "C" fn widget_keynav_failed<T: WidgetImpl>(
887 ptr: *mut ffi::GtkWidget,
888 direction_type_ptr: ffi::GtkDirectionType,
889) -> glib::ffi::gboolean {
890 unsafe {
891 let instance = &*(ptr as *mut T::Instance);
892 let imp = instance.imp();
893 let direction_type = from_glib(direction_type_ptr);
894
895 imp.keynav_failed(direction_type).into_glib()
896 }
897}
898
899unsafe extern "C" fn widget_map<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
900 unsafe {
901 let instance = &*(ptr as *mut T::Instance);
902 let imp = instance.imp();
903
904 imp.map()
905 }
906}
907
908unsafe extern "C" fn widget_measure<T: WidgetImpl>(
909 ptr: *mut ffi::GtkWidget,
910 orientation_ptr: ffi::GtkOrientation,
911 for_size: i32,
912 min_ptr: *mut libc::c_int,
913 nat_ptr: *mut libc::c_int,
914 min_base_ptr: *mut libc::c_int,
915 nat_base_ptr: *mut libc::c_int,
916) {
917 unsafe {
918 let instance = &*(ptr as *mut T::Instance);
919 let imp = instance.imp();
920 let orientation = from_glib(orientation_ptr);
921 let (min, nat, min_base, nat_base) = imp.measure(orientation, for_size);
922 if !min_ptr.is_null() {
923 *min_ptr = min;
924 }
925 if !nat_ptr.is_null() {
926 *nat_ptr = nat;
927 }
928 if !min_base_ptr.is_null() {
929 *min_base_ptr = min_base;
930 }
931 if !nat_base_ptr.is_null() {
932 *nat_base_ptr = nat_base;
933 }
934 }
935}
936
937unsafe extern "C" fn widget_mnemonic_activate<T: WidgetImpl>(
938 ptr: *mut ffi::GtkWidget,
939 group_cycling_ptr: glib::ffi::gboolean,
940) -> glib::ffi::gboolean {
941 unsafe {
942 let instance = &*(ptr as *mut T::Instance);
943 let imp = instance.imp();
944 let group_cycling: bool = from_glib(group_cycling_ptr);
945
946 imp.mnemonic_activate(group_cycling).into_glib()
947 }
948}
949
950unsafe extern "C" fn widget_move_focus<T: WidgetImpl>(
951 ptr: *mut ffi::GtkWidget,
952 direction_type_ptr: ffi::GtkDirectionType,
953) {
954 unsafe {
955 let instance = &*(ptr as *mut T::Instance);
956 let imp = instance.imp();
957 let direction_type = from_glib(direction_type_ptr);
958
959 imp.move_focus(direction_type)
960 }
961}
962
963unsafe extern "C" fn widget_query_tooltip<T: WidgetImpl>(
964 ptr: *mut ffi::GtkWidget,
965 x: i32,
966 y: i32,
967 keyboard_tooltip_ptr: glib::ffi::gboolean,
968 tooltip_ptr: *mut ffi::GtkTooltip,
969) -> glib::ffi::gboolean {
970 unsafe {
971 let instance = &*(ptr as *mut T::Instance);
972 let imp = instance.imp();
973
974 let keyboard_tooltip: bool = from_glib(keyboard_tooltip_ptr);
975 let tooltip = from_glib_borrow(tooltip_ptr);
976
977 imp.query_tooltip(x, y, keyboard_tooltip, &tooltip)
978 .into_glib()
979 }
980}
981
982unsafe extern "C" fn widget_realize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
983 unsafe {
984 let instance = &*(ptr as *mut T::Instance);
985 let imp = instance.imp();
986
987 imp.realize()
988 }
989}
990
991unsafe extern "C" fn widget_root<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
992 unsafe {
993 let instance = &*(ptr as *mut T::Instance);
994 let imp = instance.imp();
995
996 imp.root()
997 }
998}
999
1000unsafe extern "C" fn widget_set_focus_child<T: WidgetImpl>(
1001 ptr: *mut ffi::GtkWidget,
1002 child_ptr: *mut ffi::GtkWidget,
1003) {
1004 unsafe {
1005 let instance = &*(ptr as *mut T::Instance);
1006 let imp = instance.imp();
1007 let child: Borrowed<Option<Widget>> = from_glib_borrow(child_ptr);
1008
1009 imp.set_focus_child(child.as_ref().as_ref())
1010 }
1011}
1012
1013unsafe extern "C" fn widget_show<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1014 unsafe {
1015 let instance = &*(ptr as *mut T::Instance);
1016 let imp = instance.imp();
1017
1018 imp.show()
1019 }
1020}
1021
1022unsafe extern "C" fn widget_size_allocate<T: WidgetImpl>(
1023 ptr: *mut ffi::GtkWidget,
1024 width: i32,
1025 height: i32,
1026 baseline: i32,
1027) {
1028 unsafe {
1029 let instance = &*(ptr as *mut T::Instance);
1030 let imp = instance.imp();
1031
1032 imp.size_allocate(width, height, baseline)
1033 }
1034}
1035
1036unsafe extern "C" fn widget_snapshot<T: WidgetImpl>(
1037 ptr: *mut ffi::GtkWidget,
1038 snapshot_ptr: *mut ffi::GtkSnapshot,
1039) {
1040 unsafe {
1041 let instance = &*(ptr as *mut T::Instance);
1042 let imp = instance.imp();
1043 let snapshot = from_glib_borrow(snapshot_ptr);
1044
1045 imp.snapshot(&snapshot)
1046 }
1047}
1048
1049unsafe extern "C" fn widget_state_flags_changed<T: WidgetImpl>(
1050 ptr: *mut ffi::GtkWidget,
1051 state_flags_ptr: ffi::GtkStateFlags,
1052) {
1053 unsafe {
1054 let instance = &*(ptr as *mut T::Instance);
1055 let imp = instance.imp();
1056 let state_flags = from_glib(state_flags_ptr);
1057
1058 imp.state_flags_changed(&state_flags)
1059 }
1060}
1061
1062unsafe extern "C" fn widget_system_setting_changed<T: WidgetImpl>(
1063 ptr: *mut ffi::GtkWidget,
1064 settings_ptr: ffi::GtkSystemSetting,
1065) {
1066 unsafe {
1067 let instance = &*(ptr as *mut T::Instance);
1068 let imp = instance.imp();
1069 let settings = from_glib(settings_ptr);
1070
1071 imp.system_setting_changed(&settings)
1072 }
1073}
1074
1075unsafe extern "C" fn widget_unmap<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1076 unsafe {
1077 let instance = &*(ptr as *mut T::Instance);
1078 let imp = instance.imp();
1079
1080 imp.unmap()
1081 }
1082}
1083
1084unsafe extern "C" fn widget_unrealize<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1085 unsafe {
1086 let instance = &*(ptr as *mut T::Instance);
1087 let imp = instance.imp();
1088
1089 imp.unrealize()
1090 }
1091}
1092
1093unsafe extern "C" fn widget_unroot<T: WidgetImpl>(ptr: *mut ffi::GtkWidget) {
1094 unsafe {
1095 let instance = &*(ptr as *mut T::Instance);
1096 let imp = instance.imp();
1097
1098 imp.unroot()
1099 }
1100}
1101
1102#[allow(clippy::missing_safety_doc)]
1103pub unsafe trait WidgetClassExt: ClassStruct {
1104 #[doc(alias = "gtk_widget_class_set_template")]
1105 fn set_template_bytes(&mut self, template: &glib::Bytes) {
1106 unsafe {
1107 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1108 ffi::gtk_widget_class_set_template(widget_class, template.to_glib_none().0);
1109 }
1110 }
1111
1112 fn set_template(&mut self, template: &[u8]) {
1123 let template_bytes = glib::Bytes::from(template);
1124 self.set_template_bytes(&template_bytes);
1125 }
1126
1127 fn set_template_static(&mut self, template: &'static [u8]) {
1128 let template_bytes = glib::Bytes::from_static(template);
1129 self.set_template_bytes(&template_bytes);
1130 }
1131
1132 #[doc(alias = "gtk_widget_class_set_template_from_resource")]
1141 fn set_template_from_resource(&mut self, resource_name: &str) {
1142 unsafe {
1143 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1144 ffi::gtk_widget_class_set_template_from_resource(
1145 widget_class,
1146 resource_name.to_glib_none().0,
1147 );
1148 }
1149 }
1150
1151 fn install_action_async<Fut, F>(
1152 &mut self,
1153 action_name: &str,
1154 parameter_type: Option<&glib::VariantTy>,
1155 activate: F,
1156 ) where
1157 F: Fn(
1158 <<Self as ClassStruct>::Type as ObjectSubclass>::Type,
1159 String,
1160 Option<Variant>,
1161 ) -> Fut
1162 + 'static
1163 + Clone,
1164 Fut: Future<Output = ()>,
1165 {
1166 self.install_action(
1167 action_name,
1168 parameter_type,
1169 move |this, action_name, parameter_type| {
1170 let ctx = glib::MainContext::default();
1171 let action_name = action_name.to_owned();
1172 let parameter_type = parameter_type.map(ToOwned::to_owned);
1173 ctx.spawn_local(glib::clone!(
1174 #[strong]
1175 this,
1176 #[strong]
1177 action_name,
1178 #[strong]
1179 parameter_type,
1180 #[strong]
1181 activate,
1182 async move {
1183 activate(this, action_name, parameter_type).await;
1184 }
1185 ));
1186 },
1187 );
1188 }
1189
1190 #[doc(alias = "gtk_widget_class_install_action")]
1204 fn install_action<F>(
1205 &mut self,
1206 action_name: &str,
1207 parameter_type: Option<&glib::VariantTy>,
1208 activate: F,
1209 ) where
1210 F: Fn(&<<Self as ClassStruct>::Type as ObjectSubclass>::Type, &str, Option<&Variant>)
1211 + 'static,
1212 {
1213 unsafe {
1214 let mut data = <Self::Type as ObjectSubclassType>::type_data();
1217 let data = data.as_mut();
1218
1219 let f: Box_<F> = Box_::new(activate);
1220
1221 let internal = data
1222 .class_data_mut::<Internal>(<Self::Type as ObjectSubclassType>::type_())
1223 .expect("Something bad happened at class_init, the internal class_data is missing");
1224 let callback_ptr = Box_::into_raw(f) as glib::ffi::gpointer;
1225 internal
1226 .actions
1227 .insert(action_name.to_string(), callback_ptr);
1228
1229 unsafe extern "C" fn activate_trampoline<F, S>(
1230 this: *mut ffi::GtkWidget,
1231 action_name: *const libc::c_char,
1232 parameter: *mut glib::ffi::GVariant,
1233 ) where
1234 S: ClassStruct,
1235 <S as ClassStruct>::Type: ObjectSubclass,
1236 F: Fn(&<<S as ClassStruct>::Type as ObjectSubclass>::Type, &str, Option<&Variant>)
1237 + 'static,
1238 {
1239 unsafe {
1240 let action_name = GString::from_glib_borrow(action_name);
1241
1242 let data = <S::Type as ObjectSubclassType>::type_data();
1243 let internal = data
1244 .as_ref()
1245 .class_data::<Internal>(<S::Type as ObjectSubclassType>::type_())
1246 .unwrap();
1247 let activate_callback = *internal
1248 .actions
1249 .get(&action_name.to_string())
1250 .unwrap_or_else(|| {
1251 panic!("Action name '{}' was not found", action_name.as_str());
1252 });
1253
1254 let widget = Widget::from_glib_borrow(this);
1255
1256 let f: &F = &*(activate_callback as *const F);
1257 f(
1258 widget.unsafe_cast_ref(),
1259 &action_name,
1260 Option::<Variant>::from_glib_borrow(parameter)
1261 .as_ref()
1262 .as_ref(),
1263 )
1264 }
1265 }
1266 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1267 let callback = activate_trampoline::<F, Self>;
1268 ffi::gtk_widget_class_install_action(
1269 widget_class,
1270 action_name.to_glib_none().0,
1271 parameter_type.map(|p| p.as_str()).to_glib_none().0,
1272 Some(callback),
1273 );
1274 }
1275 }
1276
1277 #[doc(alias = "gtk_widget_class_query_action")]
1305 fn query_action(&self) -> WidgetActionIter {
1306 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1307 WidgetActionIter(widget_class, 0)
1308 }
1309
1310 #[doc(alias = "gtk_widget_class_set_template_scope")]
1320 fn set_template_scope<S: IsA<BuilderScope>>(&mut self, scope: &S) {
1321 unsafe {
1322 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1323 ffi::gtk_widget_class_set_template_scope(widget_class, scope.as_ref().to_glib_none().0);
1324 }
1325 }
1326
1327 #[doc(alias = "gtk_widget_class_add_binding")]
1347 fn add_binding<
1348 F: Fn(&<<Self as ClassStruct>::Type as ObjectSubclass>::Type) -> glib::Propagation + 'static,
1349 >(
1350 &mut self,
1351 keyval: gdk::Key,
1352 mods: gdk::ModifierType,
1353 callback: F,
1354 ) {
1355 let shortcut = crate::Shortcut::new(
1356 Some(crate::KeyvalTrigger::new(keyval, mods)),
1357 Some(crate::CallbackAction::new(
1358 move |widget, _| -> glib::Propagation {
1359 unsafe { callback(widget.unsafe_cast_ref()) }
1360 },
1361 )),
1362 );
1363 self.add_shortcut(&shortcut);
1364 }
1365
1366 #[doc(alias = "gtk_widget_class_add_binding_action")]
1384 fn add_binding_action(&mut self, keyval: gdk::Key, mods: gdk::ModifierType, action_name: &str) {
1385 let shortcut = crate::Shortcut::new(
1386 Some(crate::KeyvalTrigger::new(keyval, mods)),
1387 Some(crate::NamedAction::new(action_name)),
1388 );
1389 self.add_shortcut(&shortcut);
1390 }
1391
1392 #[doc(alias = "gtk_widget_class_add_binding_signal")]
1410 fn add_binding_signal(&mut self, keyval: gdk::Key, mods: gdk::ModifierType, signal_name: &str) {
1411 let type_ = <Self::Type as ObjectSubclassType>::type_();
1412 assert!(
1413 SignalId::lookup(signal_name, type_).is_some(),
1414 "Signal '{signal_name}' doesn't exists for type '{type_}'",
1415 );
1416
1417 let shortcut = crate::Shortcut::new(
1418 Some(crate::KeyvalTrigger::new(keyval, mods)),
1419 Some(crate::SignalAction::new(signal_name)),
1420 );
1421 self.add_shortcut(&shortcut);
1422 }
1423
1424 #[doc(alias = "gtk_widget_class_add_shortcut")]
1437 fn add_shortcut(&mut self, shortcut: &Shortcut) {
1438 unsafe {
1439 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1440 ffi::gtk_widget_class_add_shortcut(widget_class, shortcut.to_glib_none().0);
1441 }
1442 }
1443
1444 #[doc(alias = "gtk_widget_class_install_property_action")]
1465 fn install_property_action(&mut self, action_name: &str, property_name: &str) {
1466 unsafe {
1467 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1468 ffi::gtk_widget_class_install_property_action(
1469 widget_class,
1470 action_name.to_glib_none().0,
1471 property_name.to_glib_none().0,
1472 );
1473 }
1474 }
1475
1476 #[doc(alias = "gtk_widget_class_get_activate_signal")]
1486 #[doc(alias = "get_activate_signal")]
1487 fn activate_signal(&self) -> Option<SignalId> {
1488 unsafe {
1489 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1490 let signal_id = ffi::gtk_widget_class_get_activate_signal(widget_class);
1491 if signal_id == 0 {
1492 None
1493 } else {
1494 Some(from_glib(signal_id))
1495 }
1496 }
1497 }
1498
1499 #[doc(alias = "gtk_widget_class_set_activate_signal")]
1508 fn set_activate_signal(&mut self, signal_id: SignalId) {
1509 unsafe {
1510 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1511 ffi::gtk_widget_class_set_activate_signal(widget_class, signal_id.into_glib())
1512 }
1513 }
1514
1515 #[doc(alias = "gtk_widget_class_set_activate_signal_from_name")]
1526 fn set_activate_signal_from_name(&mut self, signal_name: &str) {
1527 let type_ = <Self::Type as ObjectSubclassType>::type_();
1528 assert!(
1529 SignalId::lookup(signal_name, type_).is_some(),
1530 "Signal '{signal_name}' doesn't exists for type '{type_}'",
1531 );
1532
1533 unsafe {
1534 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1535 ffi::gtk_widget_class_set_activate_signal_from_name(
1536 widget_class,
1537 signal_name.to_glib_none().0,
1538 );
1539 }
1540 }
1541
1542 #[doc(alias = "gtk_widget_class_set_layout_manager_type")]
1553 fn set_layout_manager_type<T: IsA<LayoutManager>>(&mut self) {
1554 unsafe {
1555 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1556 ffi::gtk_widget_class_set_layout_manager_type(
1557 widget_class,
1558 T::static_type().into_glib(),
1559 );
1560 }
1561 }
1562
1563 #[doc(alias = "gtk_widget_class_get_layout_manager_type")]
1572 #[doc(alias = "get_layout_manager_type")]
1573 fn layout_manager_type(&self) -> glib::Type {
1574 unsafe {
1575 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1576 from_glib(ffi::gtk_widget_class_get_layout_manager_type(widget_class))
1577 }
1578 }
1579
1580 #[doc(alias = "gtk_widget_class_set_css_name")]
1588 fn set_css_name(&mut self, name: &str) {
1589 unsafe {
1590 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1591 ffi::gtk_widget_class_set_css_name(widget_class, name.to_glib_none().0);
1592 }
1593 }
1594
1595 #[doc(alias = "gtk_widget_class_get_css_name")]
1603 #[doc(alias = "get_css_name")]
1604 fn css_name(&self) -> glib::GString {
1605 unsafe {
1606 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1607 from_glib_none(ffi::gtk_widget_class_get_css_name(widget_class))
1608 }
1609 }
1610
1611 #[doc(alias = "gtk_widget_class_set_accessible_role")]
1618 fn set_accessible_role(&mut self, role: AccessibleRole) {
1619 unsafe {
1620 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1621 ffi::gtk_widget_class_set_accessible_role(widget_class, role.into_glib());
1622 }
1623 }
1624
1625 #[doc(alias = "gtk_widget_class_get_accessible_role")]
1636 #[doc(alias = "get_accessible_role")]
1637 fn accessible_role(&self) -> AccessibleRole {
1638 unsafe {
1639 let widget_class = self as *const _ as *mut ffi::GtkWidgetClass;
1640 from_glib(ffi::gtk_widget_class_get_accessible_role(widget_class))
1641 }
1642 }
1643
1644 #[allow(clippy::missing_safety_doc)]
1645 #[doc(alias = "gtk_widget_class_bind_template_child_full")]
1646 unsafe fn bind_template_child_with_offset<T>(
1647 &mut self,
1648 name: &str,
1649 internal: bool,
1650 offset: field_offset::FieldOffset<Self::Type, TemplateChild<T>>,
1651 ) where
1652 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1653 {
1654 unsafe {
1655 let widget_class = self as *mut _ as *mut ffi::GtkWidgetClass;
1656 let private_offset = <Self::Type as ObjectSubclassType>::type_data()
1657 .as_ref()
1658 .impl_offset();
1659 ffi::gtk_widget_class_bind_template_child_full(
1660 widget_class,
1661 name.to_glib_none().0,
1662 internal.into_glib(),
1663 private_offset + (offset.get_byte_offset() as isize),
1664 )
1665 }
1666 }
1667
1668 fn rust_template_scope(&mut self) -> BuilderRustScope {
1669 assert_initialized_main_thread!();
1670 unsafe {
1671 let mut data = <Self::Type as ObjectSubclassType>::type_data();
1672 let internal = data
1673 .as_mut()
1674 .class_data_mut::<Internal>(<Self::Type as ObjectSubclassType>::type_())
1675 .expect("Something bad happened at class_init, the internal class_data is missing");
1676 let scope = internal.scope.get_or_insert_with(|| {
1677 let scope = BuilderRustScope::new();
1678 self.set_template_scope(&scope);
1679 scope.into_glib_ptr()
1680 });
1681 from_glib_none(*scope)
1682 }
1683 }
1684}
1685
1686unsafe impl<T: ClassStruct> WidgetClassExt for T where T::Type: WidgetImpl {}
1687
1688#[derive(Debug, PartialEq, Eq)]
1689#[repr(transparent)]
1690pub struct TemplateChild<T>
1691where
1692 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1693{
1694 ptr: *mut <T as ObjectType>::GlibType,
1695}
1696
1697impl<T: Property> Property for TemplateChild<T>
1698where
1699 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1700{
1701 type Value = T::Value;
1702}
1703
1704impl<T> Default for TemplateChild<T>
1705where
1706 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1707{
1708 fn default() -> Self {
1709 T::static_type();
1710
1711 Self {
1712 ptr: std::ptr::null_mut(),
1713 }
1714 }
1715}
1716
1717impl<T> PropertyGet for TemplateChild<T>
1718where
1719 T: Property + ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1720{
1721 type Value = T;
1722
1723 fn get<R, F: Fn(&Self::Value) -> R>(&self, f: F) -> R {
1724 f(&self.get())
1725 }
1726}
1727
1728impl<T> std::ops::Deref for TemplateChild<T>
1729where
1730 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1731{
1732 type Target = T;
1733
1734 #[inline]
1735 fn deref(&self) -> &Self::Target {
1736 unsafe {
1737 if !self.is_bound() {
1738 let name = Self::name();
1739 panic!(
1740 "Failed to retrieve template child. Please check that all fields of type `{name}` have been bound and have a #[template_child] attribute."
1741 );
1742 }
1743 &*(&self.ptr as *const _ as *const T)
1744 }
1745 }
1746}
1747
1748impl<T> Downgrade for TemplateChild<T>
1749where
1750 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType> + Downgrade,
1751{
1752 type Weak = T::Weak;
1753
1754 fn downgrade(&self) -> Self::Weak {
1755 T::downgrade(&self.get())
1756 }
1757}
1758
1759impl<T> TemplateChild<T>
1760where
1761 T: ObjectType + FromGlibPtrNone<*mut <T as ObjectType>::GlibType>,
1762{
1763 pub(crate) fn name<'a>() -> &'a str {
1764 T::static_type().name()
1765 }
1766
1767 #[track_caller]
1768 pub fn get(&self) -> T {
1769 self.try_get()
1770 .unwrap_or_else(|| {
1771 let name = Self::name();
1772 panic!("Failed to retrieve template child. Please check that all fields of type `{name}` have been bound and have a #[template_child] attribute.");
1773 })
1774 }
1775
1776 pub fn is_bound(&self) -> bool {
1780 !self.ptr.is_null()
1781 }
1782
1783 pub fn try_get(&self) -> Option<T> {
1786 unsafe { Option::<T>::from_glib_none(self.ptr) }
1787 }
1788}
1789
1790pub trait CompositeTemplate: WidgetImpl {
1796 fn bind_template(klass: &mut Self::Class);
1797 fn check_template_children(widget: &<Self as ObjectSubclass>::Type);
1798}
1799
1800pub trait CompositeTemplateClass {
1805 fn bind_template(&mut self);
1809}
1810
1811impl<T, U> CompositeTemplateClass for T
1812where
1813 T: ClassStruct<Type = U>,
1814 U: ObjectSubclass<Class = T> + CompositeTemplate,
1815{
1816 fn bind_template(&mut self) {
1817 <U as CompositeTemplate>::bind_template(self);
1818 }
1819}
1820
1821pub type TemplateCallback = (&'static str, fn(&[glib::Value]) -> Option<glib::Value>);
1822
1823pub trait CompositeTemplateCallbacks {
1829 const CALLBACKS: &'static [TemplateCallback];
1830
1831 fn bind_template_callbacks<T: WidgetClassExt>(klass: &mut T) {
1835 Self::add_callbacks_to_scope(&klass.rust_template_scope());
1836 }
1837 fn bind_template_callbacks_prefixed<T: WidgetClassExt>(klass: &mut T, prefix: &str) {
1841 Self::add_callbacks_to_scope_prefixed(&klass.rust_template_scope(), prefix);
1842 }
1843 fn add_callbacks_to_scope(scope: &BuilderRustScope) {
1846 for (name, func) in Self::CALLBACKS {
1847 scope.add_callback(*name, func);
1848 }
1849 }
1850 fn add_callbacks_to_scope_prefixed(scope: &BuilderRustScope, prefix: &str) {
1854 for (name, func) in Self::CALLBACKS {
1855 scope.add_callback(format!("{prefix}{name}"), func);
1856 }
1857 }
1858}
1859
1860pub trait CompositeTemplateCallbacksClass {
1865 fn bind_template_callbacks(&mut self);
1869}
1870
1871impl<T, U> CompositeTemplateCallbacksClass for T
1872where
1873 T: ClassStruct<Type = U> + WidgetClassExt,
1874 U: ObjectSubclass<Class = T> + CompositeTemplateCallbacks,
1875{
1876 fn bind_template_callbacks(&mut self) {
1877 <U as CompositeTemplateCallbacks>::bind_template_callbacks(self);
1878 }
1879}
1880
1881pub trait CompositeTemplateInstanceCallbacksClass {
1887 fn bind_template_instance_callbacks(&mut self);
1891}
1892
1893impl<T, U, V> CompositeTemplateInstanceCallbacksClass for T
1894where
1895 T: ClassStruct<Type = U> + WidgetClassExt,
1896 U: ObjectSubclass<Class = T, Type = V>,
1897 V: CompositeTemplateCallbacks,
1898{
1899 fn bind_template_instance_callbacks(&mut self) {
1900 <V as CompositeTemplateCallbacks>::bind_template_callbacks(self);
1901 }
1902}
1903
1904pub trait CompositeTemplateInitializingExt {
1905 fn init_template(&self);
1906}
1907
1908impl<T: WidgetImpl + CompositeTemplate> CompositeTemplateInitializingExt
1909 for glib::subclass::InitializingObject<T>
1910{
1911 fn init_template(&self) {
1912 unsafe {
1913 let widget = self
1914 .as_ref()
1915 .unsafe_cast_ref::<<T as ObjectSubclass>::Type>();
1916 ffi::gtk_widget_init_template(AsRef::<Widget>::as_ref(widget).to_glib_none().0);
1917
1918 <T as CompositeTemplate>::check_template_children(widget);
1919 }
1920 }
1921}
1922
1923pub trait CompositeTemplateDisposeExt {
1924 #[cfg(feature = "v4_8")]
1925 #[cfg_attr(docsrs, doc(cfg(feature = "v4_8")))]
1926 fn dispose_template(&self);
1927}
1928
1929impl<T: WidgetImpl + CompositeTemplate> CompositeTemplateDisposeExt for T {
1930 #[cfg(feature = "v4_8")]
1931 #[cfg_attr(docsrs, doc(cfg(feature = "v4_8")))]
1932 fn dispose_template(&self) {
1933 unsafe {
1934 ffi::gtk_widget_dispose_template(
1935 self.obj().upcast_ref::<Widget>().to_glib_none().0,
1936 <T as ObjectSubclass>::Type::static_type().into_glib(),
1937 );
1938 }
1939 }
1940}