mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-23 05:18:11 +08:00
Desktop: Add support for UI scaling (#3310)
* desktop support ui scaling * fix some warnings * use browser zoom if needed * fix infinite footprint size * fix web canvas scale * always set zoom * use only zoom for scaling * prevent user zoom * remove mouse position scaling
This commit is contained in:
+69
-32
@@ -38,8 +38,8 @@ use texture_import::SharedTextureHandle;
|
||||
|
||||
pub(crate) use context::{CefContext, CefContextBuilder, InitError};
|
||||
|
||||
pub(crate) trait CefEventHandler: Clone + Send + Sync + 'static {
|
||||
fn window_size(&self) -> WindowSize;
|
||||
pub(crate) trait CefEventHandler: Send + Sync + 'static {
|
||||
fn view_info(&self) -> ViewInfo;
|
||||
fn draw<'a>(&self, frame_buffer: FrameBufferRef<'a>);
|
||||
#[cfg(feature = "accelerated_paint")]
|
||||
fn draw_gpu(&self, shared_texture: SharedTextureHandle);
|
||||
@@ -50,24 +50,54 @@ pub(crate) trait CefEventHandler: Clone + Send + Sync + 'static {
|
||||
fn schedule_cef_message_loop_work(&self, scheduled_time: Instant);
|
||||
fn initialized_web_communication(&self);
|
||||
fn receive_web_message(&self, message: &[u8]);
|
||||
fn duplicate(&self) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct WindowSize {
|
||||
pub(crate) width: usize,
|
||||
pub(crate) height: usize,
|
||||
pub(crate) struct ViewInfo {
|
||||
width: usize,
|
||||
height: usize,
|
||||
scale: f64,
|
||||
}
|
||||
impl WindowSize {
|
||||
pub(crate) fn new(width: usize, height: usize) -> Self {
|
||||
Self { width, height }
|
||||
impl ViewInfo {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { width: 1, height: 1, scale: 1. }
|
||||
}
|
||||
pub(crate) fn apply_update(&mut self, update: ViewInfoUpdate) {
|
||||
match update {
|
||||
ViewInfoUpdate::Size { width, height } if width > 0 && height > 0 => {
|
||||
self.width = width;
|
||||
self.height = height;
|
||||
}
|
||||
ViewInfoUpdate::Scale(scale) if scale > 0. => {
|
||||
self.scale = scale;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
pub(crate) fn zoom(&self) -> f64 {
|
||||
self.scale.ln() / 1.2_f64.ln()
|
||||
}
|
||||
pub(crate) fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
pub(crate) fn height(&self) -> usize {
|
||||
self.height
|
||||
}
|
||||
}
|
||||
impl From<winit::dpi::PhysicalSize<u32>> for WindowSize {
|
||||
fn from(size: winit::dpi::PhysicalSize<u32>) -> Self {
|
||||
Self::new(size.width as usize, size.height as usize)
|
||||
impl Default for ViewInfo {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum ViewInfoUpdate {
|
||||
Size { width: usize, height: usize },
|
||||
Scale(f64),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Resource {
|
||||
pub(crate) reader: ResourceReader,
|
||||
@@ -89,34 +119,33 @@ impl Read for ResourceReader {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CefHandler {
|
||||
wgpu_context: WgpuContext,
|
||||
app_event_scheduler: AppEventScheduler,
|
||||
window_size_receiver: Arc<Mutex<WindowSizeReceiver>>,
|
||||
view_info_receiver: Arc<Mutex<ViewInfoReceiver>>,
|
||||
}
|
||||
|
||||
impl CefHandler {
|
||||
pub(crate) fn new(wgpu_context: WgpuContext, app_event_scheduler: AppEventScheduler, window_size_receiver: Receiver<WindowSize>) -> Self {
|
||||
pub(crate) fn new(wgpu_context: WgpuContext, app_event_scheduler: AppEventScheduler, view_info_receiver: Receiver<ViewInfoUpdate>) -> Self {
|
||||
Self {
|
||||
wgpu_context,
|
||||
app_event_scheduler,
|
||||
window_size_receiver: Arc::new(Mutex::new(WindowSizeReceiver::new(window_size_receiver))),
|
||||
view_info_receiver: Arc::new(Mutex::new(ViewInfoReceiver::new(view_info_receiver))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CefEventHandler for CefHandler {
|
||||
fn window_size(&self) -> WindowSize {
|
||||
let Ok(mut guard) = self.window_size_receiver.lock() else {
|
||||
tracing::error!("Failed to lock window_size_receiver");
|
||||
return WindowSize::new(1, 1);
|
||||
fn view_info(&self) -> ViewInfo {
|
||||
let Ok(mut guard) = self.view_info_receiver.lock() else {
|
||||
tracing::error!("Failed to lock view_info_receiver");
|
||||
return ViewInfo::new();
|
||||
};
|
||||
let WindowSizeReceiver { receiver, window_size } = &mut *guard;
|
||||
for new_window_size in receiver.try_iter() {
|
||||
*window_size = new_window_size;
|
||||
let ViewInfoReceiver { receiver, view_info } = &mut *guard;
|
||||
for update in receiver.try_iter() {
|
||||
view_info.apply_update(update);
|
||||
}
|
||||
*window_size
|
||||
*view_info
|
||||
}
|
||||
fn draw<'a>(&self, frame_buffer: FrameBufferRef<'a>) {
|
||||
let width = frame_buffer.width() as u32;
|
||||
@@ -244,17 +273,25 @@ impl CefEventHandler for CefHandler {
|
||||
};
|
||||
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(desktop_wrapper_message));
|
||||
}
|
||||
}
|
||||
|
||||
struct WindowSizeReceiver {
|
||||
window_size: WindowSize,
|
||||
receiver: Receiver<WindowSize>,
|
||||
}
|
||||
impl WindowSizeReceiver {
|
||||
fn new(window_size_receiver: Receiver<WindowSize>) -> Self {
|
||||
fn duplicate(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Self {
|
||||
window_size: WindowSize { width: 1, height: 1 },
|
||||
receiver: window_size_receiver,
|
||||
wgpu_context: self.wgpu_context.clone(),
|
||||
app_event_scheduler: self.app_event_scheduler.clone(),
|
||||
view_info_receiver: self.view_info_receiver.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ViewInfoReceiver {
|
||||
view_info: ViewInfo,
|
||||
receiver: Receiver<ViewInfoUpdate>,
|
||||
}
|
||||
impl ViewInfoReceiver {
|
||||
fn new(receiver: Receiver<ViewInfoUpdate>) -> Self {
|
||||
Self { view_info: ViewInfo::new(), receiver }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user