mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
Removed viewports code from imgui-winit-support
This commit is contained in:
parent
e3bdcffee0
commit
1d88eceb16
@ -14,7 +14,7 @@ glium = { version = "0.32.1", default-features = true }
|
|||||||
image = "0.23"
|
image = "0.23"
|
||||||
imgui = { path = "../imgui", features = ["tables-api"] }
|
imgui = { path = "../imgui", features = ["tables-api"] }
|
||||||
imgui-glium-renderer = { path = "../imgui-glium-renderer" }
|
imgui-glium-renderer = { path = "../imgui-glium-renderer" }
|
||||||
imgui-winit-support = { path = "../imgui-winit-support", features=["viewports"] }
|
imgui-winit-support = { path = "../imgui-winit-support" }
|
||||||
|
|
||||||
# Pin indirect dependency scoped-tls to 1.0.0
|
# Pin indirect dependency scoped-tls to 1.0.0
|
||||||
# as 1.0.1 bumped MSRV to 1.59
|
# as 1.0.1 bumped MSRV to 1.59
|
||||||
|
|||||||
@ -157,11 +157,8 @@ impl System {
|
|||||||
}
|
}
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event: WindowEvent::CloseRequested,
|
event: WindowEvent::CloseRequested,
|
||||||
window_id,
|
|
||||||
..
|
..
|
||||||
} if window_id == display.gl_window().window().id() => {
|
} => *control_flow = ControlFlow::Exit,
|
||||||
*control_flow = ControlFlow::Exit
|
|
||||||
}
|
|
||||||
event => {
|
event => {
|
||||||
let gl_window = display.gl_window();
|
let gl_window = display.gl_window();
|
||||||
platform.handle_event(imgui.io_mut(), gl_window.window(), &event);
|
platform.handle_event(imgui.io_mut(), gl_window.window(), &event);
|
||||||
|
|||||||
@ -12,6 +12,3 @@ categories = ["gui"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
imgui = { version = "0.9.0", path = "../imgui" }
|
imgui = { version = "0.9.0", path = "../imgui" }
|
||||||
winit = { version = "0.27.2", default-features = false }
|
winit = { version = "0.27.2", default-features = false }
|
||||||
|
|
||||||
[features]
|
|
||||||
viewports = [ "imgui/docking" ]
|
|
||||||
|
|||||||
@ -203,124 +203,6 @@ impl HiDpiMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "viewports")]
|
|
||||||
struct ViewportBackend {}
|
|
||||||
|
|
||||||
#[cfg(feature = "viewports")]
|
|
||||||
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,
|
|
||||||
set_show: false,
|
|
||||||
set_pos: None,
|
|
||||||
set_size: None,
|
|
||||||
set_focus: false,
|
|
||||||
set_title: None,
|
|
||||||
pos: [0.0, 0.0],
|
|
||||||
size: [0.0, 0.0],
|
|
||||||
focus: false,
|
|
||||||
minimized: false,
|
|
||||||
})) as *mut _;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy_window(&mut self, viewport: &mut imgui::Viewport) {
|
|
||||||
unsafe {
|
|
||||||
Box::from_raw(viewport.platform_user_data as *mut ViewportState);
|
|
||||||
}
|
|
||||||
viewport.platform_user_data = std::ptr::null_mut();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn show_window(&mut self, viewport: &mut imgui::Viewport) {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.set_show = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_window_pos(&mut self, viewport: &mut imgui::Viewport, pos: [f32; 2]) {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.set_pos = Some(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_window_pos(&mut self, viewport: &mut imgui::Viewport) -> [f32; 2] {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.pos
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_window_size(&mut self, viewport: &mut imgui::Viewport, size: [f32; 2]) {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.set_size = Some(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_window_size(&mut self, viewport: &mut imgui::Viewport) -> [f32; 2] {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.size
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_window_focus(&mut self, viewport: &mut imgui::Viewport) {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.set_focus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_window_focus(&mut self, viewport: &mut imgui::Viewport) -> bool {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.focus
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_window_minimized(&mut self, viewport: &mut imgui::Viewport) -> bool {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.minimized
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_window_title(&mut self, viewport: &mut imgui::Viewport, title: &str) {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
state.set_title = Some(title.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_window_alpha(&mut self, _viewport: &mut imgui::Viewport, _alpha: f32) {}
|
|
||||||
|
|
||||||
fn update_window(&mut self, _viewport: &mut imgui::Viewport) {}
|
|
||||||
|
|
||||||
fn render_window(&mut self, _viewport: &mut imgui::Viewport) {}
|
|
||||||
|
|
||||||
fn swap_buffers(&mut self, _viewport: &mut imgui::Viewport) {}
|
|
||||||
|
|
||||||
fn create_vk_surface(
|
|
||||||
&mut self,
|
|
||||||
_viewport: &mut imgui::Viewport,
|
|
||||||
_instance: u64,
|
|
||||||
_out_surface: &mut u64,
|
|
||||||
) -> i32 {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "viewports")]
|
|
||||||
struct ViewportState {
|
|
||||||
create: bool,
|
|
||||||
|
|
||||||
set_show: bool,
|
|
||||||
set_pos: Option<[f32; 2]>,
|
|
||||||
set_size: Option<[f32; 2]>,
|
|
||||||
set_focus: bool,
|
|
||||||
set_title: Option<String>,
|
|
||||||
|
|
||||||
pos: [f32; 2],
|
|
||||||
size: [f32; 2],
|
|
||||||
focus: bool,
|
|
||||||
minimized: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "viewports")]
|
|
||||||
pub trait WinitPlatformViewportStorage {
|
|
||||||
fn create_window(&mut self, id: imgui::Id, flags: imgui::ViewportFlags);
|
|
||||||
fn remove_windows(&mut self, filter: impl Fn(imgui::Id) -> bool);
|
|
||||||
fn get_window(
|
|
||||||
&mut self,
|
|
||||||
id: winit::window::WindowId,
|
|
||||||
) -> Option<(imgui::Id, &winit::window::Window)>;
|
|
||||||
|
|
||||||
fn for_each(&mut self, func: impl FnMut(imgui::Id, &winit::window::Window));
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WinitPlatform {
|
impl WinitPlatform {
|
||||||
/// Initializes a winit platform instance and configures imgui.
|
/// Initializes a winit platform instance and configures imgui.
|
||||||
///
|
///
|
||||||
@ -366,109 +248,6 @@ impl WinitPlatform {
|
|||||||
mouse_buttons: [Button::INIT; 5],
|
mouse_buttons: [Button::INIT; 5],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "viewports")]
|
|
||||||
pub fn init_viewports<T>(
|
|
||||||
imgui: &mut Context,
|
|
||||||
main_window: &winit::window::Window,
|
|
||||||
event_loop: &winit::event_loop::EventLoop<T>,
|
|
||||||
) {
|
|
||||||
let io = imgui.io_mut();
|
|
||||||
|
|
||||||
io.backend_flags
|
|
||||||
.insert(BackendFlags::PLATFORM_HAS_VIEWPORTS);
|
|
||||||
|
|
||||||
imgui.set_platform_backend(ViewportBackend {});
|
|
||||||
|
|
||||||
let mut monitors = Vec::new();
|
|
||||||
for monitor in event_loop.available_monitors() {
|
|
||||||
monitors.push(imgui::PlatformMonitor {
|
|
||||||
main_pos: [monitor.position().x as f32, monitor.position().y as f32],
|
|
||||||
main_size: [monitor.size().width as f32, monitor.size().height as f32],
|
|
||||||
work_pos: [monitor.position().x as f32, monitor.position().y as f32],
|
|
||||||
work_size: [monitor.size().width as f32, monitor.size().height as f32],
|
|
||||||
dpi_scale: 1.0,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
imgui
|
|
||||||
.platform_io_mut()
|
|
||||||
.monitors
|
|
||||||
.replace_from_slice(&monitors);
|
|
||||||
|
|
||||||
let pos = main_window.inner_position().unwrap();
|
|
||||||
let pos = [pos.x as f32, pos.y as f32];
|
|
||||||
let size = main_window.inner_size();
|
|
||||||
let size = [size.width as f32, size.height as f32];
|
|
||||||
|
|
||||||
let main_viewport = imgui.main_viewport_mut();
|
|
||||||
main_viewport.platform_user_data = Box::into_raw(Box::new(ViewportState {
|
|
||||||
create: false,
|
|
||||||
set_show: false,
|
|
||||||
set_pos: None,
|
|
||||||
set_size: None,
|
|
||||||
set_focus: false,
|
|
||||||
set_title: None,
|
|
||||||
pos,
|
|
||||||
size,
|
|
||||||
focus: true,
|
|
||||||
minimized: false,
|
|
||||||
})) as *mut _;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "viewports")]
|
|
||||||
pub fn update_viewports(
|
|
||||||
&mut self,
|
|
||||||
imgui: &mut Context,
|
|
||||||
storage: &mut impl WinitPlatformViewportStorage,
|
|
||||||
) {
|
|
||||||
// remove destroyed windows
|
|
||||||
storage.remove_windows(|id| !imgui.viewports().any(|vp| vp.id == id));
|
|
||||||
|
|
||||||
// handle new viewports
|
|
||||||
for viewport in imgui.viewports_mut() {
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
|
|
||||||
if state.create {
|
|
||||||
storage.create_window(viewport.id, viewport.flags);
|
|
||||||
state.create = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle other viewport events
|
|
||||||
storage.for_each(|id, wnd| {
|
|
||||||
let viewport = imgui.viewport_by_id_mut(id).unwrap();
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
|
|
||||||
if let Some(pos) = &state.set_pos {
|
|
||||||
let wnd_pos = wnd.outer_position().unwrap();
|
|
||||||
let inner_pos = wnd.inner_position().unwrap();
|
|
||||||
let decoration_size = [inner_pos.x - wnd_pos.x, inner_pos.y - wnd_pos.y];
|
|
||||||
|
|
||||||
wnd.set_outer_position(winit::dpi::LogicalPosition::new(
|
|
||||||
pos[0] - decoration_size[0] as f32,
|
|
||||||
pos[1] - decoration_size[1] as f32,
|
|
||||||
));
|
|
||||||
state.set_pos = None;
|
|
||||||
}
|
|
||||||
if let Some(size) = &state.set_size {
|
|
||||||
wnd.set_inner_size(winit::dpi::LogicalSize::new(size[0], size[1]));
|
|
||||||
state.set_size = None;
|
|
||||||
}
|
|
||||||
if state.set_show {
|
|
||||||
wnd.set_visible(true);
|
|
||||||
state.set_show = false;
|
|
||||||
}
|
|
||||||
if state.set_focus {
|
|
||||||
wnd.focus_window();
|
|
||||||
state.set_focus = false;
|
|
||||||
}
|
|
||||||
if let Some(title) = &state.set_title {
|
|
||||||
wnd.set_title(title);
|
|
||||||
state.set_title = None;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attaches the platform instance to a winit window.
|
/// Attaches the platform instance to a winit window.
|
||||||
///
|
///
|
||||||
/// This function configures imgui-rs in the following ways:
|
/// This function configures imgui-rs in the following ways:
|
||||||
@ -579,152 +358,6 @@ impl WinitPlatform {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "viewports")]
|
|
||||||
pub fn handle_viewport_event<T>(
|
|
||||||
&mut self,
|
|
||||||
imgui: &mut imgui::Context,
|
|
||||||
main_window: &Window,
|
|
||||||
storage: &mut impl WinitPlatformViewportStorage,
|
|
||||||
event: &Event<T>,
|
|
||||||
) {
|
|
||||||
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,
|
|
||||||
} = *event
|
|
||||||
{
|
|
||||||
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 {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let state = unsafe { &mut *(viewport.platform_user_data as *mut ViewportState) };
|
|
||||||
|
|
||||||
match *event {
|
|
||||||
WindowEvent::Resized(new_size) => {
|
|
||||||
state.size = [new_size.width as f32, new_size.height as f32];
|
|
||||||
if new_size.width == 0 || new_size.height == 0 {
|
|
||||||
state.minimized = true;
|
|
||||||
} else {
|
|
||||||
state.minimized = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowEvent::Moved(_new_pos) => {
|
|
||||||
let pos = window.inner_position().unwrap();
|
|
||||||
state.pos = [pos.x as f32, pos.y as f32];
|
|
||||||
}
|
|
||||||
WindowEvent::CloseRequested => {
|
|
||||||
viewport.platform_request_close = true;
|
|
||||||
}
|
|
||||||
WindowEvent::Focused(focus) => {
|
|
||||||
state.focus = focus;
|
|
||||||
}
|
|
||||||
WindowEvent::CursorMoved { position, .. } => {
|
|
||||||
let wnd_pos = window.inner_position().unwrap();
|
|
||||||
let pos = [
|
|
||||||
wnd_pos.x as f32 + position.x as f32,
|
|
||||||
wnd_pos.y as f32 + position.y as f32,
|
|
||||||
];
|
|
||||||
imgui.io_mut().mouse_pos = pos;
|
|
||||||
}
|
|
||||||
WindowEvent::KeyboardInput {
|
|
||||||
input:
|
|
||||||
KeyboardInput {
|
|
||||||
virtual_keycode: Some(key),
|
|
||||||
state,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} if window_id != main_window.id() => {
|
|
||||||
let io = imgui.io_mut();
|
|
||||||
|
|
||||||
let pressed = state == ElementState::Pressed;
|
|
||||||
io.keys_down[key as usize] = pressed;
|
|
||||||
|
|
||||||
// This is a bit redundant here, but we'll leave it in. The OS occasionally
|
|
||||||
// fails to send modifiers keys, but it doesn't seem to send false-positives,
|
|
||||||
// so double checking isn't terrible in case some system *doesn't* send
|
|
||||||
// device events sometimes.
|
|
||||||
match key {
|
|
||||||
VirtualKeyCode::LShift | VirtualKeyCode::RShift => io.key_shift = pressed,
|
|
||||||
VirtualKeyCode::LControl | VirtualKeyCode::RControl => {
|
|
||||||
io.key_ctrl = pressed
|
|
||||||
}
|
|
||||||
VirtualKeyCode::LAlt | VirtualKeyCode::RAlt => io.key_alt = pressed,
|
|
||||||
VirtualKeyCode::LWin | VirtualKeyCode::RWin => io.key_super = pressed,
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowEvent::ReceivedCharacter(ch) if window_id != main_window.id() => {
|
|
||||||
let io = imgui.io_mut();
|
|
||||||
|
|
||||||
// Exclude the backspace key ('\u{7f}'). Otherwise we will insert this char and then
|
|
||||||
// delete it.
|
|
||||||
if ch != '\u{7f}' {
|
|
||||||
io.add_input_character(ch)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowEvent::MouseWheel {
|
|
||||||
delta,
|
|
||||||
phase: TouchPhase::Moved,
|
|
||||||
..
|
|
||||||
} if window_id != main_window.id() => match delta {
|
|
||||||
MouseScrollDelta::LineDelta(h, v) => {
|
|
||||||
let io = imgui.io_mut();
|
|
||||||
io.mouse_wheel_h = h;
|
|
||||||
io.mouse_wheel = v;
|
|
||||||
}
|
|
||||||
MouseScrollDelta::PixelDelta(pos) => {
|
|
||||||
let io = imgui.io_mut();
|
|
||||||
let pos = pos.to_logical::<f64>(self.hidpi_factor);
|
|
||||||
match pos.x.partial_cmp(&0.0) {
|
|
||||||
Some(Ordering::Greater) => io.mouse_wheel_h += 1.0,
|
|
||||||
Some(Ordering::Less) => io.mouse_wheel_h -= 1.0,
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
match pos.y.partial_cmp(&0.0) {
|
|
||||||
Some(Ordering::Greater) => io.mouse_wheel += 1.0,
|
|
||||||
Some(Ordering::Less) => io.mouse_wheel -= 1.0,
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
WindowEvent::MouseInput { state, button, .. } if window_id != main_window.id() => {
|
|
||||||
let pressed = state == ElementState::Pressed;
|
|
||||||
match button {
|
|
||||||
MouseButton::Left => self.mouse_buttons[0].set(pressed),
|
|
||||||
MouseButton::Right => self.mouse_buttons[1].set(pressed),
|
|
||||||
MouseButton::Middle => self.mouse_buttons[2].set(pressed),
|
|
||||||
MouseButton::Other(idx @ 0..=4) => {
|
|
||||||
self.mouse_buttons[idx as usize].set(pressed)
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_window_event(&mut self, io: &mut Io, window: &Window, event: &WindowEvent) {
|
fn handle_window_event(&mut self, io: &mut Io, window: &Window, event: &WindowEvent) {
|
||||||
match *event {
|
match *event {
|
||||||
WindowEvent::Resized(physical_size) => {
|
WindowEvent::Resized(physical_size) => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user