Gtk: Abstract a BaseView Widget

Currently it just re-exports its children with getters,
but the idea is that it will also be able to handle
the saving the state of its height adjustment later.
This commit is contained in:
Jordan Petridis 2018-08-09 04:21:12 +03:00
parent 5d8b2ec15c
commit 8fb84d9484
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
4 changed files with 58 additions and 18 deletions

View File

@ -39,7 +39,7 @@ impl PopulatedStack {
let container = gtk::Box::new(gtk::Orientation::Horizontal, 0); let container = gtk::Box::new(gtk::Orientation::Horizontal, 0);
stack.add_named(&populated.container, "shows"); stack.add_named(&populated.container, "shows");
stack.add_named(&show.container, "widget"); stack.add_named(show.container(), "widget");
container.add(&stack); container.add(&stack);
container.show_all(); container.show_all();
@ -88,7 +88,7 @@ impl PopulatedStack {
} }
pub(crate) fn replace_widget(&mut self, pd: Arc<Show>) -> Result<(), Error> { pub(crate) fn replace_widget(&mut self, pd: Arc<Show>) -> Result<(), Error> {
let old = self.show.container.clone(); let old = self.show.container().clone();
// save the ShowWidget vertical scrollabar alignment // save the ShowWidget vertical scrollabar alignment
self.show.show_id().map(|id| self.show.save_vadjustment(id)); 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()); let new = ShowWidget::new(pd, self.sender.clone());
self.show = new; self.show = new;
self.stack.remove(&old); 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 // The current visible child might change depending on
// removal and insertion in the gtk::Stack, so we have // 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> { 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(); let id = self.show.show_id();
if id.is_none() { if id.is_none() {
return Ok(()); return Ok(());

View File

@ -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) -> &gtk::Box {
&self.container
}
pub(crate) fn scrolled_window(&self) -> &gtk::ScrolledWindow {
&self.scrolled_window
}
pub(crate) fn add<T: IsA<gtk::Widget>>(&self, widget: &T) {
self.scrolled_window.add(widget);
}
}

View File

@ -1,5 +1,6 @@
mod aboutdialog; mod aboutdialog;
pub(crate) mod appnotif; pub(crate) mod appnotif;
mod base_view;
mod empty; mod empty;
mod episode; mod episode;
mod home_view; mod home_view;
@ -9,6 +10,7 @@ pub(crate) mod show_menu;
mod shows_view; mod shows_view;
pub(crate) use self::aboutdialog::about_dialog; pub(crate) use self::aboutdialog::about_dialog;
pub(crate) use self::base_view::BaseView;
pub(crate) use self::empty::EmptyView; pub(crate) use self::empty::EmptyView;
pub(crate) use self::episode::EpisodeWidget; pub(crate) use self::episode::EpisodeWidget;
pub(crate) use self::home_view::HomeView; pub(crate) use self::home_view::HomeView;

View File

@ -1,5 +1,5 @@
use glib; use glib;
use gtk::{self, prelude::*, Orientation, SelectionMode}; use gtk::{self, prelude::*, SelectionMode};
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use failure::Error; use failure::Error;
@ -13,7 +13,7 @@ use podcasts_data::Show;
use app::Action; use app::Action;
use utils::{self, lazy_load}; use utils::{self, lazy_load};
use widgets::{EpisodeWidget, ShowMenu}; use widgets::{BaseView, EpisodeWidget, ShowMenu};
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -25,8 +25,7 @@ lazy_static! {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct ShowWidget { pub(crate) struct ShowWidget {
pub(crate) container: gtk::Box, view: BaseView,
scrolled_window: gtk::ScrolledWindow,
cover: gtk::Image, cover: gtk::Image,
description: gtk::Label, description: gtk::Label,
episodes: gtk::ListBox, episodes: gtk::ListBox,
@ -35,14 +34,11 @@ pub(crate) struct ShowWidget {
impl Default for ShowWidget { impl Default for ShowWidget {
fn default() -> Self { 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 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 sub_cont: gtk::Box = builder.get_object("sub_container").unwrap();
let cover: gtk::Image = builder.get_object("cover").unwrap(); let cover: gtk::Image = builder.get_object("cover").unwrap();
let description: gtk::Label = builder.get_object("description").unwrap(); let description: gtk::Label = builder.get_object("description").unwrap();
let view = BaseView::default();
let frame = gtk::Frame::new(None); let frame = gtk::Frame::new(None);
let episodes = gtk::ListBox::new(); let episodes = gtk::ListBox::new();
@ -58,12 +54,11 @@ impl Default for ShowWidget {
frame.add(&episodes); frame.add(&episodes);
sub_cont.add(&frame); sub_cont.add(&frame);
column.add(&sub_cont); column.add(&sub_cont);
scrolled_window.add(&column); view.add(&column);
column.show_all();
container.show_all();
ShowWidget { ShowWidget {
container, view,
scrolled_window,
cover, cover,
description, description,
episodes, episodes,
@ -95,6 +90,14 @@ impl ShowWidget {
debug_assert!(res.is_ok()); debug_assert!(res.is_ok());
} }
pub(crate) fn container(&self) -> &gtk::Box {
self.view.container()
}
pub(crate) fn scrolled_window(&self) -> &gtk::ScrolledWindow {
self.view.scrolled_window()
}
/// Set the show cover. /// Set the show cover.
fn set_cover(&self, pd: &Arc<Show>) -> Result<(), Error> { fn set_cover(&self, pd: &Arc<Show>) -> Result<(), Error> {
utils::set_image_from_path(&self.cover, pd.id(), 256) 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> { pub(crate) fn save_vadjustment(&self, oldid: i32) -> Result<(), Error> {
if let Ok(mut guard) = SHOW_WIDGET_VALIGNMENT.lock() { if let Ok(mut guard) = SHOW_WIDGET_VALIGNMENT.lock() {
let adj = self let adj = self
.scrolled_window .scrolled_window()
.get_vadjustment() .get_vadjustment()
.ok_or_else(|| format_err!("Could not get the adjustment"))?; .ok_or_else(|| format_err!("Could not get the adjustment"))?;
*guard = Some((oldid, Fragile::new(adj))); *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. // Copy the vertical scrollbar adjustment from the old view into the new one.
let res = fragile let res = fragile
.try_get() .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); .map_err(From::from);
debug_assert!(res.is_ok()); debug_assert!(res.is_ok());