diff --git a/src/components/label_with_widgets.rs b/src/components/label_with_widgets.rs index 409be7bc..d051a4d8 100644 --- a/src/components/label_with_widgets.rs +++ b/src/components/label_with_widgets.rs @@ -338,3 +338,9 @@ impl LabelWithWidgets { self.imp().set_label_and_widgets(label, widgets); } } + +impl Default for LabelWithWidgets { + fn default() -> Self { + Self::new() + } +} diff --git a/src/components/loading/bin.rs b/src/components/loading/bin.rs index 3973c426..badefd5f 100644 --- a/src/components/loading/bin.rs +++ b/src/components/loading/bin.rs @@ -1,6 +1,8 @@ use adw::prelude::*; use gtk::{glib, subclass::prelude::*, CompositeTemplate}; +use crate::utils::ChildPropertyExt; + mod imp { use std::marker::PhantomData; @@ -118,3 +120,13 @@ impl Default for LoadingBin { Self::new() } } + +impl ChildPropertyExt for LoadingBin { + fn child_property(&self) -> Option { + self.child() + } + + fn set_child_property(&self, child: Option<&impl IsA>) { + self.set_child(child.map(Cast::upcast_ref)); + } +} diff --git a/src/components/loading/button.rs b/src/components/loading/button.rs index 30d16075..fda8986f 100644 --- a/src/components/loading/button.rs +++ b/src/components/loading/button.rs @@ -1,7 +1,8 @@ -use adw::subclass::prelude::*; -use gtk::{glib, pango, prelude::*}; +use adw::{prelude::*, subclass::prelude::*}; +use gtk::{glib, pango}; use super::LoadingBin; +use crate::prelude::*; mod imp { use std::marker::PhantomData; @@ -65,26 +66,22 @@ mod imp { } let obj = self.obj(); - let child_label = - if let Some(child_label) = self.loading_bin.child().and_downcast::() { - child_label - } else { - let child_label = gtk::Label::builder() - .ellipsize(pango::EllipsizeMode::End) - .use_underline(true) - .mnemonic_widget(&*obj) - .css_classes(["text-button"]) - .build(); - - self.loading_bin.set_child(Some(child_label.clone())); - // In case it was an image before. - obj.remove_css_class("image-button"); - obj.update_relation(&[gtk::accessible::Relation::LabelledBy(&[ - child_label.upcast_ref() - ])]); - - child_label - }; + let child_label = self.loading_bin.child_or_else::(|| { + let child_label = gtk::Label::builder() + .ellipsize(pango::EllipsizeMode::End) + .use_underline(true) + .mnemonic_widget(&*obj) + .css_classes(["text-button"]) + .build(); + + // In case it was an image before. + obj.remove_css_class("image-button"); + obj.update_relation(&[gtk::accessible::Relation::LabelledBy(&[ + child_label.upcast_ref() + ])]); + + child_label + }); child_label.set_label(label); @@ -106,19 +103,13 @@ mod imp { } let obj = self.obj(); - let child_image = - if let Some(child_image) = self.loading_bin.child().and_downcast::() { - child_image - } else { - let child_image = gtk::Image::builder() - .accessible_role(gtk::AccessibleRole::Presentation) - .build(); - - self.loading_bin.set_child(Some(child_image.clone())); - obj.add_css_class("image-button"); + let child_image = self.loading_bin.child_or_else::(|| { + obj.add_css_class("image-button"); - child_image - }; + gtk::Image::builder() + .accessible_role(gtk::AccessibleRole::Presentation) + .build() + }); child_image.set_icon_name(Some(icon_name)); diff --git a/src/components/media/content_viewer.rs b/src/components/media/content_viewer.rs index 1dc9e337..f03139ba 100644 --- a/src/components/media/content_viewer.rs +++ b/src/components/media/content_viewer.rs @@ -230,14 +230,7 @@ mod imp { /// View the given location as a geo URI. pub(super) fn view_location(&self, geo_uri: &GeoUri) { - let location = - if let Some(location) = self.viewer.child().and_downcast::() { - location - } else { - let location = LocationViewer::new(); - self.viewer.set_child(Some(&location)); - location - }; + let location = self.viewer.child_or_default::(); location.set_location(geo_uri); self.update_animated_paintable_state(); diff --git a/src/components/media/location_viewer.rs b/src/components/media/location_viewer.rs index 29cf03a0..f4809c41 100644 --- a/src/components/media/location_viewer.rs +++ b/src/components/media/location_viewer.rs @@ -148,3 +148,9 @@ impl LocationViewer { self.imp().set_location(geo_uri); } } + +impl Default for LocationViewer { + fn default() -> Self { + Self::new() + } +} diff --git a/src/prelude.rs b/src/prelude.rs index cc33766b..06614c3b 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -10,6 +10,6 @@ pub(crate) use crate::{ utils::{ matrix::ext_traits::*, string::{StrExt, StrMutExt}, - LocationExt, + ChildPropertyExt, IsABin, LocationExt, }, }; diff --git a/src/session/view/content/explore/mod.rs b/src/session/view/content/explore/mod.rs index 7780c911..79f6163e 100644 --- a/src/session/view/content/explore/mod.rs +++ b/src/session/view/content/explore/mod.rs @@ -17,6 +17,7 @@ pub use self::{ use self::{server::ExploreServer, server_list::ExploreServerList, server_row::ExploreServerRow}; use crate::{ components::LoadingRow, + prelude::*, session::model::Session, utils::{BoundObject, LoadingState, SingleItemListModel}, }; @@ -122,16 +123,7 @@ mod imp { }; if let Some(public_room) = item.downcast_ref::() { - let public_room_row = if let Some(public_room_row) = - list_item.child().and_downcast::() - { - public_room_row - } else { - let public_room_row = PublicRoomRow::new(); - list_item.set_child(Some(&public_room_row)); - public_room_row - }; - + let public_room_row = list_item.child_or_default::(); public_room_row.set_public_room(public_room); } else if let Some(loading_row) = item.downcast_ref::() { list_item.set_child(Some(loading_row)); diff --git a/src/session/view/content/explore/public_room_row.rs b/src/session/view/content/explore/public_room_row.rs index e0b4a50b..0108c47f 100644 --- a/src/session/view/content/explore/public_room_row.rs +++ b/src/session/view/content/explore/public_room_row.rs @@ -240,3 +240,9 @@ impl PublicRoomRow { glib::Object::new() } } + +impl Default for PublicRoomRow { + fn default() -> Self { + Self::new() + } +} diff --git a/src/session/view/content/room_details/history_viewer/audio.rs b/src/session/view/content/room_details/history_viewer/audio.rs index 58a01156..7d4b9764 100644 --- a/src/session/view/content/room_details/history_viewer/audio.rs +++ b/src/session/view/content/room_details/history_viewer/audio.rs @@ -5,6 +5,7 @@ use tracing::error; use super::{AudioRow, HistoryViewerEvent, HistoryViewerEventType, HistoryViewerTimeline}; use crate::{ components::LoadingRow, + prelude::*, spawn, utils::{BoundConstructOnlyObject, LoadingState}, }; @@ -86,16 +87,7 @@ mod imp { list_item.set_child(Some(loading_row)); } else if let Some(event) = item.and_downcast::() { - let audio_row = - if let Some(audio_row) = list_item.child().and_downcast::() { - audio_row - } else { - let audio_row = AudioRow::new(); - list_item.set_child(Some(&audio_row)); - - audio_row - }; - + let audio_row = list_item.child_or_default::(); audio_row.set_event(Some(event)); } }); diff --git a/src/session/view/content/room_details/history_viewer/audio_row.rs b/src/session/view/content/room_details/history_viewer/audio_row.rs index c900e69b..f6748374 100644 --- a/src/session/view/content/room_details/history_viewer/audio_row.rs +++ b/src/session/view/content/room_details/history_viewer/audio_row.rs @@ -191,3 +191,9 @@ impl AudioRow { glib::Object::new() } } + +impl Default for AudioRow { + fn default() -> Self { + Self::new() + } +} diff --git a/src/session/view/content/room_details/history_viewer/file.rs b/src/session/view/content/room_details/history_viewer/file.rs index 18e1d230..7d688eb1 100644 --- a/src/session/view/content/room_details/history_viewer/file.rs +++ b/src/session/view/content/room_details/history_viewer/file.rs @@ -5,6 +5,7 @@ use tracing::error; use super::{FileRow, HistoryViewerEvent, HistoryViewerEventType, HistoryViewerTimeline}; use crate::{ components::LoadingRow, + prelude::*, spawn, utils::{BoundConstructOnlyObject, LoadingState}, }; @@ -86,16 +87,7 @@ mod imp { list_item.set_child(Some(loading_row)); } else if let Some(event) = item.and_downcast::() { - let file_row = - if let Some(file_row) = list_item.child().and_downcast::() { - file_row - } else { - let file_row = FileRow::new(); - list_item.set_child(Some(&file_row)); - - file_row - }; - + let file_row = list_item.child_or_default::(); file_row.set_event(Some(event)); } }); diff --git a/src/session/view/content/room_details/history_viewer/file_row.rs b/src/session/view/content/room_details/history_viewer/file_row.rs index b9e0eadc..628ab071 100644 --- a/src/session/view/content/room_details/history_viewer/file_row.rs +++ b/src/session/view/content/room_details/history_viewer/file_row.rs @@ -177,3 +177,9 @@ impl FileRow { glib::Object::new() } } + +impl Default for FileRow { + fn default() -> Self { + Self::new() + } +} diff --git a/src/session/view/content/room_details/history_viewer/visual_media.rs b/src/session/view/content/room_details/history_viewer/visual_media.rs index 710c33fd..5f20d811 100644 --- a/src/session/view/content/room_details/history_viewer/visual_media.rs +++ b/src/session/view/content/room_details/history_viewer/visual_media.rs @@ -5,6 +5,7 @@ use tracing::error; use super::{HistoryViewerEvent, HistoryViewerEventType, HistoryViewerTimeline, VisualMediaItem}; use crate::{ components::LoadingRow, + prelude::*, session::view::MediaViewer, spawn, utils::{BoundConstructOnlyObject, LoadingState}, @@ -91,20 +92,7 @@ mod imp { list_item.set_child(Some(loading_row)); } else if let Some(event) = item.and_downcast::() { - let media_item = if let Some(media_item) = - list_item.child().and_downcast::() - { - media_item - } else { - let media_item = VisualMediaItem::new(); - media_item.set_width_request(SIZE_REQUEST); - media_item.set_height_request(SIZE_REQUEST); - - list_item.set_child(Some(&media_item)); - - media_item - }; - + let media_item = list_item.child_or_default::(); media_item.set_event(Some(event)); } }); diff --git a/src/session/view/content/room_details/history_viewer/visual_media_item.rs b/src/session/view/content/room_details/history_viewer/visual_media_item.rs index c74f922a..42981820 100644 --- a/src/session/view/content/room_details/history_viewer/visual_media_item.rs +++ b/src/session/view/content/room_details/history_viewer/visual_media_item.rs @@ -241,3 +241,9 @@ impl VisualMediaItem { glib::Object::new() } } + +impl Default for VisualMediaItem { + fn default() -> Self { + Self::new() + } +} diff --git a/src/session/view/content/room_details/history_viewer/visual_media_item.ui b/src/session/view/content/room_details/history_viewer/visual_media_item.ui index 13832ece..98fe5562 100644 --- a/src/session/view/content/room_details/history_viewer/visual_media_item.ui +++ b/src/session/view/content/room_details/history_viewer/visual_media_item.ui @@ -3,6 +3,8 @@