muda/examples/winit.rs
2022-12-08 20:50:24 +02:00

190 lines
5.9 KiB
Rust

// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
#![allow(unused)]
use muda::{
accelerator::{Accelerator, Code, Modifiers},
menu_event_receiver, AboutMetadata, CheckMenuItem, ContextMenu, Menu, MenuItem,
PredefinedMenuItem, Submenu,
};
#[cfg(target_os = "macos")]
use winit::platform::macos::{EventLoopBuilderExtMacOS, WindowExtMacOS};
#[cfg(target_os = "windows")]
use winit::platform::windows::{EventLoopBuilderExtWindows, WindowExtWindows};
use winit::{
event::{ElementState, Event, MouseButton, WindowEvent},
event_loop::{ControlFlow, EventLoopBuilder},
window::{Window, WindowBuilder},
};
fn main() {
let mut event_loop_builder = EventLoopBuilder::new();
let menu_bar = Menu::new();
#[cfg(target_os = "windows")]
{
let menu_bar_c = menu_bar.clone();
event_loop_builder.with_msg_hook(move |msg| {
use windows_sys::Win32::UI::WindowsAndMessaging::{TranslateAcceleratorW, MSG};
unsafe {
let msg = msg as *const MSG;
let translated = TranslateAcceleratorW((*msg).hwnd, menu_bar_c.haccel(), msg);
translated == 1
}
});
}
#[cfg(target_os = "macos")]
event_loop_builder.with_default_menu(false);
let event_loop = event_loop_builder.build();
let window = WindowBuilder::new()
.with_title("Window 1")
.build(&event_loop)
.unwrap();
let window2 = WindowBuilder::new()
.with_title("Window 2")
.build(&event_loop)
.unwrap();
#[cfg(target_os = "macos")]
{
let app_m = Submenu::new("App", true);
menu_bar.append(&app_m);
app_m.append_items(&[
&PredefinedMenuItem::about(None, None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::services(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::hide(None),
&PredefinedMenuItem::hide_others(None),
&PredefinedMenuItem::show_all(None),
&PredefinedMenuItem::separator(),
&PredefinedMenuItem::quit(None),
]);
}
let file_m = Submenu::new("&File", true);
let edit_m = Submenu::new("&Edit", true);
let window_m = Submenu::new("&Window", true);
menu_bar.append_items(&[&file_m, &edit_m, &window_m]);
let custom_i_1 = MenuItem::new(
"C&ustom 1",
true,
Some(Accelerator::new(Some(Modifiers::ALT), Code::KeyC)),
);
let custom_i_2 = MenuItem::new("Custom 2", false, None);
let check_custom_i_1 = CheckMenuItem::new("Check Custom 1", true, true, None);
let check_custom_i_2 = CheckMenuItem::new("Check Custom 2", false, true, None);
let check_custom_i_3 = CheckMenuItem::new(
"Check Custom 3",
true,
true,
Some(Accelerator::new(Some(Modifiers::SHIFT), Code::KeyD)),
);
let copy_i = PredefinedMenuItem::copy(None);
let cut_i = PredefinedMenuItem::cut(None);
let paste_i = PredefinedMenuItem::paste(None);
file_m.append_items(&[
&custom_i_1,
&custom_i_2,
&window_m,
&PredefinedMenuItem::separator(),
&check_custom_i_1,
]);
window_m.append_items(&[
&PredefinedMenuItem::minimize(None),
&PredefinedMenuItem::maximize(None),
&PredefinedMenuItem::close_window(Some("Close")),
&PredefinedMenuItem::fullscreen(None),
&PredefinedMenuItem::about(
None,
Some(AboutMetadata {
name: Some("winit".to_string()),
copyright: Some("Copyright winit".to_string()),
..Default::default()
}),
),
&check_custom_i_3,
&custom_i_2,
&custom_i_1,
]);
edit_m.append_items(&[&copy_i, &paste_i, &PredefinedMenuItem::separator()]);
#[cfg(target_os = "windows")]
{
menu_bar.init_for_hwnd(window.hwnd() as _);
menu_bar.init_for_hwnd(window2.hwnd() as _);
}
#[cfg(target_os = "macos")]
{
menu_bar.init_for_nsapp();
window_m.set_windows_menu_for_nsapp();
}
let menu_channel = menu_event_receiver();
let mut x = 0_f64;
let mut y = 0_f64;
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => *control_flow = ControlFlow::Exit,
Event::WindowEvent {
event: WindowEvent::CursorMoved { position, .. },
window_id,
..
} => {
if window_id == window2.id() {
x = position.x;
y = position.y;
}
}
Event::WindowEvent {
event:
WindowEvent::MouseInput {
state: ElementState::Pressed,
button: MouseButton::Right,
..
},
window_id,
..
} => {
if window_id == window2.id() {
show_context_menu(&window2, &window_m, x, y);
}
}
Event::MainEventsCleared => {
window.request_redraw();
}
_ => (),
}
if let Ok(event) = menu_channel.try_recv() {
if event.id == custom_i_1.id() {
file_m.insert(&MenuItem::new("New Menu Item", false, None), 2);
}
println!("{:?}", event);
}
})
}
fn show_context_menu(window: &Window, menu: &dyn ContextMenu, x: f64, y: f64) {
#[cfg(target_os = "windows")]
menu.show_context_menu_for_hwnd(window.hwnd() as _, x, y);
#[cfg(target_os = "macos")]
menu.show_context_menu_for_nsview(window.ns_view() as _, x, y);
}