winbats transp
This commit is contained in:
parent
3a59cc5ab6
commit
c234ae5308
|
|
@ -1,7 +1,7 @@
|
|||
#![cfg_attr(all(target_os = "windows", not(debug_assertions)), windows_subsystem = "windows")]
|
||||
|
||||
use std::num::NonZeroU32;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Instant;
|
||||
|
||||
use layers::ffi::ViewportHandle;
|
||||
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
|
||||
|
|
@ -14,6 +14,7 @@ use winit::window::{Window, WindowAttributes, WindowId, WindowLevel};
|
|||
|
||||
const DEFAULT_LOGICAL_SIZE: (u32, u32) = (480, 640);
|
||||
const MIN_LOGICAL_SIZE: (u32, u32) = (380, 220);
|
||||
const ALPHA_FADE_MS: u128 = 150;
|
||||
|
||||
fn main() {
|
||||
let plugin_root = discover_plugin_root();
|
||||
|
|
@ -45,7 +46,6 @@ fn run() {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ShellApp {
|
||||
window: Option<Box<Window>>,
|
||||
handle: Option<ViewportHandle>,
|
||||
|
|
@ -53,6 +53,27 @@ struct ShellApp {
|
|||
is_hovered: bool,
|
||||
modifiers: ModifiersState,
|
||||
last_cursor: PhysicalPosition<f64>,
|
||||
current_alpha: f32,
|
||||
target_alpha: f32,
|
||||
tween_from: f32,
|
||||
tween_started: Option<Instant>,
|
||||
}
|
||||
|
||||
impl Default for ShellApp {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
window: None,
|
||||
handle: None,
|
||||
is_focused: false,
|
||||
is_hovered: false,
|
||||
modifiers: ModifiersState::empty(),
|
||||
last_cursor: PhysicalPosition::new(0.0, 0.0),
|
||||
current_alpha: 1.0,
|
||||
target_alpha: 1.0,
|
||||
tween_from: 1.0,
|
||||
tween_started: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ApplicationHandler for ShellApp {
|
||||
|
|
@ -61,7 +82,6 @@ impl ApplicationHandler for ShellApp {
|
|||
return;
|
||||
}
|
||||
tracing::info!("resumed: creating window");
|
||||
let colors = layers::ui::colors::get();
|
||||
let attrs = WindowAttributes::default()
|
||||
.with_title("Layers")
|
||||
.with_inner_size(LogicalSize::new(DEFAULT_LOGICAL_SIZE.0, DEFAULT_LOGICAL_SIZE.1))
|
||||
|
|
@ -84,6 +104,7 @@ impl ApplicationHandler for ShellApp {
|
|||
|
||||
#[cfg(target_os = "windows")]
|
||||
apply_win11_chrome(&raw_window);
|
||||
set_window_alpha(&window, self.current_alpha);
|
||||
let raw_display = window
|
||||
.display_handle()
|
||||
.expect("winit: display handle")
|
||||
|
|
@ -113,7 +134,7 @@ impl ApplicationHandler for ShellApp {
|
|||
|
||||
self.window = Some(window);
|
||||
self.handle = Some(handle);
|
||||
self.apply_window_alpha(colors);
|
||||
self.refresh_target_alpha();
|
||||
}
|
||||
|
||||
fn window_event(
|
||||
|
|
@ -146,14 +167,17 @@ impl ApplicationHandler for ShellApp {
|
|||
}
|
||||
WindowEvent::Focused(focused) => {
|
||||
self.is_focused = focused;
|
||||
self.refresh_target_alpha();
|
||||
}
|
||||
WindowEvent::CursorEntered { .. } => {
|
||||
self.is_hovered = true;
|
||||
self.refresh_target_alpha();
|
||||
}
|
||||
WindowEvent::CursorLeft { .. } => {
|
||||
self.is_hovered = false;
|
||||
handle.push_mouse_left();
|
||||
window.request_redraw();
|
||||
self.refresh_target_alpha();
|
||||
}
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
self.last_cursor = position;
|
||||
|
|
@ -211,6 +235,7 @@ impl ApplicationHandler for ShellApp {
|
|||
}
|
||||
|
||||
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
|
||||
self.step_alpha_tween();
|
||||
if let Some(window) = self.window.as_ref() {
|
||||
window.request_redraw();
|
||||
}
|
||||
|
|
@ -218,17 +243,38 @@ impl ApplicationHandler for ShellApp {
|
|||
}
|
||||
|
||||
impl ShellApp {
|
||||
fn apply_window_alpha(&self, colors: &layers::ui::colors::Colors) {
|
||||
let Some(_window) = self.window.as_ref() else { return; };
|
||||
let alpha = if self.is_focused && self.is_hovered {
|
||||
fn refresh_target_alpha(&mut self) {
|
||||
let colors = layers::ui::colors::get();
|
||||
let target = if self.is_focused && self.is_hovered {
|
||||
colors.window.alpha_focused_hovered
|
||||
} else if self.is_focused || self.is_hovered {
|
||||
colors.window.alpha_partial
|
||||
} else {
|
||||
colors.window.alpha_idle
|
||||
};
|
||||
let _ = alpha;
|
||||
let _ = NonZeroU32::new(1);
|
||||
if (target - self.target_alpha).abs() < 0.001 {
|
||||
return;
|
||||
}
|
||||
self.tween_from = self.current_alpha;
|
||||
self.target_alpha = target;
|
||||
self.tween_started = Some(Instant::now());
|
||||
}
|
||||
|
||||
fn step_alpha_tween(&mut self) {
|
||||
let Some(started) = self.tween_started else { return; };
|
||||
let Some(window) = self.window.as_ref() else { return; };
|
||||
let prev = self.current_alpha;
|
||||
let elapsed = started.elapsed().as_millis();
|
||||
if elapsed >= ALPHA_FADE_MS {
|
||||
self.current_alpha = self.target_alpha;
|
||||
self.tween_started = None;
|
||||
} else {
|
||||
let t = elapsed as f32 / ALPHA_FADE_MS as f32;
|
||||
self.current_alpha = self.tween_from + (self.target_alpha - self.tween_from) * t;
|
||||
}
|
||||
if (self.current_alpha - prev).abs() > 0.001 || self.tween_started.is_none() {
|
||||
set_window_alpha(window, self.current_alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,6 +304,33 @@ fn encode_modifiers(mods: ModifiersState) -> u32 {
|
|||
bits
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn set_window_alpha(window: &Window, alpha: f32) {
|
||||
use raw_window_handle::RawWindowHandle;
|
||||
use windows::Win32::Foundation::{COLORREF, HWND};
|
||||
use windows::Win32::UI::WindowsAndMessaging::{
|
||||
GetWindowLongPtrW, SetLayeredWindowAttributes, SetWindowLongPtrW,
|
||||
GWL_EXSTYLE, LWA_ALPHA, WS_EX_LAYERED,
|
||||
};
|
||||
|
||||
let Ok(handle) = window.window_handle() else { return; };
|
||||
let RawWindowHandle::Win32(win32) = handle.as_raw() else { return; };
|
||||
let hwnd = HWND(win32.hwnd.get() as *mut _);
|
||||
|
||||
let a = (alpha.clamp(0.0, 1.0) * 255.0).round() as u8;
|
||||
unsafe {
|
||||
let ex = GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
|
||||
let layered = WS_EX_LAYERED.0 as isize;
|
||||
if ex & layered == 0 {
|
||||
SetWindowLongPtrW(hwnd, GWL_EXSTYLE, ex | layered);
|
||||
}
|
||||
let _ = SetLayeredWindowAttributes(hwnd, COLORREF(0), a, LWA_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn set_window_alpha(_window: &Window, _alpha: f32) {}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn apply_win11_chrome(raw_window: &raw_window_handle::RawWindowHandle) {
|
||||
use raw_window_handle::RawWindowHandle;
|
||||
|
|
|
|||
Loading…
Reference in New Issue