From 173d2d3a3a3da584f9cc7056bdff328dcc9c4d12 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 20 Apr 2018 17:23:07 +0300 Subject: [PATCH] h-gtk: Refactor EpisodesStack. --- hammond-gtk/src/stacks/content.rs | 8 ++-- hammond-gtk/src/stacks/episode.rs | 68 ++++++++++++------------------- hammond-gtk/src/stacks/mod.rs | 2 +- hammond-gtk/src/views/episodes.rs | 25 ++++++++++-- 4 files changed, 54 insertions(+), 49 deletions(-) diff --git a/hammond-gtk/src/stacks/content.rs b/hammond-gtk/src/stacks/content.rs index 155ff30..9d3bd4a 100644 --- a/hammond-gtk/src/stacks/content.rs +++ b/hammond-gtk/src/stacks/content.rs @@ -7,6 +7,7 @@ use app::Action; use stacks::EpisodeStack; use stacks::ShowStack; +use std::cell::RefCell; use std::rc::Rc; use std::sync::mpsc::Sender; @@ -14,17 +15,17 @@ use std::sync::mpsc::Sender; pub struct Content { stack: gtk::Stack, shows: Rc, - episodes: Rc, + episodes: Rc>, sender: Sender, } impl Content { pub fn new(sender: Sender) -> Result { let stack = gtk::Stack::new(); - let episodes = Rc::new(EpisodeStack::new(sender.clone())?); + let episodes = Rc::new(RefCell::new(EpisodeStack::new(sender.clone())?)); let shows = Rc::new(ShowStack::new(sender.clone())?); - stack.add_titled(&episodes.get_stack(), "episodes", "Episodes"); + stack.add_titled(&episodes.borrow().get_stack(), "episodes", "Episodes"); stack.add_titled(&shows.get_stack(), "shows", "Shows"); Ok(Content { @@ -44,6 +45,7 @@ impl Content { // TODO: Maybe propagate the error? pub fn update_episode_view(&self) { self.episodes + .borrow_mut() .update() .map_err(|err| error!("Failed to update EpisodeView: {}", err)) .ok(); diff --git a/hammond-gtk/src/stacks/episode.rs b/hammond-gtk/src/stacks/episode.rs index 28dca54..a25e086 100644 --- a/hammond-gtk/src/stacks/episode.rs +++ b/hammond-gtk/src/stacks/episode.rs @@ -1,26 +1,21 @@ use gtk; use gtk::prelude::*; -use gtk::Cast; use failure::Error; use hammond_data::dbqueries::is_episodes_populated; use hammond_data::errors::DataError; -use send_cell::SendCell; use app::Action; use views::{EmptyView, EpisodesView}; +use std::rc::Rc; use std::sync::mpsc::Sender; -use std::sync::Mutex; - -lazy_static! { - pub static ref EPISODES_VIEW_VALIGNMENT: Mutex>> = - Mutex::new(None); -} #[derive(Debug, Clone)] pub struct EpisodeStack { stack: gtk::Stack, + empty: EmptyView, + episodes: Rc, sender: Sender, } @@ -34,30 +29,41 @@ impl EpisodeStack { stack.add_named(&empty.container, "empty"); set_stack_visible(&stack)?; - Ok(EpisodeStack { stack, sender }) + Ok(EpisodeStack { + stack, + empty, + episodes, + sender, + }) } - // Look into refactoring to a state-machine. - pub fn update(&self) -> Result<(), Error> { - let old = self.stack - .get_child_by_name("episodes") - .ok_or_else(|| format_err!("Faild to get \"episodes\" child from the stack."))? - .downcast::() - .map_err(|_| format_err!("Failed to downcast stack child to a Box."))?; - debug!("Name: {:?}", WidgetExt::get_name(&old)); - + pub fn update(&mut self) -> Result<(), Error> { // Copy the vertical scrollbar adjustment from the old view. - save_alignment(&old) + self.episodes + .save_alignment() .map_err(|err| error!("Failed to set episodes_view allignment: {}", err)) .ok(); + self.replace_view()?; + set_stack_visible(&self.stack)?; + Ok(()) + } + + fn replace_view(&mut self) -> Result<(), Error> { + // Get the container of the view + let old = self.episodes.container.clone(); let eps = EpisodesView::new(self.sender.clone())?; + // Remove the old widget and add the new one self.stack.remove(&old); self.stack.add_named(&eps.container, "episodes"); - set_stack_visible(&self.stack)?; + // replace view in the struct too + self.episodes = eps; + + // This might not be needed old.destroy(); + Ok(()) } @@ -76,25 +82,3 @@ fn set_stack_visible(stack: >k::Stack) -> Result<(), DataError> { Ok(()) } - -// ATTENTION: EXPECTS THE EPISODE_VIEW WIDGET CONTAINER -fn save_alignment(old_widget: >k::Box) -> Result<(), Error> { - let scrolled_window = old_widget - .get_children() - .first() - .ok_or_else(|| format_err!("Box container has no childs."))? - .clone() - .downcast::() - .map_err(|_| format_err!("Failed to downcast stack child to a ScrolledWindow."))?; - debug!("Name: {:?}", WidgetExt::get_name(&scrolled_window)); - - if let Ok(mut guard) = EPISODES_VIEW_VALIGNMENT.lock() { - let adj = scrolled_window - .get_vadjustment() - .ok_or_else(|| format_err!("Could not get the adjustment"))?; - *guard = Some(SendCell::new(adj)); - info!("Saved episodes_view alignment."); - } - - Ok(()) -} diff --git a/hammond-gtk/src/stacks/mod.rs b/hammond-gtk/src/stacks/mod.rs index f75b606..8c8a843 100644 --- a/hammond-gtk/src/stacks/mod.rs +++ b/hammond-gtk/src/stacks/mod.rs @@ -3,5 +3,5 @@ mod episode; mod show; pub use self::content::Content; -pub use self::episode::{EpisodeStack, EPISODES_VIEW_VALIGNMENT}; +pub use self::episode::EpisodeStack; pub use self::show::{ShowStack, SHOW_WIDGET_VALIGNMENT}; diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 185d2b8..fafca83 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -5,6 +5,7 @@ use gtk::prelude::*; use hammond_data::dbqueries; use hammond_data::EpisodeWidgetQuery; +use send_cell::SendCell; use app::Action; use utils::lazy_load_full; @@ -13,6 +14,12 @@ use widgets::EpisodeWidget; use std::rc::Rc; use std::sync::mpsc::Sender; +use std::sync::Mutex; + +lazy_static! { + pub static ref EPISODES_VIEW_VALIGNMENT: Mutex>> = + Mutex::new(None); +} #[derive(Debug, Clone)] enum ListSplit { @@ -26,7 +33,7 @@ enum ListSplit { #[derive(Debug, Clone)] pub struct EpisodesView { pub container: gtk::Box, - scrolled_window: gtk::ScrolledWindow, + pub scrolled_window: gtk::ScrolledWindow, frame_parent: gtk::Box, today_box: gtk::Box, yday_box: gtk::Box, @@ -117,8 +124,6 @@ impl EpisodesView { #[inline] /// Set scrolled window vertical adjustment. fn set_vadjustment(&self) -> Result<(), Error> { - use stacks::EPISODES_VIEW_VALIGNMENT; - let guard = EPISODES_VIEW_VALIGNMENT .lock() .map_err(|err| format_err!("Failed to lock widget align mutex: {}", err))?; @@ -132,6 +137,20 @@ impl EpisodesView { Ok(()) } + + #[inline] + /// Save the vertical scrollbar position. + pub fn save_alignment(&self) -> Result<(), Error> { + if let Ok(mut guard) = EPISODES_VIEW_VALIGNMENT.lock() { + let adj = self.scrolled_window + .get_vadjustment() + .ok_or_else(|| format_err!("Could not get the adjustment"))?; + *guard = Some(SendCell::new(adj)); + info!("Saved episodes_view alignment."); + } + + Ok(()) + } } #[inline]