fractal/components/loading/
bin.rs1use adw::prelude::*;
2use gtk::{glib, subclass::prelude::*, CompositeTemplate};
3
4mod imp {
5 use std::marker::PhantomData;
6
7 use glib::subclass::InitializingObject;
8
9 use super::*;
10
11 #[derive(Debug, Default, CompositeTemplate, glib::Properties)]
12 #[template(resource = "/org/gnome/Fractal/ui/components/loading/bin.ui")]
13 #[properties(wrapper_type = super::LoadingBin)]
14 pub struct LoadingBin {
15 #[template_child]
16 stack: TemplateChild<gtk::Stack>,
17 #[template_child]
18 child_bin: TemplateChild<adw::Bin>,
19 #[property(get = Self::child, set = Self::set_child, explicit_notify, nullable)]
21 child: PhantomData<Option<gtk::Widget>>,
22 #[property(get = Self::is_loading, set = Self::set_is_loading, explicit_notify)]
24 is_loading: PhantomData<bool>,
25 #[property(get = Self::vhomogeneous, set = Self::set_vhomogeneous)]
28 vhomogeneous: PhantomData<bool>,
29 }
30
31 #[glib::object_subclass]
32 impl ObjectSubclass for LoadingBin {
33 const NAME: &'static str = "LoadingBin";
34 type Type = super::LoadingBin;
35 type ParentType = gtk::Widget;
36
37 fn class_init(klass: &mut Self::Class) {
38 Self::bind_template(klass);
39
40 klass.set_layout_manager_type::<gtk::BinLayout>();
41 klass.set_css_name("loading-bin");
42 }
43
44 fn instance_init(obj: &InitializingObject<Self>) {
45 obj.init_template();
46 }
47 }
48
49 #[glib::derived_properties]
50 impl ObjectImpl for LoadingBin {
51 fn dispose(&self) {
52 self.stack.unparent();
53 }
54 }
55
56 impl WidgetImpl for LoadingBin {}
57
58 impl LoadingBin {
59 fn is_loading(&self) -> bool {
61 self.stack.visible_child_name().as_deref() == Some("loading")
62 }
63
64 fn set_is_loading(&self, loading: bool) {
66 if self.is_loading() == loading {
67 return;
68 }
69
70 let child_name = if loading { "loading" } else { "child" };
71 self.stack.set_visible_child_name(child_name);
72 self.obj().notify_is_loading();
73 }
74
75 fn vhomogeneous(&self) -> bool {
78 self.stack.is_vhomogeneous()
79 }
80
81 fn set_vhomogeneous(&self, homogeneous: bool) {
84 self.stack.set_vhomogeneous(homogeneous);
85 }
86
87 fn child(&self) -> Option<gtk::Widget> {
89 self.child_bin.child()
90 }
91
92 fn set_child(&self, child: Option<>k::Widget>) {
94 if self.child().as_ref() == child {
95 return;
96 }
97
98 self.child_bin.set_child(child);
99 self.obj().notify_child();
100 }
101 }
102}
103
104glib::wrapper! {
105 pub struct LoadingBin(ObjectSubclass<imp::LoadingBin>)
107 @extends gtk::Widget, @implements gtk::Accessible;
108}
109
110impl LoadingBin {
111 pub fn new() -> Self {
112 glib::Object::new()
113 }
114}
115
116impl Default for LoadingBin {
117 fn default() -> Self {
118 Self::new()
119 }
120}