h-gtk: Animate the adjustment of scrolled windows.

Many thanks to Julian Spaber for documenting this.
This commit is contained in:
Jordan Petridis 2018-04-29 19:07:12 +03:00
parent b0ac037964
commit 8951a6e237
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
3 changed files with 41 additions and 6 deletions

View File

@ -1,5 +1,6 @@
#![cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
use gdk::FrameClockExt;
use gdk_pixbuf::Pixbuf;
use glib;
use gtk;
@ -101,6 +102,40 @@ where
});
}
// Kudos to Julian Sparber
// https://blogs.gnome.org/jsparber/2018/04/29/animate-a-scrolledwindow/
pub fn smooth_scroll_to(view: gtk::ScrolledWindow, target: gtk::Adjustment) {
if let Some(adj) = view.get_vadjustment() {
if let Some(clock) = view.get_frame_clock() {
let duration = 200;
let start = adj.get_value();
let end = target.get_value();
let start_time = clock.get_frame_time();
let end_time = start_time + 1000 * duration;
view.add_tick_callback(move |_, clock| {
let now = clock.get_frame_time();
if now < end_time && adj.get_value() != end {
let mut t = (now - start_time) as f64 / (end_time - start_time) as f64;
t = ease_out_cubic(t);
adj.set_value(start + t * (end - start));
return glib::Continue(true);
} else {
adj.set_value(end);
return glib::Continue(false);
}
});
}
}
}
// From clutter-easing.c, based on Robert Penner's
// infamous easing equations, MIT license.
fn ease_out_cubic(t: f64) -> f64 {
let p = t - 1f64;
return p * p * p + 1f64;
}
lazy_static! {
static ref IGNORESHOWS: Arc<Mutex<HashSet<i32>>> = Arc::new(Mutex::new(HashSet::new()));
}

View File

@ -1,5 +1,6 @@
use chrono::prelude::*;
use failure::Error;
use gtk;
use gtk::prelude::*;
@ -8,8 +9,7 @@ use hammond_data::EpisodeWidgetQuery;
use send_cell::SendCell;
use app::Action;
use utils::lazy_load_full;
use utils::{get_ignored_shows, set_image_from_path};
use utils::{self, lazy_load_full};
use widgets::EpisodeWidget;
use std::rc::Rc;
@ -90,7 +90,7 @@ impl HomeView {
use self::ListSplit::*;
let view = Rc::new(HomeView::default());
let ignore = get_ignored_shows()?;
let ignore = utils::get_ignored_shows()?;
let episodes = dbqueries::get_episodes_widgets_filter_limit(&ignore, 100)?;
let now_utc = Utc::now();
@ -132,7 +132,7 @@ impl HomeView {
// Copy the vertical scrollbar adjustment from the old view into the new one.
sendcell
.try_get()
.map(|x| self.scrolled_window.set_vadjustment(&x));
.map(|x| utils::smooth_scroll_to(self.scrolled_window.clone(), x.clone()));
}
Ok(())
@ -231,6 +231,6 @@ impl EpisodesViewWidget {
#[inline]
fn set_cover(&self, podcast_id: i32) -> Result<(), Error> {
set_image_from_path(&self.image, podcast_id, 64)
utils::set_image_from_path(&self.image, podcast_id, 64)
}
}

View File

@ -165,7 +165,7 @@ impl ShowWidget {
// Copy the vertical scrollbar adjustment from the old view into the new one.
sendcell
.try_get()
.map(|x| self.scrolled_window.set_vadjustment(&x));
.map(|x| utils::smooth_scroll_to(self.scrolled_window.clone(), x.clone()));
}
Ok(())