h-gtk: Refactor EpisodesStack.

This commit is contained in:
Jordan Petridis 2018-04-20 17:23:07 +03:00
parent 9a5cc1595d
commit 173d2d3a3a
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
4 changed files with 54 additions and 49 deletions

View File

@ -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<ShowStack>,
episodes: Rc<EpisodeStack>,
episodes: Rc<RefCell<EpisodeStack>>,
sender: Sender<Action>,
}
impl Content {
pub fn new(sender: Sender<Action>) -> Result<Content, Error> {
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();

View File

@ -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<Option<SendCell<gtk::Adjustment>>> =
Mutex::new(None);
}
#[derive(Debug, Clone)]
pub struct EpisodeStack {
stack: gtk::Stack,
empty: EmptyView,
episodes: Rc<EpisodesView>,
sender: Sender<Action>,
}
@ -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::<gtk::Box>()
.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: &gtk::Stack) -> Result<(), DataError> {
Ok(())
}
// ATTENTION: EXPECTS THE EPISODE_VIEW WIDGET CONTAINER
fn save_alignment(old_widget: &gtk::Box) -> Result<(), Error> {
let scrolled_window = old_widget
.get_children()
.first()
.ok_or_else(|| format_err!("Box container has no childs."))?
.clone()
.downcast::<gtk::ScrolledWindow>()
.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(())
}

View File

@ -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};

View File

@ -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<Option<SendCell<gtk::Adjustment>>> =
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]