mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-25 19:01:19 +01:00
feature: animation
Commit to pull changes from master
This commit is contained in:
55
komorebi/src/animation.rs
Normal file
55
komorebi/src/animation.rs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ use crate::windows_api::WindowsApi;
|
||||
#[macro_use]
|
||||
mod ring;
|
||||
|
||||
mod animation;
|
||||
mod border;
|
||||
mod com;
|
||||
mod container;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user