mirror of
https://github.com/tauri-apps/winit.git
synced 2026-02-04 10:21:18 +01:00
Cleanup
This commit is contained in:
@@ -18,12 +18,10 @@ fn main() {
|
||||
.with_title("A fantastic window!")
|
||||
.with_menu(vec![
|
||||
Menu::new(
|
||||
"",
|
||||
// on macOS first menu is always app name
|
||||
"my custom app",
|
||||
vec![
|
||||
MenuItem::About("Todos".to_string()),
|
||||
MenuItem::Separator,
|
||||
MenuItem::new("preferences".to_string(), "Preferences".to_string()).key(","),
|
||||
MenuItem::Separator,
|
||||
MenuItem::Services,
|
||||
MenuItem::Separator,
|
||||
MenuItem::Hide,
|
||||
@@ -34,9 +32,9 @@ fn main() {
|
||||
],
|
||||
),
|
||||
Menu::new(
|
||||
"Custom menu",
|
||||
"File",
|
||||
vec![
|
||||
MenuItem::new("add_todo".to_string(), "Add Todo".to_string()).key("+"),
|
||||
MenuItem::new("change_menu".to_string(), "Change menu".to_string()).key("+"),
|
||||
MenuItem::Separator,
|
||||
MenuItem::CloseWindow,
|
||||
],
|
||||
@@ -56,7 +54,10 @@ fn main() {
|
||||
),
|
||||
Menu::new("View", vec![MenuItem::EnterFullScreen]),
|
||||
Menu::new("Window", vec![MenuItem::Minimize, MenuItem::Zoom]),
|
||||
Menu::new("Help", vec![]),
|
||||
Menu::new(
|
||||
"Help",
|
||||
vec![MenuItem::new("help_me".to_string(), "Custom help".to_string()).key("-")],
|
||||
),
|
||||
])
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
@@ -72,7 +73,21 @@ fn main() {
|
||||
Event::MainEventsCleared => {
|
||||
window.request_redraw();
|
||||
}
|
||||
// not sure if we should add a new event type?
|
||||
// or try to re-use the UserEvent::<T>
|
||||
Event::MenuEvent(menu_id) => {
|
||||
if menu_id == "change_menu" {
|
||||
// update menu
|
||||
window.set_menu(Some(vec![Menu::new(
|
||||
"File",
|
||||
vec![
|
||||
MenuItem::new("add_todo".to_string(), "Add Todo".to_string()).key("+"),
|
||||
MenuItem::Separator,
|
||||
MenuItem::CloseWindow,
|
||||
],
|
||||
)]))
|
||||
}
|
||||
|
||||
println!("Clicked on {}", menu_id);
|
||||
window.set_title("New window title!");
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use simple_logger::SimpleLogger;
|
||||
use winit::{
|
||||
event::{ElementState, Event, KeyboardInput, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
menu::{Menu, MenuItem},
|
||||
window::{Window, WindowBuilder},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
SimpleLogger::new().init().unwrap();
|
||||
let event_loop = EventLoop::new();
|
||||
|
||||
let mut windows = HashMap::new();
|
||||
for _ in 0..3 {
|
||||
let window = WindowBuilder::new()
|
||||
.with_menu(vec![Menu::new(
|
||||
"asf",
|
||||
vec![
|
||||
MenuItem::About("My app!".to_string()),
|
||||
MenuItem::Separator,
|
||||
MenuItem::ShowAll,
|
||||
],
|
||||
)])
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
windows.insert(window.id(), window);
|
||||
}
|
||||
|
||||
event_loop.run(move |event, event_loop, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
||||
match event {
|
||||
Event::WindowEvent { event, window_id } => {
|
||||
match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
println!("Window {:?} has received the signal to close", window_id);
|
||||
|
||||
// This drops the window, causing it to close.
|
||||
windows.remove(&window_id);
|
||||
|
||||
if windows.is_empty() {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
}
|
||||
WindowEvent::KeyboardInput {
|
||||
input:
|
||||
KeyboardInput {
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
let window = Window::new(&event_loop).unwrap();
|
||||
windows.insert(window.id(), window);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
})
|
||||
}
|
||||
20
src/menu.rs
20
src/menu.rs
@@ -15,6 +15,10 @@ impl Menu {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CustomMenu {
|
||||
// todo: replace id by a type that
|
||||
// we can send from the with_menu::<T>()
|
||||
// or we could check to use the UserEvent::<T> but
|
||||
// my latest test failed
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub key: Option<String>,
|
||||
@@ -22,15 +26,10 @@ pub struct CustomMenu {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MenuItem {
|
||||
/// A custom MenuItem. This type functions as a builder, so you can customize it easier.
|
||||
/// You can (and should) create this variant via the `new(title)` method, but if you need to do
|
||||
/// something crazier, then wrap it in this and you can hook into the Cacao menu system
|
||||
/// accordingly.
|
||||
/// A custom MenuItem
|
||||
Custom(CustomMenu),
|
||||
|
||||
/// Shows a standard "About" item, which will bring up the necessary window when clicked
|
||||
/// (include a `credits.html` in your App to make use of here). The argument baked in here
|
||||
/// should be your app name.
|
||||
/// Shows a standard "About" item
|
||||
About(String),
|
||||
|
||||
/// A standard "hide the app" menu item.
|
||||
@@ -77,18 +76,17 @@ pub enum MenuItem {
|
||||
/// An item for minimizing the window with the standard system controls.
|
||||
Minimize,
|
||||
|
||||
/// An item for instructing the app to zoom. Your app must react to this with necessary window
|
||||
/// lifecycle events.
|
||||
/// An item for instructing the app to zoom
|
||||
Zoom,
|
||||
|
||||
/// Represents a Separator. It's useful nonetheless for
|
||||
/// separating out pieces of the `NSMenu` structure.
|
||||
/// Represents a Separator
|
||||
Separator,
|
||||
}
|
||||
|
||||
impl MenuItem {
|
||||
pub fn new(unique_menu_id: String, title: String) -> Self {
|
||||
MenuItem::Custom(CustomMenu {
|
||||
// todo: would be great if we could pass a type?
|
||||
id: unique_menu_id,
|
||||
key: None,
|
||||
name: title,
|
||||
|
||||
@@ -15,7 +15,7 @@ use objc::runtime::NO;
|
||||
use crate::{
|
||||
dpi::LogicalSize,
|
||||
menu::Menu,
|
||||
platform_impl::platform::{ffi, util::IdRef, window::SharedState},
|
||||
platform_impl::platform::{ffi, menu, util::IdRef, window::SharedState},
|
||||
};
|
||||
|
||||
// Unsafe wrapper type that allows us to dispatch things that aren't Send.
|
||||
@@ -208,7 +208,13 @@ pub unsafe fn set_title_async(ns_window: id, title: String) {
|
||||
|
||||
// `setMenu:` isn't thread-safe.
|
||||
pub unsafe fn set_menu_async(_ns_window: id, menu: Option<Vec<Menu>>) {
|
||||
dbg!(menu);
|
||||
// todo: if None we should set an empty menu maybe?
|
||||
// on windows we can remove it, in macOS we can't
|
||||
if let Some(menu) = menu {
|
||||
Queue::main().exec_async(move || {
|
||||
menu::initialize(menu);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// `close:` is thread-safe, but we want the event to be triggered from the main
|
||||
|
||||
Reference in New Issue
Block a user