feature: animation

Commit to pull changes from master
This commit is contained in:
thearturca
2023-09-24 12:37:26 +03:00
committed by LGUG2Z
parent d9eea34266
commit 9d1c0ad790
3 changed files with 83 additions and 1 deletions

55
komorebi/src/animation.rs Normal file
View File

@@ -0,0 +1,55 @@
use color_eyre::Result;
use komorebi_core::Rect;
use std::thread::sleep;
use std::time::Duration;
use std::time::Instant;
pub struct Animation;
impl Animation {
pub fn lerp(x: i32, new_x: i32, t: f64) -> i32 {
(x as f64 + (new_x - x) as f64 * t) as i32
}
pub fn lerp_rect(original_rect: &Rect, new_rect: &Rect, t: f64) -> Rect {
let is_half_way = t > 0.5;
let mut rect = Rect::default();
rect.top = Animation::lerp(original_rect.top, new_rect.top, t);
rect.left = Animation::lerp(original_rect.left, new_rect.left, t);
rect.bottom = if is_half_way {
new_rect.bottom
} else {
original_rect.bottom
};
rect.right = if is_half_way {
new_rect.right
} else {
original_rect.right
};
rect
}
pub fn animate(duration: Duration, mut f: impl FnMut(f64) -> Result<()>) -> bool {
let target_frame_time = Duration::from_millis(1000 / 240);
let mut progress = 0.0;
let &animation_start = &Instant::now();
while progress < 1.0 {
let tick_start = Instant::now();
f(progress).unwrap();
progress = animation_start.elapsed().as_millis() as f64 / duration.as_millis() as f64;
if progress > 1.0 {
progress = 1.0;
}
while tick_start.elapsed() < target_frame_time {
sleep(target_frame_time - tick_start.elapsed());
}
}
f(progress).unwrap();
true
}
}

View File

@@ -65,6 +65,7 @@ use crate::windows_api::WindowsApi;
#[macro_use]
mod ring;
mod animation;
mod border;
mod com;
mod container;

View File

@@ -5,6 +5,8 @@ use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Write as _;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::Duration;
use color_eyre::eyre::anyhow;
use color_eyre::Result;
@@ -25,6 +27,7 @@ use komorebi_core::ApplicationIdentifier;
use komorebi_core::HidingBehaviour;
use komorebi_core::Rect;
use crate::animation::Animation;
use crate::styles::ExtendedWindowStyle;
use crate::styles::WindowStyle;
use crate::window_manager_event::WindowManagerEvent;
@@ -122,6 +125,22 @@ impl Window {
true,
)
}
pub fn animate_position(hwnd: HWND, layout: &Rect, top: bool) -> Result<()> {
let duration = Duration::from_millis(200);
let curr_rect = WindowsApi::window_rect(hwnd).unwrap();
if assert_eq!(curr_rect, *layout) {
WindowsApi::position_window(hwnd, layout, top);
}
let animate_window = |progress: f64| {
let new_rect = Animation::lerp_rect(&curr_rect, layout, progress);
WindowsApi::position_window(hwnd, &new_rect, top);
};
Animation::animate(duration, animate_window);
Ok(())
}
pub fn set_position(
&mut self,
@@ -154,7 +173,14 @@ impl Window {
rect.bottom += invisible_borders.bottom;
}
WindowsApi::position_window(self.hwnd(), &rect, top)
let hwnd = self.hwnd();
thread::spawn(move || {
Window::animate_position(hwnd, &rect, top).unwrap();
});
Ok(())
// WindowsApi::position_window(self.hwnd(), &rect, top)
}
pub fn hide(self) {