Updated winit, glutin and glium dependencies

This commit is contained in:
Robin Quint 2023-11-18 11:29:23 +01:00 committed by Jonathan Spira
parent 8b2722d00b
commit ca05418cb4
18 changed files with 1201 additions and 924 deletions

View File

@ -13,3 +13,6 @@ members = [
package.rust-version = "1.70"
resolver = "2"
[patch.crates-io]
glium = { git="https://github.com/glium/glium" }

View File

@ -10,7 +10,7 @@ publish = false
[dev-dependencies]
copypasta = "0.8"
glium = { version = "0.32.1", default-features = true }
glium = { version = "0.33.0", default-features = true }
image = "0.23"
imgui = { path = "../imgui", features = ["tables-api"] }
imgui-glium-renderer = { path = "../imgui-glium-renderer" }

View File

@ -1,10 +1,11 @@
use glium::glutin;
use glium::glutin::event::{Event, WindowEvent};
use glium::glutin::event_loop::{ControlFlow, EventLoop};
use glium::glutin::window::WindowBuilder;
use glium::{Display, Surface};
use glium::glutin::surface::WindowSurface;
use glium::Surface;
use imgui::{Context, FontConfig, FontGlyphRanges, FontSource, Ui};
use imgui_glium_renderer::Renderer;
use imgui_winit_support::winit::dpi::LogicalSize;
use imgui_winit_support::winit::event::{Event, WindowEvent};
use imgui_winit_support::winit::event_loop::EventLoop;
use imgui_winit_support::winit::window::{Window, WindowBuilder};
use imgui_winit_support::{HiDpiMode, WinitPlatform};
use std::path::Path;
use std::time::Instant;
@ -13,7 +14,8 @@ mod clipboard;
pub struct System {
pub event_loop: EventLoop<()>,
pub display: glium::Display,
pub window: Window,
pub display: glium::Display<WindowSurface>,
pub imgui: Context,
pub platform: WinitPlatform,
pub renderer: Renderer,
@ -25,13 +27,14 @@ pub fn init(title: &str) -> System {
Some(file_name) => file_name.to_str().unwrap(),
None => title,
};
let event_loop = EventLoop::new();
let context = glutin::ContextBuilder::new().with_vsync(true);
let event_loop = EventLoop::new().expect("Failed to create EventLoop");
let builder = WindowBuilder::new()
.with_title(title.to_owned())
.with_inner_size(glutin::dpi::LogicalSize::new(1024f64, 768f64));
let display =
Display::new(builder, context, &event_loop).expect("Failed to initialize display");
.with_title(title)
.with_inner_size(LogicalSize::new(1024, 768));
let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new()
.set_window_builder(builder)
.build(&event_loop);
let mut imgui = Context::create();
imgui.set_ini_filename(None);
@ -44,9 +47,6 @@ pub fn init(title: &str) -> System {
let mut platform = WinitPlatform::init(&mut imgui);
{
let gl_window = display.gl_window();
let window = gl_window.window();
let dpi_mode = if let Ok(factor) = std::env::var("IMGUI_EXAMPLE_FORCE_DPI_FACTOR") {
// Allow forcing of HiDPI factor for debugging purposes
match factor.parse::<f64>() {
@ -57,7 +57,7 @@ pub fn init(title: &str) -> System {
HiDpiMode::Default
};
platform.attach_window(imgui.io_mut(), window, dpi_mode);
platform.attach_window(imgui.io_mut(), &window, dpi_mode);
}
// Fixed font size. Note imgui_winit_support uses "logical
@ -103,6 +103,7 @@ pub fn init(title: &str) -> System {
System {
event_loop,
window,
display,
imgui,
platform,
@ -115,6 +116,7 @@ impl System {
pub fn main_loop<F: FnMut(&mut bool, &mut Ui) + 'static>(self, mut run_ui: F) {
let System {
event_loop,
window,
display,
mut imgui,
mut platform,
@ -123,46 +125,57 @@ impl System {
} = self;
let mut last_frame = Instant::now();
event_loop.run(move |event, _, control_flow| match event {
event_loop
.run(move |event, window_target| match event {
Event::NewEvents(_) => {
let now = Instant::now();
imgui.io_mut().update_delta_time(now - last_frame);
last_frame = now;
}
Event::MainEventsCleared => {
let gl_window = display.gl_window();
Event::AboutToWait => {
platform
.prepare_frame(imgui.io_mut(), gl_window.window())
.prepare_frame(imgui.io_mut(), &window)
.expect("Failed to prepare frame");
gl_window.window().request_redraw();
window.request_redraw();
}
Event::RedrawRequested(_) => {
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
let ui = imgui.frame();
let mut run = true;
run_ui(&mut run, ui);
if !run {
*control_flow = ControlFlow::Exit;
window_target.exit();
}
let gl_window = display.gl_window();
let mut target = display.draw();
target.clear_color_srgb(1.0, 1.0, 1.0, 1.0);
platform.prepare_render(ui, gl_window.window());
platform.prepare_render(ui, &window);
let draw_data = imgui.render();
renderer
.render(&mut target, draw_data)
.expect("Rendering failed");
target.finish().expect("Failed to swap buffers");
}
Event::WindowEvent {
event: WindowEvent::Resized(new_size),
..
} => {
if new_size.width > 0 && new_size.height > 0 {
display.resize((new_size.width, new_size.height));
}
platform.handle_event(imgui.io_mut(), &window, &event);
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => *control_flow = ControlFlow::Exit,
} => window_target.exit(),
event => {
let gl_window = display.gl_window();
platform.handle_event(imgui.io_mut(), gl_window.window(), &event);
platform.handle_event(imgui.io_mut(), &window, &event);
}
})
.expect("EventLoop error");
}
}

View File

@ -10,8 +10,13 @@ license = "MIT OR Apache-2.0"
categories = ["gui", "rendering"]
[dependencies]
glium = { version = "0.32.1", default-features = false }
glium = { version = "0.33.0", default-features = false }
imgui = { version = "0.11.0", path = "../imgui" }
[dev-dependencies]
glium = { version = "0.33.0", default-features = false, features = ["glutin_backend"] }
imgui-winit-support = {path = "../imgui-winit-support"}
glutin = "0.31.1"
glutin-winit = "0.4.2"
winit = { version = "0.29.3", features = ["rwh_05"] }
raw-window-handle = "0.5.0"

View File

@ -1,6 +1,18 @@
use glium::glutin::event::{Event, WindowEvent};
use glium::glutin::event_loop::{ControlFlow, EventLoop};
use std::num::NonZeroU32;
use glium::Surface;
use glutin::{
config::ConfigTemplateBuilder,
context::{ContextAttributesBuilder, NotCurrentGlContext},
display::{GetGlDisplay, GlDisplay},
surface::{SurfaceAttributesBuilder, WindowSurface},
};
use imgui_winit_support::winit::{dpi::LogicalSize, event_loop::EventLoop, window::WindowBuilder};
use raw_window_handle::HasRawWindowHandle;
use winit::{
event::{Event, WindowEvent},
window::Window,
};
const TITLE: &str = "Hello, imgui-rs!";
@ -8,8 +20,8 @@ fn main() {
// Common setup for creating a winit window and imgui context, not specifc
// to this renderer at all except that glutin is used to create the window
// since it will give us access to a GL context
let (event_loop, display) = create_window();
let (mut winit_platform, mut imgui_context) = imgui_init(&display);
let (event_loop, window, display) = create_window();
let (mut winit_platform, mut imgui_context) = imgui_init(&window);
// Create renderer from this crate
let mut renderer = imgui_glium_renderer::Renderer::init(&mut imgui_context, &display)
@ -19,20 +31,23 @@ fn main() {
let mut last_frame = std::time::Instant::now();
// Standard winit event loop
event_loop.run(move |event, _, control_flow| match event {
event_loop
.run(move |event, window_target| match event {
Event::NewEvents(_) => {
let now = std::time::Instant::now();
imgui_context.io_mut().update_delta_time(now - last_frame);
last_frame = now;
}
Event::MainEventsCleared => {
let gl_window = display.gl_window();
Event::AboutToWait => {
winit_platform
.prepare_frame(imgui_context.io_mut(), gl_window.window())
.prepare_frame(imgui_context.io_mut(), &window)
.expect("Failed to prepare frame");
gl_window.window().request_redraw();
window.request_redraw();
}
Event::RedrawRequested(_) => {
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
// Create frame for the all important `&imgui::Ui`
let ui = imgui_context.frame();
@ -40,14 +55,13 @@ fn main() {
ui.show_demo_window(&mut true);
// Setup for drawing
let gl_window = display.gl_window();
let mut target = display.draw();
// Renderer doesn't automatically clear window
target.clear_color_srgb(1.0, 1.0, 1.0, 1.0);
// Perform rendering
winit_platform.prepare_render(ui, gl_window.window());
winit_platform.prepare_render(ui, &window);
let draw_data = imgui_context.render();
renderer
.render(&mut target, draw_data)
@ -57,35 +71,72 @@ fn main() {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => *control_flow = ControlFlow::Exit,
} => window_target.exit(),
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::Resized(new_size),
..
} => {
if new_size.width > 0 && new_size.height > 0 {
display.resize((new_size.width, new_size.height));
}
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
event => {
let gl_window = display.gl_window();
winit_platform.handle_event(imgui_context.io_mut(), gl_window.window(), &event);
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
});
})
.expect("EventLoop error");
}
fn create_window() -> (EventLoop<()>, glium::Display) {
let event_loop = EventLoop::new();
let context = glium::glutin::ContextBuilder::new().with_vsync(true);
let builder = glium::glutin::window::WindowBuilder::new()
.with_title(TITLE.to_owned())
.with_inner_size(glium::glutin::dpi::LogicalSize::new(1024f64, 768f64));
let display =
glium::Display::new(builder, context, &event_loop).expect("Failed to initialize display");
fn create_window() -> (EventLoop<()>, Window, glium::Display<WindowSurface>) {
let event_loop = EventLoop::new().expect("Failed to create EventLoop");
(event_loop, display)
let window_builder = WindowBuilder::new()
.with_title(TITLE)
.with_inner_size(LogicalSize::new(1024, 768));
let (window, cfg) = glutin_winit::DisplayBuilder::new()
.with_window_builder(Some(window_builder))
.build(&event_loop, ConfigTemplateBuilder::new(), |mut configs| {
configs.next().unwrap()
})
.expect("Failed to create OpenGL window");
let window = window.unwrap();
let context_attribs = ContextAttributesBuilder::new().build(Some(window.raw_window_handle()));
let context = unsafe {
cfg.display()
.create_context(&cfg, &context_attribs)
.expect("Failed to create OpenGL context")
};
let surface_attribs = SurfaceAttributesBuilder::<WindowSurface>::new().build(
window.raw_window_handle(),
NonZeroU32::new(1024).unwrap(),
NonZeroU32::new(768).unwrap(),
);
let surface = unsafe {
cfg.display()
.create_window_surface(&cfg, &surface_attribs)
.expect("Failed to create OpenGL surface")
};
let context = context
.make_current(&surface)
.expect("Failed to make OpenGL context current");
let display = glium::Display::from_context_surface(context, surface)
.expect("Failed to create glium Display");
(event_loop, window, display)
}
fn imgui_init(display: &glium::Display) -> (imgui_winit_support::WinitPlatform, imgui::Context) {
fn imgui_init(window: &Window) -> (imgui_winit_support::WinitPlatform, imgui::Context) {
let mut imgui_context = imgui::Context::create();
imgui_context.set_ini_filename(None);
let mut winit_platform = imgui_winit_support::WinitPlatform::init(&mut imgui_context);
let gl_window = display.gl_window();
let window = gl_window.window();
let dpi_mode = imgui_winit_support::HiDpiMode::Default;
winit_platform.attach_window(imgui_context.io_mut(), window, dpi_mode);

View File

@ -113,7 +113,7 @@ impl glium::vertex::Vertex for GliumDrawVert {
#[inline]
fn build_bindings() -> glium::vertex::VertexFormat {
use std::borrow::Cow::*;
Borrowed(&[
&[
(
Borrowed("pos"),
0,
@ -135,7 +135,7 @@ impl glium::vertex::Vertex for GliumDrawVert {
glium::vertex::AttributeType::U8U8U8U8,
false,
),
])
]
}
}

View File

@ -14,9 +14,12 @@ glow = "0.12.0"
memoffset = "0.9"
[dev-dependencies]
glutin = "0.29.1"
glutin = "0.31.1"
glutin-winit = "0.4.2"
imgui-winit-support = { version = "0.11.0", path = "../imgui-winit-support" }
image = "0.23"
raw-window-handle = "0.5.0"
winit = { version = "0.29.3", features = ["rwh_05"] }
[features]
# Features here are used to opt-out of compiling code that depends on certain

View File

@ -1,25 +1,36 @@
//! A basic self-contained example to get you from zero-to-demo-window as fast
//! as possible.
use std::time::Instant;
use std::{num::NonZeroU32, time::Instant};
use glow::HasContext;
use glutin::{event_loop::EventLoop, WindowedContext};
use imgui_winit_support::WinitPlatform;
use glutin::{
config::ConfigTemplateBuilder,
context::{ContextAttributesBuilder, NotCurrentGlContext, PossiblyCurrentContext},
display::{GetGlDisplay, GlDisplay},
surface::{GlSurface, Surface, SurfaceAttributesBuilder, WindowSurface},
};
use imgui_winit_support::{
winit::{
dpi::LogicalSize,
event_loop::EventLoop,
window::{Window, WindowBuilder},
},
WinitPlatform,
};
use raw_window_handle::HasRawWindowHandle;
const TITLE: &str = "Hello, imgui-rs!";
type Window = WindowedContext<glutin::PossiblyCurrent>;
fn main() {
// Common setup for creating a winit window and imgui context, not specifc
// to this renderer at all except that glutin is used to create the window
// since it will give us access to a GL context
let (event_loop, window) = create_window();
let (event_loop, window, surface, context) = create_window();
let (mut winit_platform, mut imgui_context) = imgui_init(&window);
// OpenGL context from glow
let gl = glow_context(&window);
let gl = glow_context(&context);
// OpenGL renderer from this crate
let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context)
@ -28,29 +39,33 @@ fn main() {
let mut last_frame = Instant::now();
// Standard winit event loop
event_loop.run(move |event, _, control_flow| {
event_loop
.run(move |event, window_target| {
match event {
glutin::event::Event::NewEvents(_) => {
winit::event::Event::NewEvents(_) => {
let now = Instant::now();
imgui_context
.io_mut()
.update_delta_time(now.duration_since(last_frame));
last_frame = now;
}
glutin::event::Event::MainEventsCleared => {
winit::event::Event::AboutToWait => {
winit_platform
.prepare_frame(imgui_context.io_mut(), window.window())
.prepare_frame(imgui_context.io_mut(), &window)
.unwrap();
window.window().request_redraw();
window.request_redraw();
}
glutin::event::Event::RedrawRequested(_) => {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::RedrawRequested,
..
} => {
// The renderer assumes you'll be clearing the buffer yourself
unsafe { ig_renderer.gl_context().clear(glow::COLOR_BUFFER_BIT) };
let ui = imgui_context.frame();
ui.show_demo_window(&mut true);
winit_platform.prepare_render(ui, window.window());
winit_platform.prepare_render(ui, &window);
let draw_data = imgui_context.render();
// This is the only extra render step to add
@ -58,40 +73,88 @@ fn main() {
.render(draw_data)
.expect("error rendering imgui");
window.swap_buffers().unwrap();
surface
.swap_buffers(&context)
.expect("Failed to swap buffers");
}
glutin::event::Event::WindowEvent {
event: glutin::event::WindowEvent::CloseRequested,
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::CloseRequested,
..
} => {
*control_flow = glutin::event_loop::ControlFlow::Exit;
window_target.exit();
}
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::Resized(new_size),
..
} => {
if new_size.width > 0 && new_size.height > 0 {
surface.resize(
&context,
NonZeroU32::new(new_size.width).unwrap(),
NonZeroU32::new(new_size.height).unwrap(),
);
}
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
event => {
winit_platform.handle_event(imgui_context.io_mut(), window.window(), &event);
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
}
});
})
.expect("EventLoop error");
}
fn create_window() -> (EventLoop<()>, Window) {
let event_loop = glutin::event_loop::EventLoop::new();
let window = glutin::window::WindowBuilder::new()
fn create_window() -> (
EventLoop<()>,
Window,
Surface<WindowSurface>,
PossiblyCurrentContext,
) {
let event_loop = EventLoop::new().unwrap();
let window_builder = WindowBuilder::new()
.with_title(TITLE)
.with_inner_size(glutin::dpi::LogicalSize::new(1024, 768));
let window = glutin::ContextBuilder::new()
.with_vsync(true)
.build_windowed(window, &event_loop)
.expect("could not create window");
let window = unsafe {
window
.make_current()
.expect("could not make window context current")
.with_inner_size(LogicalSize::new(1024, 768));
let (window, cfg) = glutin_winit::DisplayBuilder::new()
.with_window_builder(Some(window_builder))
.build(&event_loop, ConfigTemplateBuilder::new(), |mut configs| {
configs.next().unwrap()
})
.expect("Failed to create OpenGL window");
let window = window.unwrap();
let context_attribs = ContextAttributesBuilder::new().build(Some(window.raw_window_handle()));
let context = unsafe {
cfg.display()
.create_context(&cfg, &context_attribs)
.expect("Failed to create OpenGL context")
};
(event_loop, window)
let surface_attribs = SurfaceAttributesBuilder::<WindowSurface>::new()
.with_srgb(Some(true))
.build(
window.raw_window_handle(),
NonZeroU32::new(1024).unwrap(),
NonZeroU32::new(768).unwrap(),
);
let surface = unsafe {
cfg.display()
.create_window_surface(&cfg, &surface_attribs)
.expect("Failed to create OpenGL surface")
};
let context = context
.make_current(&surface)
.expect("Failed to make OpenGL context current");
(event_loop, window, surface, context)
}
fn glow_context(window: &Window) -> glow::Context {
unsafe { glow::Context::from_loader_function(|s| window.get_proc_address(s).cast()) }
fn glow_context(context: &PossiblyCurrentContext) -> glow::Context {
unsafe {
glow::Context::from_loader_function_cstr(|s| context.display().get_proc_address(s).cast())
}
}
fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
@ -101,7 +164,7 @@ fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
let mut winit_platform = WinitPlatform::init(&mut imgui_context);
winit_platform.attach_window(
imgui_context.io_mut(),
window.window(),
window,
imgui_winit_support::HiDpiMode::Rounded,
);

View File

@ -1,38 +1,43 @@
//! A basic example showing imgui rendering on top of a simple custom scene.
use std::time::Instant;
use std::{num::NonZeroU32, time::Instant};
mod utils;
use glutin::surface::GlSurface;
use utils::Triangler;
fn main() {
let (event_loop, window) = utils::create_window("Hello, triangle!", glutin::GlRequest::Latest);
let (event_loop, window, surface, context) = utils::create_window("Hello, triangle!", None);
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
let gl = utils::glow_context(&window);
let gl = utils::glow_context(&context);
let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context)
.expect("failed to create renderer");
let tri_renderer = Triangler::new(ig_renderer.gl_context(), "#version 330");
let mut last_frame = Instant::now();
event_loop.run(move |event, _, control_flow| {
event_loop
.run(move |event, window_target| {
match event {
glutin::event::Event::NewEvents(_) => {
winit::event::Event::NewEvents(_) => {
let now = Instant::now();
imgui_context
.io_mut()
.update_delta_time(now.duration_since(last_frame));
last_frame = now;
}
glutin::event::Event::MainEventsCleared => {
winit::event::Event::AboutToWait => {
winit_platform
.prepare_frame(imgui_context.io_mut(), window.window())
.prepare_frame(imgui_context.io_mut(), &window)
.unwrap();
window.window().request_redraw();
window.request_redraw();
}
glutin::event::Event::RedrawRequested(_) => {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::RedrawRequested,
..
} => {
// Render your custom scene, note we need to borrow the OpenGL
// context from the `AutoRenderer`, which takes ownership of it.
tri_renderer.render(ig_renderer.gl_context());
@ -40,7 +45,7 @@ fn main() {
let ui = imgui_context.frame();
ui.show_demo_window(&mut true);
winit_platform.prepare_render(ui, window.window());
winit_platform.prepare_render(ui, &window);
let draw_data = imgui_context.render();
// Render imgui on top of it
@ -48,21 +53,37 @@ fn main() {
.render(draw_data)
.expect("error rendering imgui");
window.swap_buffers().unwrap();
surface
.swap_buffers(&context)
.expect("Failed to swap buffers");
}
glutin::event::Event::WindowEvent {
event: glutin::event::WindowEvent::CloseRequested,
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::CloseRequested,
..
} => {
*control_flow = glutin::event_loop::ControlFlow::Exit;
window_target.exit();
}
glutin::event::Event::LoopDestroyed => {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::Resized(new_size),
..
} => {
if new_size.width > 0 && new_size.height > 0 {
surface.resize(
&context,
NonZeroU32::new(new_size.width).unwrap(),
NonZeroU32::new(new_size.height).unwrap(),
);
}
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
winit::event::Event::LoopExiting => {
let gl = ig_renderer.gl_context();
tri_renderer.destroy(gl);
}
event => {
winit_platform.handle_event(imgui_context.io_mut(), window.window(), &event);
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
}
});
})
.expect("EventLoop error");
}

View File

@ -4,19 +4,23 @@
//! Note this example uses `Renderer` rather than `AutoRenderer` and
//! therefore requries more lifetime-management of the OpenGL context.
use std::time::Instant;
use std::{num::NonZeroU32, time::Instant};
mod utils;
use glutin::{
context::{ContextApi, Version},
surface::GlSurface,
};
use utils::Triangler;
fn main() {
let (event_loop, window) = utils::create_window(
let (event_loop, window, surface, context) = utils::create_window(
"Hello, triangle! (GLES 3.0)",
glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0)),
Some(ContextApi::Gles(Some(Version::new(3, 0)))),
);
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
let gl = utils::glow_context(&window);
let gl = utils::glow_context(&context);
// When using `Renderer`, we need to create a texture map
let mut texture_map = imgui_glow_renderer::SimpleTextureMap::default();
@ -31,30 +35,34 @@ fn main() {
let tri_renderer = Triangler::new(&gl, "#version 300 es\nprecision mediump float;");
let mut last_frame = Instant::now();
event_loop.run(move |event, _, control_flow| {
event_loop
.run(move |event, window_target| {
match event {
glutin::event::Event::NewEvents(_) => {
winit::event::Event::NewEvents(_) => {
let now = Instant::now();
imgui_context
.io_mut()
.update_delta_time(now.duration_since(last_frame));
last_frame = now;
}
glutin::event::Event::MainEventsCleared => {
winit::event::Event::AboutToWait => {
winit_platform
.prepare_frame(imgui_context.io_mut(), window.window())
.prepare_frame(imgui_context.io_mut(), &window)
.unwrap();
window.window().request_redraw();
window.request_redraw();
}
glutin::event::Event::RedrawRequested(_) => {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::RedrawRequested,
..
} => {
// Draw custom scene
tri_renderer.render(&gl);
let ui = imgui_context.frame();
ui.show_demo_window(&mut true);
winit_platform.prepare_render(ui, window.window());
winit_platform.prepare_render(ui, &window);
let draw_data = imgui_context.render();
// Render imgui on top
@ -62,23 +70,39 @@ fn main() {
.render(&gl, &texture_map, draw_data)
.expect("error rendering imgui");
window.swap_buffers().unwrap();
surface
.swap_buffers(&context)
.expect("Failed to swap buffers");
}
glutin::event::Event::WindowEvent {
event: glutin::event::WindowEvent::CloseRequested,
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::CloseRequested,
..
} => {
*control_flow = glutin::event_loop::ControlFlow::Exit;
window_target.exit();
}
glutin::event::Event::LoopDestroyed => {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::Resized(new_size),
..
} => {
if new_size.width > 0 && new_size.height > 0 {
surface.resize(
&context,
NonZeroU32::new(new_size.width).unwrap(),
NonZeroU32::new(new_size.height).unwrap(),
);
}
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
winit::event::Event::LoopExiting => {
tri_renderer.destroy(&gl);
// Note, to be good citizens we should manually call destroy
// when the renderer does not own the GL context
ig_renderer.destroy(&gl);
}
event => {
winit_platform.handle_event(imgui_context.io_mut(), window.window(), &event);
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
}
});
})
.expect("EventLoop error");
}

View File

@ -5,13 +5,15 @@
//! OpenGL automatically converts colors to linear space before the shaders.
//! The renderer assumes you set this internal format correctly like this.
use std::{io::Cursor, time::Instant};
use std::{io::Cursor, num::NonZeroU32, time::Instant};
use glow::HasContext;
use glutin::surface::GlSurface;
use image::{jpeg::JpegDecoder, ImageDecoder};
use imgui::Condition;
use imgui_glow_renderer::Renderer;
use winit::event_loop::ControlFlow;
#[allow(dead_code)]
mod utils;
@ -19,9 +21,9 @@ mod utils;
const LENNA_JPEG: &[u8] = include_bytes!("../../resources/Lenna.jpg");
fn main() {
let (event_loop, window) = utils::create_window("Custom textures", glutin::GlRequest::Latest);
let (event_loop, window, surface, context) = utils::create_window("Custom textures", None);
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
let gl = utils::glow_context(&window);
let gl = utils::glow_context(&context);
// This time, we tell OpenGL this is an sRGB framebuffer and OpenGL will
// do the conversion to sSGB space for us after the fragment shader.
unsafe { gl.enable(glow::FRAMEBUFFER_SRGB) };
@ -35,55 +37,75 @@ fn main() {
let textures_ui = TexturesUi::new(&gl, &mut textures);
let mut last_frame = Instant::now();
event_loop.run(move |event, _, control_flow| {
event_loop
.run(move |event, window_target| {
// Note we can potentially make the loop more efficient by
// changing the `Poll` (default) value to `ControlFlow::Wait`
// but be careful to test on all target platforms!
*control_flow = glutin::event_loop::ControlFlow::Poll;
window_target.set_control_flow(ControlFlow::Poll);
match event {
glutin::event::Event::NewEvents(_) => {
winit::event::Event::NewEvents(_) => {
let now = Instant::now();
imgui_context
.io_mut()
.update_delta_time(now.duration_since(last_frame));
last_frame = now;
}
glutin::event::Event::MainEventsCleared => {
winit::event::Event::AboutToWait => {
winit_platform
.prepare_frame(imgui_context.io_mut(), window.window())
.prepare_frame(imgui_context.io_mut(), &window)
.unwrap();
window.window().request_redraw();
window.request_redraw();
}
glutin::event::Event::RedrawRequested(_) => {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::RedrawRequested,
..
} => {
unsafe { gl.clear(glow::COLOR_BUFFER_BIT) };
let ui = imgui_context.frame();
textures_ui.show(ui);
winit_platform.prepare_render(ui, window.window());
winit_platform.prepare_render(ui, &window);
let draw_data = imgui_context.render();
ig_renderer
.render(&gl, &textures, draw_data)
.expect("error rendering imgui");
window.swap_buffers().unwrap();
surface
.swap_buffers(&context)
.expect("Failed to swap buffers");
}
glutin::event::Event::WindowEvent {
event: glutin::event::WindowEvent::CloseRequested,
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::Resized(new_size),
..
} => {
*control_flow = glutin::event_loop::ControlFlow::Exit;
if new_size.width > 0 && new_size.height > 0 {
surface.resize(
&context,
NonZeroU32::new(new_size.width).unwrap(),
NonZeroU32::new(new_size.height).unwrap(),
);
}
glutin::event::Event::LoopDestroyed => {
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::CloseRequested,
..
} => {
window_target.exit();
}
winit::event::Event::LoopExiting => {
ig_renderer.destroy(&gl);
}
event => {
winit_platform.handle_event(imgui_context.io_mut(), window.window(), &event);
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
}
});
})
.expect("EventLoop error");
}
struct TexturesUi {

View File

@ -1,10 +1,11 @@
//! A basic example showing imgui rendering on top of a simple custom scene.
use std::{cell::RefCell, rc::Rc, time::Instant};
use std::{cell::RefCell, num::NonZeroU32, rc::Rc, time::Instant};
mod utils;
use glow::HasContext;
use glutin::surface::GlSurface;
use utils::Triangler;
struct UserData {
@ -16,9 +17,9 @@ struct UserData {
const FBO_SIZE: i32 = 128;
fn main() {
let (event_loop, window) = utils::create_window("Hello, FBO!", glutin::GlRequest::Latest);
let (event_loop, window, surface, context) = utils::create_window("Hello, FBO!", None);
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
let gl = utils::glow_context(&window);
let gl = utils::glow_context(&context);
let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context)
.expect("failed to create renderer");
@ -55,23 +56,27 @@ fn main() {
}));
let mut last_frame = Instant::now();
event_loop.run(move |event, _, control_flow| {
event_loop
.run(move |event, window_target| {
match event {
glutin::event::Event::NewEvents(_) => {
winit::event::Event::NewEvents(_) => {
let now = Instant::now();
imgui_context
.io_mut()
.update_delta_time(now.duration_since(last_frame));
last_frame = now;
}
glutin::event::Event::MainEventsCleared => {
winit::event::Event::AboutToWait => {
winit_platform
.prepare_frame(imgui_context.io_mut(), window.window())
.prepare_frame(imgui_context.io_mut(), &window)
.unwrap();
window.window().request_redraw();
window.request_redraw();
}
glutin::event::Event::RedrawRequested(_) => {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::RedrawRequested,
..
} => {
// Render your custom scene, note we need to borrow the OpenGL
// context from the `AutoRenderer`, which takes ownership of it.
unsafe {
@ -82,7 +87,10 @@ fn main() {
ui.show_demo_window(&mut true);
ui.window("FBO").resizable(false).build(|| {
let pos = ui.cursor_screen_pos();
ui.set_cursor_screen_pos([pos[0] + FBO_SIZE as f32, pos[1] + FBO_SIZE as f32]);
ui.set_cursor_screen_pos([
pos[0] + FBO_SIZE as f32,
pos[1] + FBO_SIZE as f32,
]);
let draws = ui.get_window_draw_list();
let scale = ui.io().display_framebuffer_scale;
@ -100,7 +108,12 @@ fn main() {
let dst_y0 = (y - FBO_SIZE as f32 * scale[1]) as i32;
let dst_x1 = (x + FBO_SIZE as f32 * scale[0]) as i32;
let dst_y1 = y as i32;
gl.scissor(dst_x0, dst_y0, dst_x1 - dst_x0, dst_y1 - dst_y0);
gl.scissor(
dst_x0,
dst_y0,
dst_x1 - dst_x0,
dst_y1 - dst_y0,
);
gl.enable(glow::SCISSOR_TEST);
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(data.fbo));
gl.blit_framebuffer(
@ -122,7 +135,7 @@ fn main() {
.build();
});
winit_platform.prepare_render(ui, window.window());
winit_platform.prepare_render(ui, &window);
let draw_data = imgui_context.render();
// Render imgui on top of it
@ -130,21 +143,37 @@ fn main() {
.render(draw_data)
.expect("error rendering imgui");
window.swap_buffers().unwrap();
surface
.swap_buffers(&context)
.expect("Failed to swap buffers");
}
glutin::event::Event::WindowEvent {
event: glutin::event::WindowEvent::CloseRequested,
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::CloseRequested,
..
} => {
*control_flow = glutin::event_loop::ControlFlow::Exit;
window_target.exit();
}
glutin::event::Event::LoopDestroyed => {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::Resized(new_size),
..
} => {
if new_size.width > 0 && new_size.height > 0 {
surface.resize(
&context,
NonZeroU32::new(new_size.width).unwrap(),
NonZeroU32::new(new_size.height).unwrap(),
);
}
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
winit::event::Event::LoopExiting => {
let gl = ig_renderer.gl_context();
tri_renderer.destroy(gl);
}
event => {
winit_platform.handle_event(imgui_context.io_mut(), window.window(), &event);
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
}
}
});
})
.expect("EventLoop error");
}

View File

@ -1,29 +1,82 @@
use std::num::NonZeroU32;
use glow::HasContext;
use glutin::{event_loop::EventLoop, GlRequest};
use imgui_winit_support::WinitPlatform;
pub type Window = glutin::WindowedContext<glutin::PossiblyCurrent>;
pub fn create_window(title: &str, gl_request: GlRequest) -> (EventLoop<()>, Window) {
let event_loop = glutin::event_loop::EventLoop::new();
let window = glutin::window::WindowBuilder::new()
.with_title(title)
.with_inner_size(glutin::dpi::LogicalSize::new(1024, 768));
let window = glutin::ContextBuilder::new()
.with_gl(gl_request)
.with_vsync(true)
.build_windowed(window, &event_loop)
.expect("could not create window");
let window = unsafe {
window
.make_current()
.expect("could not make window context current")
use glutin::{
config::ConfigTemplateBuilder,
context::{ContextApi, ContextAttributesBuilder, NotCurrentGlContext, PossiblyCurrentContext},
display::{GetGlDisplay, GlDisplay},
surface::{GlSurface, Surface, SurfaceAttributesBuilder, SwapInterval, WindowSurface},
};
(event_loop, window)
use imgui_winit_support::WinitPlatform;
use raw_window_handle::HasRawWindowHandle;
use winit::{
dpi::LogicalSize,
event_loop::EventLoop,
window::{Window, WindowBuilder},
};
pub fn create_window(
title: &str,
context_api: Option<ContextApi>,
) -> (
EventLoop<()>,
Window,
Surface<WindowSurface>,
PossiblyCurrentContext,
) {
let event_loop = EventLoop::new().unwrap();
let window_builder = WindowBuilder::new()
.with_title(title)
.with_inner_size(LogicalSize::new(1024, 768));
let (window, cfg) = glutin_winit::DisplayBuilder::new()
.with_window_builder(Some(window_builder))
.build(&event_loop, ConfigTemplateBuilder::new(), |mut configs| {
configs.next().unwrap()
})
.expect("Failed to create OpenGL window");
let window = window.unwrap();
let mut context_attribs = ContextAttributesBuilder::new();
if let Some(context_api) = context_api {
context_attribs = context_attribs.with_context_api(context_api);
}
let context_attribs = context_attribs.build(Some(window.raw_window_handle()));
let context = unsafe {
cfg.display()
.create_context(&cfg, &context_attribs)
.expect("Failed to create OpenGL context")
};
let surface_attribs = SurfaceAttributesBuilder::<WindowSurface>::new()
.with_srgb(Some(true))
.build(
window.raw_window_handle(),
NonZeroU32::new(1024).unwrap(),
NonZeroU32::new(768).unwrap(),
);
let surface = unsafe {
cfg.display()
.create_window_surface(&cfg, &surface_attribs)
.expect("Failed to create OpenGL surface")
};
let context = context
.make_current(&surface)
.expect("Failed to make OpenGL context current");
surface
.set_swap_interval(&context, SwapInterval::Wait(NonZeroU32::new(1).unwrap()))
.expect("Failed to set swap interval");
(event_loop, window, surface, context)
}
pub fn glow_context(window: &Window) -> glow::Context {
unsafe { glow::Context::from_loader_function(|s| window.get_proc_address(s).cast()) }
pub fn glow_context(context: &PossiblyCurrentContext) -> glow::Context {
unsafe {
glow::Context::from_loader_function_cstr(|s| context.display().get_proc_address(s).cast())
}
}
pub fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
@ -33,7 +86,7 @@ pub fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
let mut winit_platform = WinitPlatform::init(&mut imgui_context);
winit_platform.attach_window(
imgui_context.io_mut(),
window.window(),
window,
imgui_winit_support::HiDpiMode::Rounded,
);

View File

@ -13,8 +13,8 @@ license = "MIT OR Apache-2.0"
imgui = { version = "0.11.0", path="../imgui", features=["docking"] }
glow = "0.12.0"
glutin = "0.30.3"
glutin = "0.31.1"
glutin-winit = "0.4.2"
raw-window-handle = "0.5.0"
winit = "0.27.5"
winit = "0.29.3"
thiserror = "1.0.38"
glutin-winit = "0.2.1"

View File

@ -3,21 +3,24 @@ use std::{ffi::CString, num::NonZeroU32, time::Instant};
use glow::{Context, HasContext};
use glutin::{
config::ConfigTemplateBuilder,
context::ContextAttributesBuilder,
context::{ContextAttributesBuilder, NotCurrentGlContext, PossiblyCurrentGlContext},
display::GetGlDisplay,
prelude::{
GlDisplay, NotCurrentGlContextSurfaceAccessor, PossiblyCurrentContextGlSurfaceAccessor,
},
prelude::GlDisplay,
surface::{GlSurface, SurfaceAttributesBuilder, WindowSurface},
};
use glutin_winit::DisplayBuilder;
use imgui::ConfigFlags;
use imgui_winit_glow_renderer_viewports::Renderer;
use raw_window_handle::HasRawWindowHandle;
use winit::{dpi::LogicalSize, event::WindowEvent, event_loop::EventLoop, window::WindowBuilder};
use winit::{
dpi::LogicalSize,
event::WindowEvent,
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
fn main() {
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().expect("Failed to create EventLoop");
let window_builder = WindowBuilder::new()
.with_inner_size(LogicalSize::new(800.0, 600.0))
@ -82,8 +85,9 @@ fn main() {
let mut last_frame = Instant::now();
event_loop.run(move |event, window_target, control_flow| {
control_flow.set_poll();
event_loop
.run(move |event, window_target| {
window_target.set_control_flow(ControlFlow::Poll);
renderer.handle_event(&mut imgui, &window, &event);
@ -97,7 +101,7 @@ fn main() {
window_id,
event: WindowEvent::CloseRequested,
} if window_id == window.id() => {
control_flow.set_exit();
window_target.exit();
}
winit::event::Event::WindowEvent {
window_id,
@ -109,10 +113,13 @@ fn main() {
NonZeroU32::new(new_size.height).unwrap(),
);
}
winit::event::Event::MainEventsCleared => {
winit::event::Event::AboutToWait => {
window.request_redraw();
}
winit::event::Event::RedrawRequested(_) => {
winit::event::Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
let ui = imgui.frame();
ui.dockspace_over_main_viewport();
@ -158,5 +165,6 @@ fn main() {
}
_ => {}
}
});
})
.expect("EventLoop error");
}

View File

@ -10,19 +10,23 @@ use std::{
use glow::HasContext;
use glutin::{
config::ConfigTemplateBuilder,
context::{ContextAttributesBuilder, NotCurrentContext},
context::{
ContextAttributesBuilder, NotCurrentContext, NotCurrentGlContext, PossiblyCurrentGlContext,
},
display::GetGlDisplay,
prelude::{GlDisplay, NotCurrentGlContextSurfaceAccessor, PossiblyCurrentGlContext},
prelude::GlDisplay,
surface::{GlSurface, Surface, SurfaceAttributesBuilder, WindowSurface},
};
use glutin_winit::DisplayBuilder;
use imgui::{BackendFlags, ConfigFlags, Id, Key, MouseButton, ViewportFlags};
use imgui::{BackendFlags, ConfigFlags, Id, Io, Key, MouseButton, ViewportFlags};
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
use thiserror::Error;
use winit::{
dpi::{PhysicalPosition, PhysicalSize},
event::{DeviceEvent, ElementState, KeyboardInput, TouchPhase, VirtualKeyCode},
event::{ElementState, TouchPhase},
event_loop::EventLoopWindowTarget,
keyboard::{Key as WinitKey, KeyLocation, NamedKey},
platform::modifier_supplement::KeyEventExtModifierSupplement,
window::{CursorIcon, Window, WindowBuilder},
};
@ -438,11 +442,11 @@ impl Renderer {
main_window: &Window,
event: &winit::event::Event<T>,
) {
match *event {
winit::event::Event::WindowEvent {
if let winit::event::Event::WindowEvent {
window_id,
ref event,
} => {
} = *event
{
let (window, viewport) = if window_id == main_window.id() {
(main_window, imgui.main_viewport_mut())
} else if let Some((id, wnd)) =
@ -487,22 +491,19 @@ impl Renderer {
winit::event::WindowEvent::CloseRequested if window_id != main_window.id() => {
viewport.platform_request_close = true;
}
winit::event::WindowEvent::ReceivedCharacter(c) => {
imgui.io_mut().add_input_character(c);
}
winit::event::WindowEvent::Focused(f) => unsafe {
(*(viewport.platform_user_data.cast::<ViewportData>())).focus = f;
},
winit::event::WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(key),
state,
..
},
..
} => {
let pressed = state == ElementState::Pressed;
winit::event::WindowEvent::KeyboardInput { ref event, .. } => {
if let Some(txt) = &event.text {
for ch in txt.chars() {
imgui.io_mut().add_input_character(ch);
}
}
let key = event.key_without_modifiers();
let pressed = event.state == ElementState::Pressed;
// We map both left and right ctrl to `ModCtrl`, etc.
// imgui is told both "left control is pressed" and
@ -510,22 +511,26 @@ impl Renderer {
// applications to use either general "ctrl" or a
// specific key. Same applies to other modifiers.
// https://github.com/ocornut/imgui/issues/5047
handle_key_modifier(imgui.io_mut(), key, pressed);
handle_key_modifier(imgui.io_mut(), &key, pressed);
// Add main key event
if let Some(key) = to_imgui_key(key) {
if let Some(key) = to_imgui_key(key, event.location) {
imgui.io_mut().add_key_event(key, pressed);
}
}
winit::event::WindowEvent::ModifiersChanged(modifiers) => {
let state = modifiers.state();
imgui
.io_mut()
.add_key_event(Key::ModShift, modifiers.shift());
imgui.io_mut().add_key_event(Key::ModCtrl, modifiers.ctrl());
imgui.io_mut().add_key_event(Key::ModAlt, modifiers.alt());
.add_key_event(Key::ModShift, state.shift_key());
imgui
.io_mut()
.add_key_event(Key::ModSuper, modifiers.logo());
.add_key_event(Key::ModCtrl, state.control_key());
imgui.io_mut().add_key_event(Key::ModAlt, state.alt_key());
imgui
.io_mut()
.add_key_event(Key::ModSuper, state.super_key());
}
winit::event::WindowEvent::CursorMoved { position, .. } => {
if imgui
@ -533,8 +538,7 @@ impl Renderer {
.config_flags
.contains(ConfigFlags::VIEWPORTS_ENABLE)
{
let window_pos =
window.inner_position().unwrap_or_default().cast::<f32>();
let window_pos = window.inner_position().unwrap_or_default().cast::<f32>();
imgui.io_mut().add_mouse_pos_event([
position.x as f32 + window_pos.x,
position.y as f32 + window_pos.y,
@ -581,21 +585,6 @@ impl Renderer {
_ => {}
}
}
winit::event::Event::DeviceEvent {
event:
DeviceEvent::Key(KeyboardInput {
virtual_keycode: Some(key),
state: ElementState::Released,
..
}),
..
} => {
if let Some(key) = to_imgui_key(key) {
imgui.io_mut().add_key_event(key, false);
}
}
_ => {}
}
}
pub fn update_viewports<T>(
@ -630,7 +619,7 @@ impl Renderer {
}
ViewportEvent::SetSize(id, size) => {
if let Some((_, _, _, wnd)) = self.extra_windows.get(&id) {
wnd.set_inner_size(PhysicalSize::new(size[0], size[1]));
_ = wnd.request_inner_size(PhysicalSize::new(size[0], size[1]));
}
}
ViewportEvent::SetVisible(id) => {
@ -663,7 +652,7 @@ impl Renderer {
imgui::MouseCursor::ResizeEW => winit::window::CursorIcon::EwResize,
imgui::MouseCursor::ResizeNESW => winit::window::CursorIcon::NeswResize,
imgui::MouseCursor::ResizeNWSE => winit::window::CursorIcon::NwseResize,
imgui::MouseCursor::Hand => winit::window::CursorIcon::Hand,
imgui::MouseCursor::Hand => winit::window::CursorIcon::Grab,
imgui::MouseCursor::NotAllowed => winit::window::CursorIcon::NotAllowed,
}
}
@ -911,15 +900,13 @@ struct PlatformBackend {
event_queue: Rc<RefCell<VecDeque<ViewportEvent>>>,
}
fn handle_key_modifier(io: &mut imgui::Io, key: VirtualKeyCode, down: bool) {
if key == VirtualKeyCode::LShift || key == VirtualKeyCode::RShift {
io.add_key_event(imgui::Key::ModShift, down);
} else if key == VirtualKeyCode::LControl || key == VirtualKeyCode::RControl {
io.add_key_event(imgui::Key::ModCtrl, down);
} else if key == VirtualKeyCode::LAlt || key == VirtualKeyCode::RAlt {
io.add_key_event(imgui::Key::ModAlt, down);
} else if key == VirtualKeyCode::LWin || key == VirtualKeyCode::RWin {
io.add_key_event(imgui::Key::ModSuper, down);
fn handle_key_modifier(io: &mut Io, key: &WinitKey, down: bool) {
match key {
WinitKey::Named(NamedKey::Shift) => io.add_key_event(imgui::Key::ModShift, down),
WinitKey::Named(NamedKey::Control) => io.add_key_event(imgui::Key::ModCtrl, down),
WinitKey::Named(NamedKey::Alt) => io.add_key_event(imgui::Key::ModAlt, down),
WinitKey::Named(NamedKey::Super) => io.add_key_event(imgui::Key::ModSuper, down),
_ => {}
}
}
@ -1028,113 +1015,113 @@ impl imgui::RendererViewportBackend for RendererBackend {
fn swap_buffers(&mut self, _viewport: &mut imgui::Viewport) {}
}
fn to_imgui_key(keycode: VirtualKeyCode) -> Option<Key> {
match keycode {
VirtualKeyCode::Tab => Some(Key::Tab),
VirtualKeyCode::Left => Some(Key::LeftArrow),
VirtualKeyCode::Right => Some(Key::RightArrow),
VirtualKeyCode::Up => Some(Key::UpArrow),
VirtualKeyCode::Down => Some(Key::DownArrow),
VirtualKeyCode::PageUp => Some(Key::PageUp),
VirtualKeyCode::PageDown => Some(Key::PageDown),
VirtualKeyCode::Home => Some(Key::Home),
VirtualKeyCode::End => Some(Key::End),
VirtualKeyCode::Insert => Some(Key::Insert),
VirtualKeyCode::Delete => Some(Key::Delete),
VirtualKeyCode::Back => Some(Key::Backspace),
VirtualKeyCode::Space => Some(Key::Space),
VirtualKeyCode::Return => Some(Key::Enter),
VirtualKeyCode::Escape => Some(Key::Escape),
VirtualKeyCode::LControl => Some(Key::LeftCtrl),
VirtualKeyCode::LShift => Some(Key::LeftShift),
VirtualKeyCode::LAlt => Some(Key::LeftAlt),
VirtualKeyCode::LWin => Some(Key::LeftSuper),
VirtualKeyCode::RControl => Some(Key::RightCtrl),
VirtualKeyCode::RShift => Some(Key::RightShift),
VirtualKeyCode::RAlt => Some(Key::RightAlt),
VirtualKeyCode::RWin => Some(Key::RightSuper),
//VirtualKeyCode::Menu => Some(Key::Menu), // TODO: find out if there is a Menu key in winit
VirtualKeyCode::Key0 => Some(Key::Alpha0),
VirtualKeyCode::Key1 => Some(Key::Alpha1),
VirtualKeyCode::Key2 => Some(Key::Alpha2),
VirtualKeyCode::Key3 => Some(Key::Alpha3),
VirtualKeyCode::Key4 => Some(Key::Alpha4),
VirtualKeyCode::Key5 => Some(Key::Alpha5),
VirtualKeyCode::Key6 => Some(Key::Alpha6),
VirtualKeyCode::Key7 => Some(Key::Alpha7),
VirtualKeyCode::Key8 => Some(Key::Alpha8),
VirtualKeyCode::Key9 => Some(Key::Alpha9),
VirtualKeyCode::A => Some(Key::A),
VirtualKeyCode::B => Some(Key::B),
VirtualKeyCode::C => Some(Key::C),
VirtualKeyCode::D => Some(Key::D),
VirtualKeyCode::E => Some(Key::E),
VirtualKeyCode::F => Some(Key::F),
VirtualKeyCode::G => Some(Key::G),
VirtualKeyCode::H => Some(Key::H),
VirtualKeyCode::I => Some(Key::I),
VirtualKeyCode::J => Some(Key::J),
VirtualKeyCode::K => Some(Key::K),
VirtualKeyCode::L => Some(Key::L),
VirtualKeyCode::M => Some(Key::M),
VirtualKeyCode::N => Some(Key::N),
VirtualKeyCode::O => Some(Key::O),
VirtualKeyCode::P => Some(Key::P),
VirtualKeyCode::Q => Some(Key::Q),
VirtualKeyCode::R => Some(Key::R),
VirtualKeyCode::S => Some(Key::S),
VirtualKeyCode::T => Some(Key::T),
VirtualKeyCode::U => Some(Key::U),
VirtualKeyCode::V => Some(Key::V),
VirtualKeyCode::W => Some(Key::W),
VirtualKeyCode::X => Some(Key::X),
VirtualKeyCode::Y => Some(Key::Y),
VirtualKeyCode::Z => Some(Key::Z),
VirtualKeyCode::F1 => Some(Key::F1),
VirtualKeyCode::F2 => Some(Key::F2),
VirtualKeyCode::F3 => Some(Key::F3),
VirtualKeyCode::F4 => Some(Key::F4),
VirtualKeyCode::F5 => Some(Key::F5),
VirtualKeyCode::F6 => Some(Key::F6),
VirtualKeyCode::F7 => Some(Key::F7),
VirtualKeyCode::F8 => Some(Key::F8),
VirtualKeyCode::F9 => Some(Key::F9),
VirtualKeyCode::F10 => Some(Key::F10),
VirtualKeyCode::F11 => Some(Key::F11),
VirtualKeyCode::F12 => Some(Key::F12),
VirtualKeyCode::Apostrophe => Some(Key::Apostrophe),
VirtualKeyCode::Comma => Some(Key::Comma),
VirtualKeyCode::Minus => Some(Key::Minus),
VirtualKeyCode::Period => Some(Key::Period),
VirtualKeyCode::Slash => Some(Key::Slash),
VirtualKeyCode::Semicolon => Some(Key::Semicolon),
VirtualKeyCode::Equals => Some(Key::Equal),
VirtualKeyCode::LBracket => Some(Key::LeftBracket),
VirtualKeyCode::Backslash => Some(Key::Backslash),
VirtualKeyCode::RBracket => Some(Key::RightBracket),
VirtualKeyCode::Grave => Some(Key::GraveAccent),
VirtualKeyCode::Capital => Some(Key::CapsLock),
VirtualKeyCode::Scroll => Some(Key::ScrollLock),
VirtualKeyCode::Numlock => Some(Key::NumLock),
VirtualKeyCode::Snapshot => Some(Key::PrintScreen),
VirtualKeyCode::Pause => Some(Key::Pause),
VirtualKeyCode::Numpad0 => Some(Key::Keypad0),
VirtualKeyCode::Numpad1 => Some(Key::Keypad1),
VirtualKeyCode::Numpad2 => Some(Key::Keypad2),
VirtualKeyCode::Numpad3 => Some(Key::Keypad3),
VirtualKeyCode::Numpad4 => Some(Key::Keypad4),
VirtualKeyCode::Numpad5 => Some(Key::Keypad5),
VirtualKeyCode::Numpad6 => Some(Key::Keypad6),
VirtualKeyCode::Numpad7 => Some(Key::Keypad7),
VirtualKeyCode::Numpad8 => Some(Key::Keypad8),
VirtualKeyCode::Numpad9 => Some(Key::Keypad9),
VirtualKeyCode::NumpadDecimal => Some(Key::KeypadDecimal),
VirtualKeyCode::NumpadDivide => Some(Key::KeypadDivide),
VirtualKeyCode::NumpadMultiply => Some(Key::KeypadMultiply),
VirtualKeyCode::NumpadSubtract => Some(Key::KeypadSubtract),
VirtualKeyCode::NumpadAdd => Some(Key::KeypadAdd),
VirtualKeyCode::NumpadEnter => Some(Key::KeypadEnter),
VirtualKeyCode::NumpadEquals => Some(Key::KeypadEqual),
fn to_imgui_key(key: winit::keyboard::Key, location: KeyLocation) -> Option<Key> {
match (key.as_ref(), location) {
(WinitKey::Named(NamedKey::Tab), _) => Some(Key::Tab),
(WinitKey::Named(NamedKey::ArrowLeft), _) => Some(Key::LeftArrow),
(WinitKey::Named(NamedKey::ArrowRight), _) => Some(Key::RightArrow),
(WinitKey::Named(NamedKey::ArrowUp), _) => Some(Key::UpArrow),
(WinitKey::Named(NamedKey::ArrowDown), _) => Some(Key::DownArrow),
(WinitKey::Named(NamedKey::PageUp), _) => Some(Key::PageUp),
(WinitKey::Named(NamedKey::PageDown), _) => Some(Key::PageDown),
(WinitKey::Named(NamedKey::Home), _) => Some(Key::Home),
(WinitKey::Named(NamedKey::End), _) => Some(Key::End),
(WinitKey::Named(NamedKey::Insert), _) => Some(Key::Insert),
(WinitKey::Named(NamedKey::Delete), _) => Some(Key::Delete),
(WinitKey::Named(NamedKey::Backspace), _) => Some(Key::Backspace),
(WinitKey::Named(NamedKey::Space), _) => Some(Key::Space),
(WinitKey::Named(NamedKey::Enter), KeyLocation::Standard) => Some(Key::Enter),
(WinitKey::Named(NamedKey::Enter), KeyLocation::Numpad) => Some(Key::KeypadEnter),
(WinitKey::Named(NamedKey::Escape), _) => Some(Key::Escape),
(WinitKey::Named(NamedKey::Control), KeyLocation::Left) => Some(Key::LeftCtrl),
(WinitKey::Named(NamedKey::Control), KeyLocation::Right) => Some(Key::RightCtrl),
(WinitKey::Named(NamedKey::Shift), KeyLocation::Left) => Some(Key::LeftShift),
(WinitKey::Named(NamedKey::Shift), KeyLocation::Right) => Some(Key::RightShift),
(WinitKey::Named(NamedKey::Alt), KeyLocation::Left) => Some(Key::LeftAlt),
(WinitKey::Named(NamedKey::Alt), KeyLocation::Right) => Some(Key::RightAlt),
(WinitKey::Named(NamedKey::Super), KeyLocation::Left) => Some(Key::LeftSuper),
(WinitKey::Named(NamedKey::Super), KeyLocation::Right) => Some(Key::RightSuper),
(WinitKey::Named(NamedKey::ContextMenu), _) => Some(Key::Menu),
(WinitKey::Named(NamedKey::F1), _) => Some(Key::F1),
(WinitKey::Named(NamedKey::F2), _) => Some(Key::F2),
(WinitKey::Named(NamedKey::F3), _) => Some(Key::F3),
(WinitKey::Named(NamedKey::F4), _) => Some(Key::F4),
(WinitKey::Named(NamedKey::F5), _) => Some(Key::F5),
(WinitKey::Named(NamedKey::F6), _) => Some(Key::F6),
(WinitKey::Named(NamedKey::F7), _) => Some(Key::F7),
(WinitKey::Named(NamedKey::F8), _) => Some(Key::F8),
(WinitKey::Named(NamedKey::F9), _) => Some(Key::F9),
(WinitKey::Named(NamedKey::F10), _) => Some(Key::F10),
(WinitKey::Named(NamedKey::F11), _) => Some(Key::F11),
(WinitKey::Named(NamedKey::F12), _) => Some(Key::F12),
(WinitKey::Named(NamedKey::CapsLock), _) => Some(Key::CapsLock),
(WinitKey::Named(NamedKey::ScrollLock), _) => Some(Key::ScrollLock),
(WinitKey::Named(NamedKey::NumLock), _) => Some(Key::NumLock),
(WinitKey::Named(NamedKey::PrintScreen), _) => Some(Key::PrintScreen),
(WinitKey::Named(NamedKey::Pause), _) => Some(Key::Pause),
(WinitKey::Character("0"), KeyLocation::Standard) => Some(Key::Alpha0),
(WinitKey::Character("1"), KeyLocation::Standard) => Some(Key::Alpha1),
(WinitKey::Character("2"), KeyLocation::Standard) => Some(Key::Alpha2),
(WinitKey::Character("3"), KeyLocation::Standard) => Some(Key::Alpha3),
(WinitKey::Character("4"), KeyLocation::Standard) => Some(Key::Alpha4),
(WinitKey::Character("5"), KeyLocation::Standard) => Some(Key::Alpha5),
(WinitKey::Character("6"), KeyLocation::Standard) => Some(Key::Alpha6),
(WinitKey::Character("7"), KeyLocation::Standard) => Some(Key::Alpha7),
(WinitKey::Character("8"), KeyLocation::Standard) => Some(Key::Alpha8),
(WinitKey::Character("9"), KeyLocation::Standard) => Some(Key::Alpha9),
(WinitKey::Character("0"), KeyLocation::Numpad) => Some(Key::Keypad0),
(WinitKey::Character("1"), KeyLocation::Numpad) => Some(Key::Keypad1),
(WinitKey::Character("2"), KeyLocation::Numpad) => Some(Key::Keypad2),
(WinitKey::Character("3"), KeyLocation::Numpad) => Some(Key::Keypad3),
(WinitKey::Character("4"), KeyLocation::Numpad) => Some(Key::Keypad4),
(WinitKey::Character("5"), KeyLocation::Numpad) => Some(Key::Keypad5),
(WinitKey::Character("6"), KeyLocation::Numpad) => Some(Key::Keypad6),
(WinitKey::Character("7"), KeyLocation::Numpad) => Some(Key::Keypad7),
(WinitKey::Character("8"), KeyLocation::Numpad) => Some(Key::Keypad8),
(WinitKey::Character("9"), KeyLocation::Numpad) => Some(Key::Keypad9),
(WinitKey::Character("a"), _) => Some(Key::A),
(WinitKey::Character("b"), _) => Some(Key::B),
(WinitKey::Character("c"), _) => Some(Key::C),
(WinitKey::Character("d"), _) => Some(Key::D),
(WinitKey::Character("e"), _) => Some(Key::E),
(WinitKey::Character("f"), _) => Some(Key::F),
(WinitKey::Character("g"), _) => Some(Key::G),
(WinitKey::Character("h"), _) => Some(Key::H),
(WinitKey::Character("i"), _) => Some(Key::I),
(WinitKey::Character("j"), _) => Some(Key::J),
(WinitKey::Character("k"), _) => Some(Key::K),
(WinitKey::Character("l"), _) => Some(Key::L),
(WinitKey::Character("m"), _) => Some(Key::M),
(WinitKey::Character("n"), _) => Some(Key::N),
(WinitKey::Character("o"), _) => Some(Key::O),
(WinitKey::Character("p"), _) => Some(Key::P),
(WinitKey::Character("q"), _) => Some(Key::Q),
(WinitKey::Character("r"), _) => Some(Key::R),
(WinitKey::Character("s"), _) => Some(Key::S),
(WinitKey::Character("t"), _) => Some(Key::T),
(WinitKey::Character("u"), _) => Some(Key::U),
(WinitKey::Character("v"), _) => Some(Key::V),
(WinitKey::Character("w"), _) => Some(Key::W),
(WinitKey::Character("x"), _) => Some(Key::X),
(WinitKey::Character("y"), _) => Some(Key::Y),
(WinitKey::Character("z"), _) => Some(Key::Z),
(WinitKey::Character("'"), _) => Some(Key::Apostrophe),
(WinitKey::Character(","), KeyLocation::Standard) => Some(Key::Comma),
(WinitKey::Character("-"), KeyLocation::Standard) => Some(Key::Minus),
(WinitKey::Character("-"), KeyLocation::Numpad) => Some(Key::KeypadSubtract),
(WinitKey::Character("."), KeyLocation::Standard) => Some(Key::Period),
(WinitKey::Character("."), KeyLocation::Numpad) => Some(Key::KeypadDecimal),
(WinitKey::Character("/"), KeyLocation::Standard) => Some(Key::Slash),
(WinitKey::Character("/"), KeyLocation::Numpad) => Some(Key::KeypadDivide),
(WinitKey::Character(";"), _) => Some(Key::Semicolon),
(WinitKey::Character("="), KeyLocation::Standard) => Some(Key::Equal),
(WinitKey::Character("="), KeyLocation::Numpad) => Some(Key::KeypadEqual),
(WinitKey::Character("["), _) => Some(Key::LeftBracket),
(WinitKey::Character("\\"), _) => Some(Key::Backslash),
(WinitKey::Character("]"), _) => Some(Key::RightBracket),
(WinitKey::Character("`"), _) => Some(Key::GraveAccent),
(WinitKey::Character("*"), KeyLocation::Numpad) => Some(Key::KeypadMultiply),
(WinitKey::Character("+"), KeyLocation::Numpad) => Some(Key::KeypadAdd),
_ => None,
}
}

View File

@ -11,4 +11,4 @@ categories = ["gui"]
[dependencies]
imgui = { version = "0.11.0", path = "../imgui" }
winit = { version = "0.27.2", default-features = false }
winit = { version = "0.29.3", default-features = false }

View File

@ -23,7 +23,7 @@
//! use winit::event_loop::{ControlFlow, EventLoop};
//! use winit::window::Window;
//!
//! let mut event_loop = EventLoop::new();
//! let mut event_loop = EventLoop::new().expect("Failed to create EventLoop");
//! let mut window = Window::new(&event_loop).unwrap();
//!
//! let mut imgui = Context::create();
@ -34,7 +34,7 @@
//!
//! let mut last_frame = Instant::now();
//! let mut run = true;
//! event_loop.run(move |event, _, control_flow| {
//! event_loop.run(move |event, window_target| {
//! match event {
//! Event::NewEvents(_) => {
//! // other application-specific logic
@ -42,13 +42,13 @@
//! imgui.io_mut().update_delta_time(now - last_frame);
//! last_frame = now;
//! },
//! Event::MainEventsCleared => {
//! Event::AboutToWait => {
//! // other application-specific logic
//! platform.prepare_frame(imgui.io_mut(), &window) // step 4
//! .expect("Failed to prepare frame");
//! window.request_redraw();
//! }
//! Event::RedrawRequested(_) => {
//! Event::WindowEvent { event: WindowEvent::RedrawRequested, .. } => {
//! let ui = imgui.frame();
//! // application-specific rendering *under the UI*
//!
@ -62,7 +62,7 @@
//! // application-specific rendering *over the UI*
//! },
//! Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
//! *control_flow = ControlFlow::Exit;
//! window_target.exit();
//! }
//! // other application-specific event handling
//! event => {
@ -70,7 +70,7 @@
//! // other application-specific event handling
//! }
//! }
//! })
//! }).expect("EventLoop error");
//! ```
use imgui::{self, BackendFlags, ConfigFlags, Context, Io, Key, Ui};
@ -78,14 +78,15 @@ use std::cmp::Ordering;
// Re-export winit to make it easier for users to use the correct version.
pub use winit;
use winit::dpi::{LogicalPosition, LogicalSize};
use winit::{
dpi::{LogicalPosition, LogicalSize},
keyboard::{Key as WinitKey, KeyLocation, NamedKey},
platform::modifier_supplement::KeyEventExtModifierSupplement,
};
use winit::{
error::ExternalError,
event::{
DeviceEvent, ElementState, Event, KeyboardInput, MouseButton, MouseScrollDelta, TouchPhase,
VirtualKeyCode, WindowEvent,
},
event::{ElementState, Event, MouseButton, MouseScrollDelta, TouchPhase, WindowEvent},
window::{CursorIcon as MouseCursor, Window},
};
@ -112,7 +113,7 @@ fn to_winit_cursor(cursor: imgui::MouseCursor) -> MouseCursor {
imgui::MouseCursor::ResizeEW => MouseCursor::EwResize,
imgui::MouseCursor::ResizeNESW => MouseCursor::NeswResize,
imgui::MouseCursor::ResizeNWSE => MouseCursor::NwseResize,
imgui::MouseCursor::Hand => MouseCursor::Hand,
imgui::MouseCursor::Hand => MouseCursor::Grab,
imgui::MouseCursor::NotAllowed => MouseCursor::NotAllowed,
}
}
@ -180,126 +181,124 @@ fn to_imgui_mouse_button(button: MouseButton) -> Option<imgui::MouseButton> {
}
}
fn to_imgui_key(keycode: VirtualKeyCode) -> Option<Key> {
match keycode {
VirtualKeyCode::Tab => Some(Key::Tab),
VirtualKeyCode::Left => Some(Key::LeftArrow),
VirtualKeyCode::Right => Some(Key::RightArrow),
VirtualKeyCode::Up => Some(Key::UpArrow),
VirtualKeyCode::Down => Some(Key::DownArrow),
VirtualKeyCode::PageUp => Some(Key::PageUp),
VirtualKeyCode::PageDown => Some(Key::PageDown),
VirtualKeyCode::Home => Some(Key::Home),
VirtualKeyCode::End => Some(Key::End),
VirtualKeyCode::Insert => Some(Key::Insert),
VirtualKeyCode::Delete => Some(Key::Delete),
VirtualKeyCode::Back => Some(Key::Backspace),
VirtualKeyCode::Space => Some(Key::Space),
VirtualKeyCode::Return => Some(Key::Enter),
VirtualKeyCode::Escape => Some(Key::Escape),
VirtualKeyCode::LControl => Some(Key::LeftCtrl),
VirtualKeyCode::LShift => Some(Key::LeftShift),
VirtualKeyCode::LAlt => Some(Key::LeftAlt),
VirtualKeyCode::LWin => Some(Key::LeftSuper),
VirtualKeyCode::RControl => Some(Key::RightCtrl),
VirtualKeyCode::RShift => Some(Key::RightShift),
VirtualKeyCode::RAlt => Some(Key::RightAlt),
VirtualKeyCode::RWin => Some(Key::RightSuper),
//VirtualKeyCode::Menu => Some(Key::Menu), // TODO: find out if there is a Menu key in winit
VirtualKeyCode::Key0 => Some(Key::Alpha0),
VirtualKeyCode::Key1 => Some(Key::Alpha1),
VirtualKeyCode::Key2 => Some(Key::Alpha2),
VirtualKeyCode::Key3 => Some(Key::Alpha3),
VirtualKeyCode::Key4 => Some(Key::Alpha4),
VirtualKeyCode::Key5 => Some(Key::Alpha5),
VirtualKeyCode::Key6 => Some(Key::Alpha6),
VirtualKeyCode::Key7 => Some(Key::Alpha7),
VirtualKeyCode::Key8 => Some(Key::Alpha8),
VirtualKeyCode::Key9 => Some(Key::Alpha9),
VirtualKeyCode::A => Some(Key::A),
VirtualKeyCode::B => Some(Key::B),
VirtualKeyCode::C => Some(Key::C),
VirtualKeyCode::D => Some(Key::D),
VirtualKeyCode::E => Some(Key::E),
VirtualKeyCode::F => Some(Key::F),
VirtualKeyCode::G => Some(Key::G),
VirtualKeyCode::H => Some(Key::H),
VirtualKeyCode::I => Some(Key::I),
VirtualKeyCode::J => Some(Key::J),
VirtualKeyCode::K => Some(Key::K),
VirtualKeyCode::L => Some(Key::L),
VirtualKeyCode::M => Some(Key::M),
VirtualKeyCode::N => Some(Key::N),
VirtualKeyCode::O => Some(Key::O),
VirtualKeyCode::P => Some(Key::P),
VirtualKeyCode::Q => Some(Key::Q),
VirtualKeyCode::R => Some(Key::R),
VirtualKeyCode::S => Some(Key::S),
VirtualKeyCode::T => Some(Key::T),
VirtualKeyCode::U => Some(Key::U),
VirtualKeyCode::V => Some(Key::V),
VirtualKeyCode::W => Some(Key::W),
VirtualKeyCode::X => Some(Key::X),
VirtualKeyCode::Y => Some(Key::Y),
VirtualKeyCode::Z => Some(Key::Z),
VirtualKeyCode::F1 => Some(Key::F1),
VirtualKeyCode::F2 => Some(Key::F2),
VirtualKeyCode::F3 => Some(Key::F3),
VirtualKeyCode::F4 => Some(Key::F4),
VirtualKeyCode::F5 => Some(Key::F5),
VirtualKeyCode::F6 => Some(Key::F6),
VirtualKeyCode::F7 => Some(Key::F7),
VirtualKeyCode::F8 => Some(Key::F8),
VirtualKeyCode::F9 => Some(Key::F9),
VirtualKeyCode::F10 => Some(Key::F10),
VirtualKeyCode::F11 => Some(Key::F11),
VirtualKeyCode::F12 => Some(Key::F12),
VirtualKeyCode::Apostrophe => Some(Key::Apostrophe),
VirtualKeyCode::Comma => Some(Key::Comma),
VirtualKeyCode::Minus => Some(Key::Minus),
VirtualKeyCode::Period => Some(Key::Period),
VirtualKeyCode::Slash => Some(Key::Slash),
VirtualKeyCode::Semicolon => Some(Key::Semicolon),
VirtualKeyCode::Equals => Some(Key::Equal),
VirtualKeyCode::LBracket => Some(Key::LeftBracket),
VirtualKeyCode::Backslash => Some(Key::Backslash),
VirtualKeyCode::RBracket => Some(Key::RightBracket),
VirtualKeyCode::Grave => Some(Key::GraveAccent),
VirtualKeyCode::Capital => Some(Key::CapsLock),
VirtualKeyCode::Scroll => Some(Key::ScrollLock),
VirtualKeyCode::Numlock => Some(Key::NumLock),
VirtualKeyCode::Snapshot => Some(Key::PrintScreen),
VirtualKeyCode::Pause => Some(Key::Pause),
VirtualKeyCode::Numpad0 => Some(Key::Keypad0),
VirtualKeyCode::Numpad1 => Some(Key::Keypad1),
VirtualKeyCode::Numpad2 => Some(Key::Keypad2),
VirtualKeyCode::Numpad3 => Some(Key::Keypad3),
VirtualKeyCode::Numpad4 => Some(Key::Keypad4),
VirtualKeyCode::Numpad5 => Some(Key::Keypad5),
VirtualKeyCode::Numpad6 => Some(Key::Keypad6),
VirtualKeyCode::Numpad7 => Some(Key::Keypad7),
VirtualKeyCode::Numpad8 => Some(Key::Keypad8),
VirtualKeyCode::Numpad9 => Some(Key::Keypad9),
VirtualKeyCode::NumpadDecimal => Some(Key::KeypadDecimal),
VirtualKeyCode::NumpadDivide => Some(Key::KeypadDivide),
VirtualKeyCode::NumpadMultiply => Some(Key::KeypadMultiply),
VirtualKeyCode::NumpadSubtract => Some(Key::KeypadSubtract),
VirtualKeyCode::NumpadAdd => Some(Key::KeypadAdd),
VirtualKeyCode::NumpadEnter => Some(Key::KeypadEnter),
VirtualKeyCode::NumpadEquals => Some(Key::KeypadEqual),
fn to_imgui_key(key: winit::keyboard::Key, location: KeyLocation) -> Option<Key> {
match (key.as_ref(), location) {
(WinitKey::Named(NamedKey::Tab), _) => Some(Key::Tab),
(WinitKey::Named(NamedKey::ArrowLeft), _) => Some(Key::LeftArrow),
(WinitKey::Named(NamedKey::ArrowRight), _) => Some(Key::RightArrow),
(WinitKey::Named(NamedKey::ArrowUp), _) => Some(Key::UpArrow),
(WinitKey::Named(NamedKey::ArrowDown), _) => Some(Key::DownArrow),
(WinitKey::Named(NamedKey::PageUp), _) => Some(Key::PageUp),
(WinitKey::Named(NamedKey::PageDown), _) => Some(Key::PageDown),
(WinitKey::Named(NamedKey::Home), _) => Some(Key::Home),
(WinitKey::Named(NamedKey::End), _) => Some(Key::End),
(WinitKey::Named(NamedKey::Insert), _) => Some(Key::Insert),
(WinitKey::Named(NamedKey::Delete), _) => Some(Key::Delete),
(WinitKey::Named(NamedKey::Backspace), _) => Some(Key::Backspace),
(WinitKey::Named(NamedKey::Space), _) => Some(Key::Space),
(WinitKey::Named(NamedKey::Enter), KeyLocation::Standard) => Some(Key::Enter),
(WinitKey::Named(NamedKey::Enter), KeyLocation::Numpad) => Some(Key::KeypadEnter),
(WinitKey::Named(NamedKey::Escape), _) => Some(Key::Escape),
(WinitKey::Named(NamedKey::Control), KeyLocation::Left) => Some(Key::LeftCtrl),
(WinitKey::Named(NamedKey::Control), KeyLocation::Right) => Some(Key::RightCtrl),
(WinitKey::Named(NamedKey::Shift), KeyLocation::Left) => Some(Key::LeftShift),
(WinitKey::Named(NamedKey::Shift), KeyLocation::Right) => Some(Key::RightShift),
(WinitKey::Named(NamedKey::Alt), KeyLocation::Left) => Some(Key::LeftAlt),
(WinitKey::Named(NamedKey::Alt), KeyLocation::Right) => Some(Key::RightAlt),
(WinitKey::Named(NamedKey::Super), KeyLocation::Left) => Some(Key::LeftSuper),
(WinitKey::Named(NamedKey::Super), KeyLocation::Right) => Some(Key::RightSuper),
(WinitKey::Named(NamedKey::ContextMenu), _) => Some(Key::Menu),
(WinitKey::Named(NamedKey::F1), _) => Some(Key::F1),
(WinitKey::Named(NamedKey::F2), _) => Some(Key::F2),
(WinitKey::Named(NamedKey::F3), _) => Some(Key::F3),
(WinitKey::Named(NamedKey::F4), _) => Some(Key::F4),
(WinitKey::Named(NamedKey::F5), _) => Some(Key::F5),
(WinitKey::Named(NamedKey::F6), _) => Some(Key::F6),
(WinitKey::Named(NamedKey::F7), _) => Some(Key::F7),
(WinitKey::Named(NamedKey::F8), _) => Some(Key::F8),
(WinitKey::Named(NamedKey::F9), _) => Some(Key::F9),
(WinitKey::Named(NamedKey::F10), _) => Some(Key::F10),
(WinitKey::Named(NamedKey::F11), _) => Some(Key::F11),
(WinitKey::Named(NamedKey::F12), _) => Some(Key::F12),
(WinitKey::Named(NamedKey::CapsLock), _) => Some(Key::CapsLock),
(WinitKey::Named(NamedKey::ScrollLock), _) => Some(Key::ScrollLock),
(WinitKey::Named(NamedKey::NumLock), _) => Some(Key::NumLock),
(WinitKey::Named(NamedKey::PrintScreen), _) => Some(Key::PrintScreen),
(WinitKey::Named(NamedKey::Pause), _) => Some(Key::Pause),
(WinitKey::Character("0"), KeyLocation::Standard) => Some(Key::Alpha0),
(WinitKey::Character("1"), KeyLocation::Standard) => Some(Key::Alpha1),
(WinitKey::Character("2"), KeyLocation::Standard) => Some(Key::Alpha2),
(WinitKey::Character("3"), KeyLocation::Standard) => Some(Key::Alpha3),
(WinitKey::Character("4"), KeyLocation::Standard) => Some(Key::Alpha4),
(WinitKey::Character("5"), KeyLocation::Standard) => Some(Key::Alpha5),
(WinitKey::Character("6"), KeyLocation::Standard) => Some(Key::Alpha6),
(WinitKey::Character("7"), KeyLocation::Standard) => Some(Key::Alpha7),
(WinitKey::Character("8"), KeyLocation::Standard) => Some(Key::Alpha8),
(WinitKey::Character("9"), KeyLocation::Standard) => Some(Key::Alpha9),
(WinitKey::Character("0"), KeyLocation::Numpad) => Some(Key::Keypad0),
(WinitKey::Character("1"), KeyLocation::Numpad) => Some(Key::Keypad1),
(WinitKey::Character("2"), KeyLocation::Numpad) => Some(Key::Keypad2),
(WinitKey::Character("3"), KeyLocation::Numpad) => Some(Key::Keypad3),
(WinitKey::Character("4"), KeyLocation::Numpad) => Some(Key::Keypad4),
(WinitKey::Character("5"), KeyLocation::Numpad) => Some(Key::Keypad5),
(WinitKey::Character("6"), KeyLocation::Numpad) => Some(Key::Keypad6),
(WinitKey::Character("7"), KeyLocation::Numpad) => Some(Key::Keypad7),
(WinitKey::Character("8"), KeyLocation::Numpad) => Some(Key::Keypad8),
(WinitKey::Character("9"), KeyLocation::Numpad) => Some(Key::Keypad9),
(WinitKey::Character("a"), _) => Some(Key::A),
(WinitKey::Character("b"), _) => Some(Key::B),
(WinitKey::Character("c"), _) => Some(Key::C),
(WinitKey::Character("d"), _) => Some(Key::D),
(WinitKey::Character("e"), _) => Some(Key::E),
(WinitKey::Character("f"), _) => Some(Key::F),
(WinitKey::Character("g"), _) => Some(Key::G),
(WinitKey::Character("h"), _) => Some(Key::H),
(WinitKey::Character("i"), _) => Some(Key::I),
(WinitKey::Character("j"), _) => Some(Key::J),
(WinitKey::Character("k"), _) => Some(Key::K),
(WinitKey::Character("l"), _) => Some(Key::L),
(WinitKey::Character("m"), _) => Some(Key::M),
(WinitKey::Character("n"), _) => Some(Key::N),
(WinitKey::Character("o"), _) => Some(Key::O),
(WinitKey::Character("p"), _) => Some(Key::P),
(WinitKey::Character("q"), _) => Some(Key::Q),
(WinitKey::Character("r"), _) => Some(Key::R),
(WinitKey::Character("s"), _) => Some(Key::S),
(WinitKey::Character("t"), _) => Some(Key::T),
(WinitKey::Character("u"), _) => Some(Key::U),
(WinitKey::Character("v"), _) => Some(Key::V),
(WinitKey::Character("w"), _) => Some(Key::W),
(WinitKey::Character("x"), _) => Some(Key::X),
(WinitKey::Character("y"), _) => Some(Key::Y),
(WinitKey::Character("z"), _) => Some(Key::Z),
(WinitKey::Character("'"), _) => Some(Key::Apostrophe),
(WinitKey::Character(","), KeyLocation::Standard) => Some(Key::Comma),
(WinitKey::Character("-"), KeyLocation::Standard) => Some(Key::Minus),
(WinitKey::Character("-"), KeyLocation::Numpad) => Some(Key::KeypadSubtract),
(WinitKey::Character("."), KeyLocation::Standard) => Some(Key::Period),
(WinitKey::Character("."), KeyLocation::Numpad) => Some(Key::KeypadDecimal),
(WinitKey::Character("/"), KeyLocation::Standard) => Some(Key::Slash),
(WinitKey::Character("/"), KeyLocation::Numpad) => Some(Key::KeypadDivide),
(WinitKey::Character(";"), _) => Some(Key::Semicolon),
(WinitKey::Character("="), KeyLocation::Standard) => Some(Key::Equal),
(WinitKey::Character("="), KeyLocation::Numpad) => Some(Key::KeypadEqual),
(WinitKey::Character("["), _) => Some(Key::LeftBracket),
(WinitKey::Character("\\"), _) => Some(Key::Backslash),
(WinitKey::Character("]"), _) => Some(Key::RightBracket),
(WinitKey::Character("`"), _) => Some(Key::GraveAccent),
(WinitKey::Character("*"), KeyLocation::Numpad) => Some(Key::KeypadMultiply),
(WinitKey::Character("+"), KeyLocation::Numpad) => Some(Key::KeypadAdd),
_ => None,
}
}
fn handle_key_modifier(io: &mut Io, key: VirtualKeyCode, down: bool) {
if key == VirtualKeyCode::LShift || key == VirtualKeyCode::RShift {
io.add_key_event(imgui::Key::ModShift, down);
} else if key == VirtualKeyCode::LControl || key == VirtualKeyCode::RControl {
io.add_key_event(imgui::Key::ModCtrl, down);
} else if key == VirtualKeyCode::LAlt || key == VirtualKeyCode::RAlt {
io.add_key_event(imgui::Key::ModAlt, down);
} else if key == VirtualKeyCode::LWin || key == VirtualKeyCode::RWin {
io.add_key_event(imgui::Key::ModSuper, down);
fn handle_key_modifier(io: &mut Io, key: &WinitKey, down: bool) {
match key {
WinitKey::Named(NamedKey::Shift) => io.add_key_event(imgui::Key::ModShift, down),
WinitKey::Named(NamedKey::Control) => io.add_key_event(imgui::Key::ModCtrl, down),
WinitKey::Named(NamedKey::Alt) => io.add_key_event(imgui::Key::ModAlt, down),
WinitKey::Named(NamedKey::Super) => io.add_key_event(imgui::Key::ModSuper, down),
_ => {}
}
}
@ -411,19 +410,18 @@ impl WinitPlatform {
}
// Track key release events outside our window. If we don't do this,
// we might never see the release event if some other window gets focus.
Event::DeviceEvent {
event:
DeviceEvent::Key(KeyboardInput {
state: ElementState::Released,
virtual_keycode: Some(key),
..
}),
..
} => {
if let Some(key) = to_imgui_key(key) {
io.add_key_event(key, false);
}
}
// Event::DeviceEvent {
// event:
// DeviceEvent::Key(RawKeyEvent {
// physical_key,
// state: ElementState::Released,
// }),
// ..
// } => {
// if let Some(key) = to_imgui_key(key) {
// io.add_key_event(key, false);
// }
// }
_ => (),
}
}
@ -456,24 +454,26 @@ impl WinitPlatform {
io.display_size = [logical_size.width as f32, logical_size.height as f32];
}
WindowEvent::ModifiersChanged(modifiers) => {
let state = modifiers.state();
// We need to track modifiers separately because some system like macOS, will
// not reliably send modifier states during certain events like ScreenCapture.
// Gotta let the people show off their pretty imgui widgets!
io.add_key_event(Key::ModShift, modifiers.shift());
io.add_key_event(Key::ModCtrl, modifiers.ctrl());
io.add_key_event(Key::ModAlt, modifiers.alt());
io.add_key_event(Key::ModSuper, modifiers.logo());
io.add_key_event(Key::ModShift, state.shift_key());
io.add_key_event(Key::ModCtrl, state.control_key());
io.add_key_event(Key::ModAlt, state.alt_key());
io.add_key_event(Key::ModSuper, state.super_key());
}
WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(key),
state,
..
},
..
} => {
let pressed = state == ElementState::Pressed;
WindowEvent::KeyboardInput { ref event, .. } => {
if let Some(txt) = &event.text {
for ch in txt.chars() {
if ch != '\u{7f}' {
io.add_input_character(ch)
}
}
}
let key = event.key_without_modifiers();
let pressed = event.state == ElementState::Pressed;
// We map both left and right ctrl to `ModCtrl`, etc.
// imgui is told both "left control is pressed" and
@ -481,20 +481,15 @@ impl WinitPlatform {
// applications to use either general "ctrl" or a
// specific key. Same applies to other modifiers.
// https://github.com/ocornut/imgui/issues/5047
handle_key_modifier(io, key, pressed);
handle_key_modifier(io, &key, pressed);
println!("KEY EVENT: {event:?}");
// Add main key event
if let Some(key) = to_imgui_key(key) {
if let Some(key) = to_imgui_key(key, event.location) {
io.add_key_event(key, pressed);
}
}
WindowEvent::ReceivedCharacter(ch) => {
// 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::CursorMoved { position, .. } => {
let position = position.to_logical(window.scale_factor());
let position = self.scale_pos_from_winit(window, position);