Skip to content

Commit

Permalink
Add animation section in config
Browse files Browse the repository at this point in the history
  • Loading branch information
filtsin committed Mar 22, 2023
1 parent 0afbdd1 commit 6335f79
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 87 deletions.
89 changes: 29 additions & 60 deletions src/animation.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use chrono::{DateTime, Utc};
use keyframe::{ease_with_scaled_time, functions::EaseInOut};
use std::{borrow::Cow, collections::HashMap, time::Duration};
use std::{
collections::HashMap,
time::{Duration, Instant},
};

#[derive(Default)]
pub struct Animator {
animations: HashMap<String, AnimationInner>,
remove_later: Vec<String>,
animations: HashMap<Animation, AnimationInner>,
remove_later: Vec<Animation>,
}

#[derive(Debug)]
Expand All @@ -14,87 +16,55 @@ struct AnimationInner {
end: f64,
current: f64,

start_time: DateTime<Utc>,
start_time: Instant,
duration: Duration,
t: AnimationType,
}

#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum AnimationType {
Single,
Repeat,
#[derive(Eq, PartialEq, Debug, Hash, Clone)]
pub enum Animation {
Height,
}

pub struct AnimationConfig {
pub height: Duration,
}

impl Animator {
pub fn new() -> Self {
Self::default()
}

pub fn add_animation(
&mut self,
name: Cow<'_, str>,
start: f64,
end: f64,
duration: Duration,
t: AnimationType,
) {
match self.animations.entry(name.into_owned()) {
pub fn add_animation(&mut self, name: Animation, start: f64, end: f64, duration: Duration) {
match self.animations.entry(name) {
std::collections::hash_map::Entry::Occupied(o) =>
panic!("Add already existed animation with {}. It is a bug. Please submit a bug to https://github.com/l4l/yofi/issues", o.key()),
panic!("Add already existed animation with {:?}. It is a bug. Please submit a bug to https://github.com/l4l/yofi/issues", o),
std::collections::hash_map::Entry::Vacant(v) => {
v.insert(AnimationInner::new(start, end, duration, t));
v.insert(AnimationInner::new(start, end, duration));
}
}
}

pub fn cancel_animation(&mut self, name: &str) {
self.animations.remove(name);
pub fn cancel_animation(&mut self, name: Animation) {
self.animations.remove(&name);
}

pub fn add_step_animation(
&mut self,
name: Cow<'_, str>,
start: f64,
end: f64,
step_duration: Duration,
t: AnimationType,
) {
let full_duration = Duration::from_millis(
((end - start) as u128 * step_duration.as_millis())
.try_into()
.unwrap_or(u64::MAX),
);
self.add_animation(name, start, end, full_duration, t);
pub fn contains(&self, name: Animation) -> bool {
self.animations.contains_key(&name)
}

pub fn contains(&self, name: &str) -> bool {
self.animations.contains_key(name)
}

pub fn get_value(&mut self, name: &str) -> Option<f64> {
Some(self.animations.get(name)?.current)
pub fn get_value(&mut self, name: Animation) -> Option<f64> {
Some(self.animations.get(&name)?.current)
}

pub fn proceed(&mut self) -> bool {
let current_time = Utc::now();
let current_time = Instant::now();

for name in std::mem::take(&mut self.remove_later).into_iter() {
let animation = self.animations.remove(&name).unwrap();
if animation.t == AnimationType::Repeat {
self.animations.insert(
name.clone(),
AnimationInner::new(
animation.start,
animation.end,
animation.duration,
animation.t,
),
);
}
self.animations.remove(&name).unwrap();
}

for (name, animation) in self.animations.iter_mut() {
let time = (current_time - animation.start_time).num_milliseconds() as f64;
let time = (current_time - animation.start_time).as_millis() as f64;

let mut start = animation.start;
let mut end = animation.end;
Expand Down Expand Up @@ -140,14 +110,13 @@ impl Animator {
}

impl AnimationInner {
fn new(start: f64, end: f64, duration: Duration, t: AnimationType) -> Self {
fn new(start: f64, end: f64, duration: Duration) -> Self {
Self {
start,
end,
current: start,
start_time: Utc::now(),
start_time: Instant::now(),
duration,
t,
}
}
}
15 changes: 11 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::ffi::CString;
use std::path::PathBuf;
use std::time::Duration;

use defaults::Defaults;
use serde::Deserialize;
Expand Down Expand Up @@ -32,8 +33,6 @@ pub struct Config {
#[def = "false"]
auto_height: bool,
#[def = "false"]
animations: bool,
#[def = "false"]
force_window: bool,
window_offsets: Option<(i32, i32)>,
scale: Option<u16>,
Expand All @@ -48,6 +47,7 @@ pub struct Config {
corner_radius: Radius,

icon: Option<Icon>,
animation: Option<Animation>,

input_text: InputText,
list_items: ListItems,
Expand All @@ -58,8 +58,8 @@ impl Config {
self.icon = None;
}

pub fn animations_enabled(&self) -> bool {
self.animations
pub fn animation(&self) -> &Option<Animation> {
&self.animation
}

pub fn set_prompt(&mut self, prompt: String) {
Expand Down Expand Up @@ -120,6 +120,13 @@ struct Icon {
fallback_icon_path: Option<PathBuf>,
}

#[derive(Defaults, Deserialize)]
#[serde(default)]
pub struct Animation {
#[def = "500"]
height_duration_ms: u64,
}

fn config_path() -> PathBuf {
xdg::BaseDirectories::with_prefix(crate::prog_name!())
.expect("failed to get xdg dirs")
Expand Down
9 changes: 9 additions & 0 deletions src/config/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::rc::Rc;
use once_cell::unsync::Lazy;

use super::*;
use crate::animation::AnimationConfig;
use crate::desktop::IconConfig;
use crate::draw::{BgParams, InputTextParams, ListParams};
use crate::font::{Font, FontBackend, InnerFont};
Expand Down Expand Up @@ -126,6 +127,14 @@ impl<'a> From<&'a Config> for Option<IconConfig> {
}
}

impl<'a> From<&'a Config> for Option<AnimationConfig> {
fn from(config: &'a Config) -> Option<AnimationConfig> {
config.animation.as_ref().map(|c| AnimationConfig {
height: Duration::from_millis(c.height_duration_ms),
})
}
}

fn default_font() -> Font {
std::thread_local! {
static DEFAULT_FONT: Lazy<Font> = Lazy::new(|| Rc::new(InnerFont::default()));
Expand Down
7 changes: 2 additions & 5 deletions src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub use list_view::{ListItem, Params as ListParams, ADDITIONAL_CAP};

use crate::{style::Radius, Color};

pub use self::list_view::ListViewInfo;

pub type DrawTarget<'a> = raqote::DrawTarget<&'a mut [u32]>;

mod background;
Expand All @@ -34,11 +36,6 @@ pub enum Widget<'a, It = std::iter::Empty<ListItem<'a>>> {
Background(background::Background),
}

pub struct ListViewInfo {
pub new_skip: usize,
pub new_y: u32,
}

impl<'a, It> Widget<'a, It> {
pub fn input_text(text: &'a str, params: &'a InputTextParams<'a>) -> Self {
Self::InputText(Box::new(input_text::InputText::new(text, params)))
Expand Down
7 changes: 6 additions & 1 deletion src/draw/list_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::{DrawTarget, Drawable, Space};
use crate::font::{Font, FontBackend, FontColor};
use crate::state::ContinuousMatch;
use crate::style::Margin;
use crate::{Color, ListViewInfo};
use crate::Color;
use unicode_segmentation::UnicodeSegmentation;

pub const ADDITIONAL_CAP: u32 = 10;
Expand Down Expand Up @@ -44,6 +44,11 @@ pub struct ListView<'a, It> {
_tparam: PhantomData<&'a ()>,
}

pub struct ListViewInfo {
pub new_skip: usize,
pub new_y: u32,
}

impl<'a, It> ListView<'a, It> {
pub fn new(
items: It,
Expand Down
32 changes: 17 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::HashSet;
use std::path::PathBuf;
use std::{collections::HashSet, time::Duration};

use animation::AnimationConfig;
use log::LevelFilter;
use sctk::{
environment::SimpleGlobal,
Expand All @@ -12,7 +13,7 @@ use sctk::{
};
use structopt::{clap::ArgGroup, StructOpt};

pub use animation::Animator;
pub use animation::{Animation, Animator};
pub use color::Color;
pub use desktop::Entry as DesktopEntry;
pub use draw::{DrawTarget, ListViewInfo};
Expand Down Expand Up @@ -218,7 +219,7 @@ fn main_inner() {
let background_config = config.param();
let input_config = config.param();
let list_config = config.param();
let animations = config.animations_enabled();
let animation_config = config.param();

if !env.get_shell().unwrap().needs_configure() {
draw(
Expand All @@ -228,7 +229,7 @@ fn main_inner() {
&input_config,
&list_config,
&mut surface,
animations,
&animation_config,
);
}

Expand All @@ -239,8 +240,8 @@ fn main_inner() {
loop {
let mut should_redraw = false;
for event in key_stream.try_iter() {
if animations {
animator.cancel_animation("HeightAnimation");
if animation_config.is_some() {
animator.cancel_animation(Animation::Height);
}

should_redraw = true;
Expand All @@ -256,7 +257,7 @@ fn main_inner() {
surface::EventStatus::Idle => {}
};

if animations && animator.proceed() {
if animation_config.is_some() && animator.proceed() {
should_redraw = true
}

Expand All @@ -268,13 +269,13 @@ fn main_inner() {
&input_config,
&list_config,
&mut surface,
animations,
&animation_config,
);
}

display.flush().unwrap();

let timeout = if animations {
let timeout = if animation_config.is_some() {
animator.proceed_step()
} else {
None
Expand Down Expand Up @@ -317,7 +318,7 @@ fn draw(
input_config: &draw::InputTextParams,
list_config: &draw::ListParams,
surface: &mut surface::Surface,
animations: bool,
animation_config: &Option<AnimationConfig>,
) {
use std::iter::once;

Expand All @@ -327,7 +328,7 @@ fn draw(

let old_height = surface.get_height();

match animator.get_value("HeightAnimation") {
match animator.get_value(Animation::Height) {
Some(value) => surface.update_height(value as u32),
None => surface.update_height(background_config.height),
}
Expand Down Expand Up @@ -357,11 +358,13 @@ fn draw(
+ list_config.margin.bottom as u32
+ ADDITIONAL_CAP;

if animator.contains("HeightAnimation") {
if animator.contains(Animation::Height) {
surface.commit();
return;
}

let animations = animation_config.is_some();

if full_height != old_height {
if full_height > background_config.height {
full_height = background_config.height;
Expand All @@ -372,11 +375,10 @@ fn draw(
// ListItem::show_default)
if animations && state.input_changed() {
animator.add_animation(
"HeightAnimation".into(),
Animation::Height,
old_height as f64,
full_height as f64,
Duration::from_millis(500),
animation::AnimationType::Single,
animation_config.as_ref().unwrap().height,
);
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,6 @@ impl Surface {
space_left.height -= occupied.height;
}
}

// Create a new buffer from the pool
}

pub fn commit(&mut self) {
Expand Down

0 comments on commit 6335f79

Please sign in to comment.