diff --git a/imgui-examples/Cargo.toml b/imgui-examples/Cargo.toml index 148d06c..2a71724 100644 --- a/imgui-examples/Cargo.toml +++ b/imgui-examples/Cargo.toml @@ -13,6 +13,6 @@ publish = false clipboard = "0.5" glium = { version = "0.31", default-features = true } image = "0.23" -imgui = { path = "../imgui", features = ["tables-api", "docking"] } +imgui = { path = "../imgui", features = ["tables-api"] } imgui-glium-renderer = { path = "../imgui-glium-renderer" } imgui-winit-support = { path = "../imgui-winit-support", features=["viewports"] } diff --git a/imgui-examples/examples/hello_world.rs b/imgui-examples/examples/hello_world.rs index 42d4ce8..1857ecd 100644 --- a/imgui-examples/examples/hello_world.rs +++ b/imgui-examples/examples/hello_world.rs @@ -3,8 +3,7 @@ use imgui::*; mod support; fn main() { - let mut system = support::init(file!()); - system.imgui.io_mut().config_flags.insert(ConfigFlags::VIEWPORTS_ENABLE); + let system = support::init(file!()); let mut value = 0; let choices = ["test test this is 1", "test test this is 2"]; diff --git a/imgui-examples/examples/support/mod.rs b/imgui-examples/examples/support/mod.rs index 1424dcd..5c5a57e 100644 --- a/imgui-examples/examples/support/mod.rs +++ b/imgui-examples/examples/support/mod.rs @@ -3,9 +3,10 @@ use glium::glutin::event::{Event, WindowEvent}; use glium::glutin::event_loop::{ControlFlow, EventLoop}; use glium::glutin::window::WindowBuilder; use glium::{Display, Surface}; -use imgui::{Context, FontConfig, FontGlyphRanges, FontSource, Ui}; +use imgui::{Context, FontConfig, FontGlyphRanges, FontSource, Ui, ViewportFlags}; use imgui_glium_renderer::Renderer; use imgui_winit_support::{HiDpiMode, WinitPlatform}; +use std::collections::HashMap; use std::path::Path; use std::time::Instant; @@ -112,6 +113,46 @@ pub fn init(title: &str) -> System { } } +struct ViewportStorage<'a, T: 'static> { + event_loop: &'a glium::glutin::event_loop::EventLoopWindowTarget, + viewports: &'a mut HashMap, +} + +impl<'a, T> imgui_winit_support::WinitPlatformViewportStorage for ViewportStorage<'a, T> { + fn create_window(&mut self, id: imgui::Id, flags: imgui::ViewportFlags) { + let builder = WindowBuilder::new() + .with_always_on_top(flags.contains(ViewportFlags::TOP_MOST)) + // .with_decorations(!flags.contains(ViewportFlags::NO_DECORATION)) + .with_resizable(true) + .with_visible(false); + + let window = builder.build(self.event_loop).unwrap(); + self.viewports.insert(id, window); + } + + fn remove_windows(&mut self, filter: impl Fn(imgui::Id) -> bool) { + self.viewports.retain(|id, _| !filter(*id)); + } + + fn get_window( + &mut self, + id: glium::glutin::window::WindowId, + ) -> Option<(imgui::Id, &glium::glutin::window::Window)> { + let res = self + .viewports + .iter() + .find(|(_, wnd)| wnd.id() == id) + .map(|(id, wnd)| (*id, wnd)); + res + } + + fn for_each(&mut self, mut func: impl FnMut(imgui::Id, &glium::glutin::window::Window)) { + for (id, wnd) in self.viewports.iter() { + func(*id, wnd); + } + } +} + impl System { pub fn main_loop(self, mut run_ui: F) { let System { @@ -124,6 +165,8 @@ impl System { } = self; let mut last_frame = Instant::now(); + let mut viewports = HashMap::new(); + event_loop.run(move |event, window_target, control_flow| match event { Event::NewEvents(_) => { let now = Instant::now(); @@ -137,7 +180,11 @@ impl System { .expect("Failed to prepare frame"); gl_window.window().request_redraw(); - platform.update_viewports(&mut imgui, window_target); + let mut storage = ViewportStorage { + event_loop: window_target, + viewports: &mut viewports, + }; + platform.update_viewports(&mut imgui, &mut storage); } Event::RedrawRequested(_) => { let ui = imgui.frame(); @@ -164,11 +211,23 @@ impl System { event: WindowEvent::CloseRequested, window_id, .. - } if window_id == display.gl_window().window().id() => *control_flow = ControlFlow::Exit, + } if window_id == display.gl_window().window().id() => { + *control_flow = ControlFlow::Exit + } event => { let gl_window = display.gl_window(); platform.handle_event(imgui.io_mut(), gl_window.window(), &event); - platform.handle_viewport_event(&mut imgui, gl_window.window(), &event); + + let mut storage = ViewportStorage { + event_loop: window_target, + viewports: &mut viewports, + }; + platform.handle_viewport_event( + &mut imgui, + gl_window.window(), + &mut storage, + &event, + ); } }) } diff --git a/imgui-examples/examples/viewports.rs b/imgui-examples/examples/viewports.rs index 3783460..f328e4d 100644 --- a/imgui-examples/examples/viewports.rs +++ b/imgui-examples/examples/viewports.rs @@ -1,4 +1 @@ - -fn main() { - -} +fn main() {} diff --git a/imgui-glium-renderer/src/lib.rs b/imgui-glium-renderer/src/lib.rs index b1ea68b..eddc659 100644 --- a/imgui-glium-renderer/src/lib.rs +++ b/imgui-glium-renderer/src/lib.rs @@ -150,9 +150,6 @@ impl Renderer { ctx.io_mut() .backend_flags .insert(BackendFlags::RENDERER_HAS_VTX_OFFSET); - ctx.io_mut() - .backend_flags - .insert(BackendFlags::RENDERER_HAS_VIEWPORTS); Ok(Renderer { ctx: Rc::clone(facade.get_context()), program, diff --git a/imgui-winit-support/Cargo.toml b/imgui-winit-support/Cargo.toml index f9ca765..cae6bd3 100644 --- a/imgui-winit-support/Cargo.toml +++ b/imgui-winit-support/Cargo.toml @@ -20,7 +20,7 @@ winit-25 = { version = "0.25", package = "winit", default-features = false, opti winit-26 = { version = "0.26", package = "winit", default-features = false, optional = true } [features] -default = ["winit-26/default", "viewports"] +default = ["winit-26/default"] test = ["winit-23/default", "winit-24/default", "winit-25/default", "winit-26/default"] viewports = [ "imgui/docking" ] diff --git a/imgui-winit-support/src/lib.rs b/imgui-winit-support/src/lib.rs index a7a14b6..3e484e5 100644 --- a/imgui-winit-support/src/lib.rs +++ b/imgui-winit-support/src/lib.rs @@ -189,8 +189,8 @@ use winit_20 as winit; use winit_19 as winit; use imgui::{self, BackendFlags, ConfigFlags, Context, Io, Key, Ui}; +use std::cell::Cell; use std::cmp::Ordering; -use std::{cell::Cell, collections::HashMap}; use winit::dpi::{LogicalPosition, LogicalSize}; #[cfg(all( @@ -452,7 +452,6 @@ impl imgui::PlatformViewportBackend for ViewportBackend { fn create_window(&mut self, viewport: &mut imgui::Viewport) { viewport.platform_user_data = Box::into_raw(Box::new(ViewportState { create: true, - create_flags: viewport.flags, set_show: false, set_pos: None, set_size: None, @@ -538,7 +537,6 @@ impl imgui::PlatformViewportBackend for ViewportBackend { #[cfg(feature = "viewports")] struct ViewportState { create: bool, - create_flags: imgui::ViewportFlags, set_show: bool, set_pos: Option<[f32; 2]>, @@ -648,7 +646,6 @@ impl WinitPlatform { let main_viewport = imgui.main_viewport_mut(); main_viewport.platform_user_data = Box::into_raw(Box::new(ViewportState { create: false, - create_flags: imgui::ViewportFlags::empty(), set_show: false, set_pos: None, set_size: None, @@ -1079,6 +1076,18 @@ impl WinitPlatform { storage: &mut impl WinitPlatformViewportStorage, event: &Event, ) { + if !imgui + .io() + .backend_flags + .contains(BackendFlags::PLATFORM_HAS_VIEWPORTS | BackendFlags::RENDERER_HAS_VIEWPORTS) + || !imgui + .io() + .config_flags + .contains(ConfigFlags::VIEWPORTS_ENABLE) + { + return; + } + if let Event::WindowEvent { window_id, ref event, @@ -1086,16 +1095,14 @@ impl WinitPlatform { { let (viewport, window) = if window_id == main_window.id() { (imgui.main_viewport_mut(), main_window) - } else { - if let Some((viewport_id, window)) = storage.get_window(window_id) { - if let Some(viewport) = imgui.viewport_by_id_mut(viewport_id) { - (viewport, window) - } else { - return; - } + } else if let Some((viewport_id, window)) = storage.get_window(window_id) { + if let Some(viewport) = imgui.viewport_by_id_mut(viewport_id) { + (viewport, window) } else { return; } + } else { + return; }; let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };