diff --git a/podcasts-gtk/src/stacks/populated.rs b/podcasts-gtk/src/stacks/populated.rs index e99bf5b..586828f 100644 --- a/podcasts-gtk/src/stacks/populated.rs +++ b/podcasts-gtk/src/stacks/populated.rs @@ -39,7 +39,7 @@ impl PopulatedStack { let container = gtk::Box::new(gtk::Orientation::Horizontal, 0); stack.add_named(&populated.container, "shows"); - stack.add_named(&show.container, "widget"); + stack.add_named(show.container(), "widget"); container.add(&stack); container.show_all(); @@ -88,7 +88,7 @@ impl PopulatedStack { } pub(crate) fn replace_widget(&mut self, pd: Arc) -> Result<(), Error> { - let old = self.show.container.clone(); + let old = self.show.container().clone(); // save the ShowWidget vertical scrollabar alignment self.show.show_id().map(|id| self.show.save_vadjustment(id)); @@ -96,7 +96,7 @@ impl PopulatedStack { let new = ShowWidget::new(pd, self.sender.clone()); self.show = new; self.stack.remove(&old); - self.stack.add_named(&self.show.container, "widget"); + self.stack.add_named(self.show.container(), "widget"); // The current visible child might change depending on // removal and insertion in the gtk::Stack, so we have @@ -108,7 +108,7 @@ impl PopulatedStack { } pub(crate) fn update_widget(&mut self) -> Result<(), Error> { - let old = self.show.container.clone(); + let old = self.show.container().clone(); let id = self.show.show_id(); if id.is_none() { return Ok(()); diff --git a/podcasts-gtk/src/widgets/base_view.rs b/podcasts-gtk/src/widgets/base_view.rs new file mode 100644 index 0000000..8846767 --- /dev/null +++ b/podcasts-gtk/src/widgets/base_view.rs @@ -0,0 +1,35 @@ +use gtk::{self, prelude::*, Orientation}; + +#[derive(Debug, Clone)] +pub(crate) struct BaseView { + container: gtk::Box, + scrolled_window: gtk::ScrolledWindow, +} + +impl Default for BaseView { + fn default() -> Self { + let container = gtk::Box::new(Orientation::Horizontal, 0); + let scrolled_window = gtk::ScrolledWindow::new(None, None); + container.add(&scrolled_window); + container.show_all(); + + BaseView { + container, + scrolled_window, + } + } +} + +impl BaseView { + pub(crate) fn container(&self) -> >k::Box { + &self.container + } + + pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { + &self.scrolled_window + } + + pub(crate) fn add>(&self, widget: &T) { + self.scrolled_window.add(widget); + } +} diff --git a/podcasts-gtk/src/widgets/mod.rs b/podcasts-gtk/src/widgets/mod.rs index 7ff0246..85aae87 100644 --- a/podcasts-gtk/src/widgets/mod.rs +++ b/podcasts-gtk/src/widgets/mod.rs @@ -1,5 +1,6 @@ mod aboutdialog; pub(crate) mod appnotif; +mod base_view; mod empty; mod episode; mod home_view; @@ -9,6 +10,7 @@ pub(crate) mod show_menu; mod shows_view; pub(crate) use self::aboutdialog::about_dialog; +pub(crate) use self::base_view::BaseView; pub(crate) use self::empty::EmptyView; pub(crate) use self::episode::EpisodeWidget; pub(crate) use self::home_view::HomeView; diff --git a/podcasts-gtk/src/widgets/show.rs b/podcasts-gtk/src/widgets/show.rs index 4a205a0..daacf96 100644 --- a/podcasts-gtk/src/widgets/show.rs +++ b/podcasts-gtk/src/widgets/show.rs @@ -1,5 +1,5 @@ use glib; -use gtk::{self, prelude::*, Orientation, SelectionMode}; +use gtk::{self, prelude::*, SelectionMode}; use crossbeam_channel::Sender; use failure::Error; @@ -13,7 +13,7 @@ use podcasts_data::Show; use app::Action; use utils::{self, lazy_load}; -use widgets::{EpisodeWidget, ShowMenu}; +use widgets::{BaseView, EpisodeWidget, ShowMenu}; use std::rc::Rc; use std::sync::{Arc, Mutex}; @@ -25,8 +25,7 @@ lazy_static! { #[derive(Debug, Clone)] pub(crate) struct ShowWidget { - pub(crate) container: gtk::Box, - scrolled_window: gtk::ScrolledWindow, + view: BaseView, cover: gtk::Image, description: gtk::Label, episodes: gtk::ListBox, @@ -35,14 +34,11 @@ pub(crate) struct ShowWidget { impl Default for ShowWidget { fn default() -> Self { - let container = gtk::Box::new(Orientation::Horizontal, 0); - let scrolled_window = gtk::ScrolledWindow::new(None, None); - container.add(&scrolled_window); - let builder = gtk::Builder::new_from_resource("/org/gnome/Podcasts/gtk/show_widget.ui"); let sub_cont: gtk::Box = builder.get_object("sub_container").unwrap(); let cover: gtk::Image = builder.get_object("cover").unwrap(); let description: gtk::Label = builder.get_object("description").unwrap(); + let view = BaseView::default(); let frame = gtk::Frame::new(None); let episodes = gtk::ListBox::new(); @@ -58,12 +54,11 @@ impl Default for ShowWidget { frame.add(&episodes); sub_cont.add(&frame); column.add(&sub_cont); - scrolled_window.add(&column); + view.add(&column); + column.show_all(); - container.show_all(); ShowWidget { - container, - scrolled_window, + view, cover, description, episodes, @@ -95,6 +90,14 @@ impl ShowWidget { debug_assert!(res.is_ok()); } + pub(crate) fn container(&self) -> >k::Box { + self.view.container() + } + + pub(crate) fn scrolled_window(&self) -> >k::ScrolledWindow { + self.view.scrolled_window() + } + /// Set the show cover. fn set_cover(&self, pd: &Arc) -> Result<(), Error> { utils::set_image_from_path(&self.cover, pd.id(), 256) @@ -110,7 +113,7 @@ impl ShowWidget { pub(crate) fn save_vadjustment(&self, oldid: i32) -> Result<(), Error> { if let Ok(mut guard) = SHOW_WIDGET_VALIGNMENT.lock() { let adj = self - .scrolled_window + .scrolled_window() .get_vadjustment() .ok_or_else(|| format_err!("Could not get the adjustment"))?; *guard = Some((oldid, Fragile::new(adj))); @@ -138,7 +141,7 @@ impl ShowWidget { // Copy the vertical scrollbar adjustment from the old view into the new one. let res = fragile .try_get() - .map(|x| utils::smooth_scroll_to(&self.scrolled_window, &x)) + .map(|x| utils::smooth_scroll_to(self.scrolled_window(), &x)) .map_err(From::from); debug_assert!(res.is_ok());