mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
imgui-glutin-support crate
This commit is contained in:
parent
b8a1abf1b7
commit
eeb800db13
@ -5,6 +5,7 @@
|
||||
### Added
|
||||
|
||||
- `ImGui::mouse_down`
|
||||
- `imgui-glutin-support` crate
|
||||
|
||||
## [0.0.20] - 2018-08-13
|
||||
|
||||
|
||||
@ -16,4 +16,4 @@ travis-ci = { repository = "Gekkio/imgui-rs" }
|
||||
imgui-sys = { version = "0.0.21-pre", path = "imgui-sys" }
|
||||
|
||||
[workspace]
|
||||
members = ["imgui-examples", "imgui-sys", "imgui-gfx-renderer", "imgui-glium-renderer"]
|
||||
members = ["imgui-examples", "imgui-sys", "imgui-gfx-renderer", "imgui-glium-renderer", "imgui-glutin-support"]
|
||||
|
||||
16
imgui-glutin-support/Cargo.toml
Normal file
16
imgui-glutin-support/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "imgui-glutin-support"
|
||||
version = "0.0.21-pre"
|
||||
authors = ["Joonas Javanainen <joonas.javanainen@gmail.com>", "imgui-rs contributors"]
|
||||
description = "glutin support code for the imgui crate"
|
||||
homepage = "https://github.com/Gekkio/imgui-rs"
|
||||
repository = "https://github.com/Gekkio/imgui-rs"
|
||||
license = "MIT/Apache-2.0"
|
||||
categories = ["gui"]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "Gekkio/imgui-rs" }
|
||||
|
||||
[dependencies]
|
||||
glutin = "0.18"
|
||||
imgui = { version = "0.0.21-pre", path = "../" }
|
||||
224
imgui-glutin-support/src/lib.rs
Normal file
224
imgui-glutin-support/src/lib.rs
Normal file
@ -0,0 +1,224 @@
|
||||
//! This crate provides support functions to simplify integrating imgui-rs with glutin.
|
||||
//!
|
||||
//! # Using the library
|
||||
//!
|
||||
//! In your initialization code call `configure_keys`:
|
||||
//!
|
||||
//! ```
|
||||
//! # extern crate imgui;
|
||||
//! # extern crate imgui_glutin_support;
|
||||
//! use imgui::ImGui;
|
||||
//!
|
||||
//! let mut imgui = ImGui::init();
|
||||
//! imgui_glutin_support::configure_keys(&mut imgui);
|
||||
//! ```
|
||||
//!
|
||||
//! In your main loop you should already be retrieving events from glutin and handling them. All
|
||||
//! you need to do is pass each event to `imgui_glutin_support` as well:
|
||||
//!
|
||||
//! ```
|
||||
//! # extern crate glutin;
|
||||
//! # extern crate imgui;
|
||||
//! # extern crate imgui_glutin_support;
|
||||
//! # use glutin::EventsLoop;
|
||||
//! # use imgui::ImGui;
|
||||
//! # let mut events_loop = EventsLoop::new();
|
||||
//! # let mut imgui = ImGui::init();
|
||||
//! events_loop.poll_events(|event| {
|
||||
//! // do application-specific stuff with event
|
||||
//!
|
||||
//! imgui_glutin_support::handle_event(&mut imgui, &event);
|
||||
//! });
|
||||
//! ```
|
||||
//!
|
||||
//! # Advanced use cases
|
||||
//!
|
||||
//! In more advanced use cases you might want to handle and filter events yourself and call some of
|
||||
//! the various smaller helper functions exported by the library.
|
||||
//!
|
||||
//! For example, you might want to customize mouse wheel line scrolling amount:
|
||||
//!
|
||||
//! ```
|
||||
//! # extern crate glutin;
|
||||
//! # extern crate imgui;
|
||||
//! # extern crate imgui_glutin_support;
|
||||
//! # use glutin::{EventsLoop, Event, WindowEvent, MouseScrollDelta, TouchPhase};
|
||||
//! # use imgui::ImGui;
|
||||
//! # let mut events_loop = EventsLoop::new();
|
||||
//! # let mut imgui = ImGui::init();
|
||||
//! events_loop.poll_events(|event| {
|
||||
//! // do application-specific stuff with event
|
||||
//!
|
||||
//! // default handling for events
|
||||
//! imgui_glutin_support::handle_event(&mut imgui, &event);
|
||||
//!
|
||||
//! // Scroll 10 times the pixels per line by handling LineDelta events again and
|
||||
//! // overriding the mouse wheel value
|
||||
//! if let Event::WindowEvent { event, .. } = event {
|
||||
//! match event {
|
||||
//! WindowEvent::MouseWheel {
|
||||
//! delta: MouseScrollDelta::LineDelta(_, lines),
|
||||
//! phase: TouchPhase::Moved,
|
||||
//! ..
|
||||
//! } => {
|
||||
//! imgui.set_mouse_wheel(lines * 10.0);
|
||||
//! }
|
||||
//! _ => ()
|
||||
//! }
|
||||
//! }
|
||||
//! });
|
||||
//! ```
|
||||
|
||||
extern crate glutin;
|
||||
extern crate imgui;
|
||||
|
||||
use glutin::{
|
||||
ElementState, Event, KeyboardInput, ModifiersState, MouseButton, MouseCursor, MouseScrollDelta,
|
||||
TouchPhase, VirtualKeyCode, Window, WindowEvent,
|
||||
};
|
||||
use imgui::{FrameSize, ImGui, ImGuiKey, ImGuiMouseCursor};
|
||||
|
||||
/// Configure imgui key map with glutin `VirtualKeyCode` values
|
||||
pub fn configure_keys(imgui: &mut ImGui) {
|
||||
imgui.set_imgui_key(ImGuiKey::Tab, VirtualKeyCode::Tab as _);
|
||||
imgui.set_imgui_key(ImGuiKey::LeftArrow, VirtualKeyCode::Left as _);
|
||||
imgui.set_imgui_key(ImGuiKey::RightArrow, VirtualKeyCode::Right as _);
|
||||
imgui.set_imgui_key(ImGuiKey::UpArrow, VirtualKeyCode::Up as _);
|
||||
imgui.set_imgui_key(ImGuiKey::DownArrow, VirtualKeyCode::Down as _);
|
||||
imgui.set_imgui_key(ImGuiKey::PageUp, VirtualKeyCode::PageUp as _);
|
||||
imgui.set_imgui_key(ImGuiKey::PageDown, VirtualKeyCode::PageDown as _);
|
||||
imgui.set_imgui_key(ImGuiKey::Home, VirtualKeyCode::Home as _);
|
||||
imgui.set_imgui_key(ImGuiKey::End, VirtualKeyCode::End as _);
|
||||
imgui.set_imgui_key(ImGuiKey::Delete, VirtualKeyCode::Delete as _);
|
||||
imgui.set_imgui_key(ImGuiKey::Backspace, VirtualKeyCode::Back as _);
|
||||
imgui.set_imgui_key(ImGuiKey::Enter, VirtualKeyCode::Return as _);
|
||||
imgui.set_imgui_key(ImGuiKey::Escape, VirtualKeyCode::Escape as _);
|
||||
imgui.set_imgui_key(ImGuiKey::A, VirtualKeyCode::A as _);
|
||||
imgui.set_imgui_key(ImGuiKey::C, VirtualKeyCode::C as _);
|
||||
imgui.set_imgui_key(ImGuiKey::V, VirtualKeyCode::V as _);
|
||||
imgui.set_imgui_key(ImGuiKey::X, VirtualKeyCode::X as _);
|
||||
imgui.set_imgui_key(ImGuiKey::Y, VirtualKeyCode::Y as _);
|
||||
imgui.set_imgui_key(ImGuiKey::Z, VirtualKeyCode::Z as _);
|
||||
}
|
||||
|
||||
/// Update imgui keyboard state
|
||||
pub fn handle_keyboard_input(imgui: &mut ImGui, event: KeyboardInput) {
|
||||
handle_modifiers(imgui, event.modifiers);
|
||||
if let Some(key) = event.virtual_keycode {
|
||||
let state_bool = event.state == ElementState::Pressed;
|
||||
imgui.set_key(key as _, state_bool);
|
||||
match key {
|
||||
VirtualKeyCode::LShift | VirtualKeyCode::RShift => imgui.set_key_shift(state_bool),
|
||||
VirtualKeyCode::LControl | VirtualKeyCode::RControl => imgui.set_key_ctrl(state_bool),
|
||||
VirtualKeyCode::LAlt | VirtualKeyCode::RAlt => imgui.set_key_alt(state_bool),
|
||||
VirtualKeyCode::LWin | VirtualKeyCode::RWin => imgui.set_key_super(state_bool),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Update imgui keyboard modifier state
|
||||
pub fn handle_modifiers(imgui: &mut ImGui, modifiers: ModifiersState) {
|
||||
imgui.set_key_shift(modifiers.shift);
|
||||
imgui.set_key_ctrl(modifiers.ctrl);
|
||||
imgui.set_key_alt(modifiers.alt);
|
||||
imgui.set_key_super(modifiers.logo);
|
||||
}
|
||||
|
||||
/// Update imgui mouse wheel position
|
||||
pub fn handle_mouse_scroll_delta(imgui: &mut ImGui, delta: MouseScrollDelta) {
|
||||
match delta {
|
||||
MouseScrollDelta::LineDelta(_, y) => imgui.set_mouse_wheel(y),
|
||||
MouseScrollDelta::PixelDelta(pos) => imgui.set_mouse_wheel(pos.y as f32),
|
||||
}
|
||||
}
|
||||
|
||||
/// Update imgui mouse button state
|
||||
pub fn handle_mouse_button_state(imgui: &mut ImGui, button: MouseButton, state: ElementState) {
|
||||
let mut states = imgui.mouse_down();
|
||||
let state_bool = state == ElementState::Pressed;
|
||||
match button {
|
||||
MouseButton::Left => states[0] = state_bool,
|
||||
MouseButton::Right => states[1] = state_bool,
|
||||
MouseButton::Middle => states[2] = state_bool,
|
||||
MouseButton::Other(idx @ 0...4) => states[idx as usize] = state_bool,
|
||||
_ => (),
|
||||
}
|
||||
imgui.set_mouse_down(states);
|
||||
}
|
||||
|
||||
/// Update imgui state from glutin event
|
||||
pub fn handle_event(imgui: &mut ImGui, event: &Event) {
|
||||
match event {
|
||||
&Event::WindowEvent { ref event, .. } => handle_window_event(imgui, event),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
/// Update imgui state from glutin window event
|
||||
pub fn handle_window_event(imgui: &mut ImGui, event: &WindowEvent) {
|
||||
use WindowEvent::*;
|
||||
match event {
|
||||
&KeyboardInput { input, .. } => handle_keyboard_input(imgui, input),
|
||||
&ReceivedCharacter(ch) => imgui.add_input_character(ch),
|
||||
&CursorMoved {
|
||||
position,
|
||||
modifiers,
|
||||
..
|
||||
} => {
|
||||
imgui.set_mouse_pos(position.x as f32, position.y as f32);
|
||||
handle_modifiers(imgui, modifiers);
|
||||
}
|
||||
&MouseWheel {
|
||||
delta,
|
||||
modifiers,
|
||||
phase: TouchPhase::Moved,
|
||||
..
|
||||
} => {
|
||||
handle_mouse_scroll_delta(imgui, delta);
|
||||
handle_modifiers(imgui, modifiers);
|
||||
}
|
||||
&MouseInput {
|
||||
state,
|
||||
button,
|
||||
modifiers,
|
||||
..
|
||||
} => {
|
||||
handle_mouse_button_state(imgui, button, state);
|
||||
handle_modifiers(imgui, modifiers);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
/// Update glutin window mouse cursor state
|
||||
pub fn update_mouse_cursor(imgui: &ImGui, window: &Window) {
|
||||
let mouse_cursor = imgui.mouse_cursor();
|
||||
if imgui.mouse_draw_cursor() || mouse_cursor == ImGuiMouseCursor::None {
|
||||
// Hide OS cursor
|
||||
window.hide_cursor(true);
|
||||
} else {
|
||||
// Set OS cursor
|
||||
window.hide_cursor(false);
|
||||
window.set_cursor(match mouse_cursor {
|
||||
ImGuiMouseCursor::None => unreachable!("mouse_cursor was None!"),
|
||||
ImGuiMouseCursor::Arrow => MouseCursor::Arrow,
|
||||
ImGuiMouseCursor::TextInput => MouseCursor::Text,
|
||||
ImGuiMouseCursor::Move => MouseCursor::Move,
|
||||
ImGuiMouseCursor::ResizeNS => MouseCursor::NsResize,
|
||||
ImGuiMouseCursor::ResizeEW => MouseCursor::EwResize,
|
||||
ImGuiMouseCursor::ResizeNESW => MouseCursor::NeswResize,
|
||||
ImGuiMouseCursor::ResizeNWSE => MouseCursor::NwseResize,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current frame size for imgui frame rendering.
|
||||
///
|
||||
/// Returns `None` if the window no longer exists
|
||||
pub fn get_frame_size(window: &mut Window) -> Option<FrameSize> {
|
||||
window.get_inner_size().map(|logical_size| FrameSize {
|
||||
logical_size: logical_size.into(),
|
||||
hidpi_factor: window.get_hidpi_factor(),
|
||||
})
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user