Desktop: show platform specific window buttons (#3078)
Implement app window button functionality and set platform
This commit is contained in:
parent
508606cdba
commit
c5991c6f61
|
|
@ -2,7 +2,7 @@ use crate::CustomEvent;
|
|||
use crate::cef::WindowSize;
|
||||
use crate::consts::{APP_NAME, CEF_MESSAGE_LOOP_MAX_ITERATIONS};
|
||||
use crate::render::GraphicsState;
|
||||
use graphite_desktop_wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage};
|
||||
use graphite_desktop_wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, Platform};
|
||||
use graphite_desktop_wrapper::{DesktopWrapper, NodeGraphExecutionResult, WgpuContext, serialize_frontend_messages};
|
||||
|
||||
use rfd::AsyncFileDialog;
|
||||
|
|
@ -152,6 +152,15 @@ impl WinitApp {
|
|||
graphics_state.set_overlays_scene(scene);
|
||||
}
|
||||
}
|
||||
DesktopFrontendMessage::UpdateWindowState { maximized, minimized } => {
|
||||
if let Some(window) = &self.window {
|
||||
window.set_maximized(maximized);
|
||||
window.set_minimized(minimized);
|
||||
}
|
||||
}
|
||||
DesktopFrontendMessage::CloseWindow => {
|
||||
let _ = self.event_loop_proxy.send_event(CustomEvent::CloseWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -223,9 +232,17 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
|
|||
tracing::info!("Winit window created and ready");
|
||||
|
||||
self.desktop_wrapper.init(self.wgpu_context.clone());
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let platform = Platform::Windows;
|
||||
#[cfg(target_os = "macos")]
|
||||
let platform = Platform::Mac;
|
||||
#[cfg(target_os = "linux")]
|
||||
let platform = Platform::Linux;
|
||||
self.dispatch_desktop_wrapper_message(DesktopWrapperMessage::UpdatePlatform(platform));
|
||||
}
|
||||
|
||||
fn user_event(&mut self, _: &ActiveEventLoop, event: CustomEvent) {
|
||||
fn user_event(&mut self, event_loop: &ActiveEventLoop, event: CustomEvent) {
|
||||
match event {
|
||||
CustomEvent::WebCommunicationInitialized => {
|
||||
self.web_communication_initialized = true;
|
||||
|
|
@ -268,6 +285,12 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
|
|||
self.cef_schedule = Some(instant);
|
||||
}
|
||||
}
|
||||
CustomEvent::CloseWindow => {
|
||||
// TODO: Implement graceful shutdown
|
||||
|
||||
tracing::info!("Exiting main event loop");
|
||||
event_loop.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -276,14 +299,12 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
|
|||
|
||||
match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
tracing::info!("The close button was pressed; stopping");
|
||||
event_loop.exit();
|
||||
let _ = self.event_loop_proxy.send_event(CustomEvent::CloseWindow);
|
||||
}
|
||||
WindowEvent::Resized(PhysicalSize { width, height }) => {
|
||||
let _ = self.window_size_sender.send(WindowSize::new(width as usize, height as usize));
|
||||
self.cef_context.notify_of_resize();
|
||||
}
|
||||
|
||||
WindowEvent::RedrawRequested => {
|
||||
let Some(ref mut graphics_state) = self.graphics_state else { return };
|
||||
// Only rerender once we have a new ui texture to display
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ pub(crate) enum CustomEvent {
|
|||
WebCommunicationInitialized,
|
||||
DesktopWrapperMessage(DesktopWrapperMessage),
|
||||
NodeGraphExecutionResult(NodeGraphExecutionResult),
|
||||
CloseWindow,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
use graphene_std::Color;
|
||||
use graphene_std::raster::Image;
|
||||
use graphite_editor::messages::prelude::{DocumentMessage, PortfolioMessage};
|
||||
use graphite_editor::messages::app_window::app_window_message_handler::AppWindowPlatform;
|
||||
use graphite_editor::messages::prelude::{AppWindowMessage, DocumentMessage, PortfolioMessage};
|
||||
|
||||
use crate::messages::Platform;
|
||||
|
||||
use super::DesktopWrapperMessageDispatcher;
|
||||
use super::messages::{DesktopFrontendMessage, DesktopWrapperMessage, EditorMessage, OpenFileDialogContext, SaveFileDialogContext};
|
||||
|
|
@ -106,5 +109,14 @@ pub(super) fn handle_desktop_wrapper_message(dispatcher: &mut DesktopWrapperMess
|
|||
dispatcher.queue_editor_message(message.into());
|
||||
}
|
||||
DesktopWrapperMessage::PollNodeGraphEvaluation => dispatcher.poll_node_graph_evaluation(),
|
||||
DesktopWrapperMessage::UpdatePlatform(platform) => {
|
||||
let platform = match platform {
|
||||
Platform::Windows => AppWindowPlatform::Windows,
|
||||
Platform::Mac => AppWindowPlatform::Mac,
|
||||
Platform::Linux => AppWindowPlatform::Linux,
|
||||
};
|
||||
let message = AppWindowMessage::AppWindowUpdatePlatform { platform };
|
||||
dispatcher.queue_editor_message(message.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,15 @@ pub(super) fn intercept_frontend_message(dispatcher: &mut DesktopWrapperMessageD
|
|||
FrontendMessage::TriggerVisitLink { url } => {
|
||||
dispatcher.respond(DesktopFrontendMessage::OpenUrl(url));
|
||||
}
|
||||
FrontendMessage::UpdateWindowState { maximized, minimized } => {
|
||||
dispatcher.respond(DesktopFrontendMessage::UpdateWindowState { maximized, minimized });
|
||||
|
||||
// Forward this to update the ui
|
||||
return Some(message);
|
||||
}
|
||||
FrontendMessage::CloseWindow => {
|
||||
dispatcher.respond(DesktopFrontendMessage::CloseWindow);
|
||||
}
|
||||
m => return Some(m),
|
||||
}
|
||||
None
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ pub enum DesktopFrontendMessage {
|
|||
height: f32,
|
||||
},
|
||||
UpdateOverlays(vello::Scene),
|
||||
UpdateWindowState {
|
||||
maximized: bool,
|
||||
minimized: bool,
|
||||
},
|
||||
CloseWindow,
|
||||
}
|
||||
|
||||
pub struct FileFilter {
|
||||
|
|
@ -47,6 +52,7 @@ pub enum DesktopWrapperMessage {
|
|||
ImportSvg { path: PathBuf, content: Vec<u8> },
|
||||
ImportImage { path: PathBuf, content: Vec<u8> },
|
||||
PollNodeGraphEvaluation,
|
||||
UpdatePlatform(Platform),
|
||||
}
|
||||
|
||||
pub enum OpenFileDialogContext {
|
||||
|
|
@ -58,3 +64,9 @@ pub enum SaveFileDialogContext {
|
|||
Document { document_id: DocumentId, content: Vec<u8> },
|
||||
File { content: Vec<u8> },
|
||||
}
|
||||
|
||||
pub enum Platform {
|
||||
Windows,
|
||||
Mac,
|
||||
Linux,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
use crate::messages::prelude::*;
|
||||
|
||||
use super::app_window_message_handler::AppWindowPlatform;
|
||||
|
||||
#[impl_message(Message, AppWindow)]
|
||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum AppWindowMessage {
|
||||
AppWindowMinimize,
|
||||
AppWindowMaximize,
|
||||
AppWindowUpdatePlatform { platform: AppWindowPlatform },
|
||||
AppWindowClose,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,34 +6,34 @@ use graphite_proc_macros::{ExtractField, message_handler_data};
|
|||
pub struct AppWindowMessageHandler {
|
||||
platform: AppWindowPlatform,
|
||||
maximized: bool,
|
||||
viewport_hole_punch_active: bool,
|
||||
minimized: bool,
|
||||
}
|
||||
|
||||
#[message_handler_data]
|
||||
impl MessageHandler<AppWindowMessage, ()> for AppWindowMessageHandler {
|
||||
fn process_message(&mut self, message: AppWindowMessage, responses: &mut std::collections::VecDeque<Message>, _: ()) {
|
||||
match message {
|
||||
AppWindowMessage::AppWindowMinimize => {
|
||||
self.platform = if self.platform == AppWindowPlatform::Mac {
|
||||
AppWindowPlatform::Windows
|
||||
} else {
|
||||
AppWindowPlatform::Mac
|
||||
};
|
||||
responses.add(FrontendMessage::UpdatePlatform { platform: self.platform });
|
||||
}
|
||||
AppWindowMessage::AppWindowMaximize => {
|
||||
self.maximized = !self.maximized;
|
||||
responses.add(FrontendMessage::UpdateMaximized { maximized: self.maximized });
|
||||
|
||||
self.viewport_hole_punch_active = !self.viewport_hole_punch_active;
|
||||
responses.add(FrontendMessage::UpdateViewportHolePunch {
|
||||
active: self.viewport_hole_punch_active,
|
||||
responses.add(FrontendMessage::UpdateWindowState {
|
||||
maximized: self.maximized,
|
||||
minimized: self.minimized,
|
||||
});
|
||||
}
|
||||
AppWindowMessage::AppWindowClose => {
|
||||
self.platform = AppWindowPlatform::Web;
|
||||
AppWindowMessage::AppWindowMinimize => {
|
||||
self.minimized = !self.minimized;
|
||||
responses.add(FrontendMessage::UpdateWindowState {
|
||||
maximized: self.maximized,
|
||||
minimized: self.minimized,
|
||||
});
|
||||
}
|
||||
AppWindowMessage::AppWindowUpdatePlatform { platform } => {
|
||||
self.platform = platform;
|
||||
responses.add(FrontendMessage::UpdatePlatform { platform: self.platform });
|
||||
}
|
||||
AppWindowMessage::AppWindowClose => {
|
||||
responses.add(FrontendMessage::CloseWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -329,9 +329,11 @@ pub enum FrontendMessage {
|
|||
UpdatePlatform {
|
||||
platform: AppWindowPlatform,
|
||||
},
|
||||
UpdateMaximized {
|
||||
UpdateWindowState {
|
||||
maximized: bool,
|
||||
minimized: bool,
|
||||
},
|
||||
CloseWindow,
|
||||
UpdateViewportHolePunch {
|
||||
active: bool,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -356,10 +356,13 @@ export class UpdatePlatform extends JsMessage {
|
|||
readonly platform!: AppWindowPlatform;
|
||||
}
|
||||
|
||||
export class UpdateMaximized extends JsMessage {
|
||||
export class UpdateWindowState extends JsMessage {
|
||||
readonly maximized!: boolean;
|
||||
readonly minimized!: boolean;
|
||||
}
|
||||
|
||||
export class CloseWindow extends JsMessage {}
|
||||
|
||||
export class UpdateViewportHolePunch extends JsMessage {
|
||||
readonly active!: boolean;
|
||||
}
|
||||
|
|
@ -1741,7 +1744,7 @@ export const messageMakers: Record<string, MessageMaker> = {
|
|||
UpdateLayersPanelControlBarLeftLayout,
|
||||
UpdateLayersPanelControlBarRightLayout,
|
||||
UpdateLayerWidths,
|
||||
UpdateMaximized,
|
||||
UpdateWindowState,
|
||||
UpdateMenuBarLayout,
|
||||
UpdateMouseCursor,
|
||||
UpdateNodeGraphControlBarLayout,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import { writable } from "svelte/store";
|
||||
|
||||
import { type Editor } from "@graphite/editor";
|
||||
import { type AppWindowPlatform, UpdatePlatform, UpdateMaximized, UpdateViewportHolePunch } from "@graphite/messages";
|
||||
import { type AppWindowPlatform, UpdatePlatform, UpdateViewportHolePunch, UpdateWindowState } from "@graphite/messages";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export function createAppWindowState(editor: Editor) {
|
||||
|
|
@ -20,9 +20,9 @@ export function createAppWindowState(editor: Editor) {
|
|||
return state;
|
||||
});
|
||||
});
|
||||
editor.subscriptions.subscribeJsMessage(UpdateMaximized, (maximized) => {
|
||||
editor.subscriptions.subscribeJsMessage(UpdateWindowState, (updateWindowState) => {
|
||||
update((state) => {
|
||||
state.maximized = maximized.maximized;
|
||||
state.maximized = updateWindowState.maximized;
|
||||
return state;
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue