2024-08-04 00:18:39 +02:00
|
|
|
#[cfg(any(x11_platform, macos_platform, windows_platform))]
|
2023-10-14 19:07:39 -07:00
|
|
|
#[allow(deprecated)]
|
2023-04-11 12:50:52 +01:00
|
|
|
fn main() -> Result<(), impl std::error::Error> {
|
2022-12-22 08:07:13 +08:00
|
|
|
use std::collections::HashMap;
|
2022-10-10 05:12:23 +09:00
|
|
|
|
2024-05-20 20:27:36 +04:00
|
|
|
use winit::application::ApplicationHandler;
|
2024-01-31 17:29:59 +04:00
|
|
|
use winit::dpi::{LogicalPosition, LogicalSize, Position};
|
2024-05-20 20:27:36 +04:00
|
|
|
use winit::event::{ElementState, KeyEvent, WindowEvent};
|
2024-01-31 17:29:59 +04:00
|
|
|
use winit::event_loop::{ActiveEventLoop, EventLoop};
|
|
|
|
|
use winit::raw_window_handle::HasRawWindowHandle;
|
2024-08-23 23:40:27 +03:00
|
|
|
use winit::window::{Window, WindowAttributes, WindowId};
|
2024-01-31 17:29:59 +04:00
|
|
|
|
|
|
|
|
#[path = "util/fill.rs"]
|
|
|
|
|
mod fill;
|
2022-10-10 05:12:23 +09:00
|
|
|
|
2025-03-03 08:40:04 +01:00
|
|
|
#[derive(Debug)]
|
2025-01-10 12:07:17 -03:00
|
|
|
struct WindowData {
|
|
|
|
|
window: Box<dyn Window>,
|
|
|
|
|
color: u32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl WindowData {
|
|
|
|
|
fn new(window: Box<dyn Window>, color: u32) -> Self {
|
|
|
|
|
Self { window, color }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-03 08:40:04 +01:00
|
|
|
#[derive(Default, Debug)]
|
2024-05-20 20:27:36 +04:00
|
|
|
struct Application {
|
|
|
|
|
parent_window_id: Option<WindowId>,
|
2025-01-10 12:07:17 -03:00
|
|
|
windows: HashMap<WindowId, WindowData>,
|
2022-12-22 08:07:13 +08:00
|
|
|
}
|
2022-10-10 05:12:23 +09:00
|
|
|
|
2024-05-20 20:27:36 +04:00
|
|
|
impl ApplicationHandler for Application {
|
2024-08-06 21:02:53 +03:00
|
|
|
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
2024-08-23 23:40:27 +03:00
|
|
|
let attributes = WindowAttributes::default()
|
2024-05-20 20:27:36 +04:00
|
|
|
.with_title("parent window")
|
|
|
|
|
.with_position(Position::Logical(LogicalPosition::new(0.0, 0.0)))
|
2024-09-04 15:04:48 +02:00
|
|
|
.with_surface_size(LogicalSize::new(640.0f32, 480.0f32));
|
2024-05-20 20:27:36 +04:00
|
|
|
let window = event_loop.create_window(attributes).unwrap();
|
|
|
|
|
println!("Parent window id: {:?})", window.id());
|
|
|
|
|
self.parent_window_id = Some(window.id());
|
2022-10-10 05:12:23 +09:00
|
|
|
|
2025-01-10 12:07:17 -03:00
|
|
|
self.windows.insert(window.id(), WindowData::new(window, 0xffbbbbbb));
|
2024-05-20 20:27:36 +04:00
|
|
|
}
|
2024-01-31 17:29:59 +04:00
|
|
|
|
2024-05-20 20:27:36 +04:00
|
|
|
fn window_event(
|
|
|
|
|
&mut self,
|
2024-08-06 21:02:53 +03:00
|
|
|
event_loop: &dyn ActiveEventLoop,
|
2024-05-20 20:27:36 +04:00
|
|
|
window_id: winit::window::WindowId,
|
|
|
|
|
event: WindowEvent,
|
|
|
|
|
) {
|
|
|
|
|
match event {
|
2022-10-10 05:12:23 +09:00
|
|
|
WindowEvent::CloseRequested => {
|
2024-05-20 20:27:36 +04:00
|
|
|
self.windows.clear();
|
2024-01-31 17:29:59 +04:00
|
|
|
event_loop.exit();
|
2022-10-10 05:12:23 +09:00
|
|
|
},
|
2024-10-08 14:19:00 +02:00
|
|
|
WindowEvent::PointerEntered { device_id: _, .. } => {
|
2022-12-22 08:07:13 +08:00
|
|
|
// On x11, println when the cursor entered in a window even if the child window
|
2022-10-10 05:12:23 +09:00
|
|
|
// is created by some key inputs.
|
|
|
|
|
// the child windows are always placed at (0, 0) with size (200, 200) in the
|
2024-02-19 11:58:44 +07:00
|
|
|
// parent window, so we also can see this log when we move
|
|
|
|
|
// the cursor around (200, 200) in parent window.
|
2023-01-27 07:18:58 +03:00
|
|
|
println!("cursor entered in the window {window_id:?}");
|
2022-10-10 05:12:23 +09:00
|
|
|
},
|
|
|
|
|
WindowEvent::KeyboardInput {
|
|
|
|
|
event: KeyEvent { state: ElementState::Pressed, .. },
|
|
|
|
|
..
|
|
|
|
|
} => {
|
2025-01-10 12:07:17 -03:00
|
|
|
let child_index = self.windows.len() - 1;
|
|
|
|
|
let child_color =
|
|
|
|
|
0xff000000 + 3_u32.pow((child_index + 2).rem_euclid(16) as u32);
|
|
|
|
|
|
2024-05-20 20:27:36 +04:00
|
|
|
let parent_window = self.windows.get(&self.parent_window_id.unwrap()).unwrap();
|
2025-01-10 12:07:17 -03:00
|
|
|
let child_window =
|
|
|
|
|
spawn_child_window(parent_window.window.as_ref(), event_loop, child_index);
|
2024-01-31 17:29:59 +04:00
|
|
|
let child_id = child_window.id();
|
|
|
|
|
println!("Child window created with id: {child_id:?}");
|
2025-01-10 12:07:17 -03:00
|
|
|
self.windows.insert(child_id, WindowData::new(child_window, child_color));
|
2022-10-10 05:12:23 +09:00
|
|
|
},
|
2023-08-27 16:15:09 +02:00
|
|
|
WindowEvent::RedrawRequested => {
|
2024-05-20 20:27:36 +04:00
|
|
|
if let Some(window) = self.windows.get(&window_id) {
|
2025-01-10 12:07:17 -03:00
|
|
|
if window_id == self.parent_window_id.unwrap() {
|
|
|
|
|
fill::fill_window(window.window.as_ref());
|
|
|
|
|
} else {
|
|
|
|
|
fill::fill_window_with_color(window.window.as_ref(), window.color);
|
|
|
|
|
}
|
2023-08-27 16:15:09 +02:00
|
|
|
}
|
|
|
|
|
},
|
2022-10-10 05:12:23 +09:00
|
|
|
_ => (),
|
2024-05-20 20:27:36 +04:00
|
|
|
}
|
2022-10-10 05:12:23 +09:00
|
|
|
}
|
2024-05-20 20:27:36 +04:00
|
|
|
}
|
|
|
|
|
|
2024-08-23 23:40:27 +03:00
|
|
|
fn spawn_child_window(
|
|
|
|
|
parent: &dyn Window,
|
|
|
|
|
event_loop: &dyn ActiveEventLoop,
|
2025-01-10 12:07:17 -03:00
|
|
|
child_count: usize,
|
2024-08-23 23:40:27 +03:00
|
|
|
) -> Box<dyn Window> {
|
2024-05-20 20:27:36 +04:00
|
|
|
let parent = parent.raw_window_handle().unwrap();
|
2025-01-10 12:07:17 -03:00
|
|
|
|
|
|
|
|
// As child count increases, x goes from 0*128 to 5*128 and then repeats
|
|
|
|
|
let x: f64 = child_count.rem_euclid(5) as f64 * 128.0;
|
|
|
|
|
|
|
|
|
|
// After 5 windows have been put side by side horizontally, a new row starts
|
|
|
|
|
let y: f64 = (child_count / 5) as f64 * 96.0;
|
|
|
|
|
|
2024-08-23 23:40:27 +03:00
|
|
|
let mut window_attributes = WindowAttributes::default()
|
2024-05-20 20:27:36 +04:00
|
|
|
.with_title("child window")
|
2025-01-10 12:07:17 -03:00
|
|
|
.with_surface_size(LogicalSize::new(128.0f32, 96.0))
|
|
|
|
|
.with_position(Position::Logical(LogicalPosition::new(x, y)))
|
2024-05-20 20:27:36 +04:00
|
|
|
.with_visible(true);
|
|
|
|
|
// `with_parent_window` is unsafe. Parent window must be a valid window.
|
|
|
|
|
window_attributes = unsafe { window_attributes.with_parent_window(Some(parent)) };
|
|
|
|
|
|
|
|
|
|
event_loop.create_window(window_attributes).unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-24 13:04:55 +03:00
|
|
|
let event_loop = EventLoop::new().unwrap();
|
2024-07-11 15:38:09 +02:00
|
|
|
event_loop.run_app(Application::default())
|
2022-10-10 05:12:23 +09:00
|
|
|
}
|
|
|
|
|
|
2024-08-04 00:18:39 +02:00
|
|
|
#[cfg(not(any(x11_platform, macos_platform, windows_platform)))]
|
2022-10-10 05:12:23 +09:00
|
|
|
fn main() {
|
2023-10-14 19:07:39 -07:00
|
|
|
panic!(
|
|
|
|
|
"This example is supported only on x11, macOS, and Windows, with the `rwh_06` feature \
|
|
|
|
|
enabled."
|
|
|
|
|
);
|
2022-10-10 05:12:23 +09:00
|
|
|
}
|