mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-20 01:48:29 +00:00
API changes + additions
This commit is contained in:
parent
e261db71ba
commit
8bf34e8ced
@ -1,55 +1,80 @@
|
|||||||
use glium::{DisplayBuild, Surface};
|
use glium::{DisplayBuild, Surface};
|
||||||
|
use glium::backend::glutin_backend::GlutinFacade;
|
||||||
use glium::glutin;
|
use glium::glutin;
|
||||||
use glium::glutin::{ElementState, Event, MouseButton, VirtualKeyCode};
|
use glium::glutin::{ElementState, Event, MouseButton, VirtualKeyCode};
|
||||||
use imgui::{ImGui, Frame};
|
use imgui::{ImGui, Frame};
|
||||||
use imgui::glium_renderer::Renderer;
|
use imgui::glium_renderer::Renderer;
|
||||||
use time::SteadyTime;
|
use time::SteadyTime;
|
||||||
|
|
||||||
pub fn main_with_frame<'a, F: Fn(&Frame<'a>)>(f: F) {
|
pub struct Support {
|
||||||
let display = glutin::WindowBuilder::new()
|
display: GlutinFacade,
|
||||||
.build_glium()
|
imgui: ImGui,
|
||||||
.unwrap();
|
renderer: Renderer,
|
||||||
|
last_frame: SteadyTime,
|
||||||
|
mouse_pos: (i32, i32),
|
||||||
|
mouse_pressed: (bool, bool, bool)
|
||||||
|
}
|
||||||
|
|
||||||
let mut imgui = ImGui::init();
|
impl Support {
|
||||||
let mut renderer = Renderer::init(&mut imgui, &display).unwrap();
|
pub fn init() -> Support {
|
||||||
|
let display = glutin::WindowBuilder::new()
|
||||||
|
.build_glium()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut last_frame = SteadyTime::now();
|
let mut imgui = ImGui::init();
|
||||||
let mut mouse_pos = (0, 0);
|
let renderer = Renderer::init(&mut imgui, &display).unwrap();
|
||||||
let mut mouse_pressed = (false, false, false);
|
|
||||||
|
|
||||||
'main: loop {
|
Support {
|
||||||
|
display: display,
|
||||||
|
imgui: imgui,
|
||||||
|
renderer: renderer,
|
||||||
|
last_frame: SteadyTime::now(),
|
||||||
|
mouse_pos: (0, 0),
|
||||||
|
mouse_pressed: (false, false, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_mouse(&mut self) {
|
||||||
|
self.imgui.set_mouse_pos(self.mouse_pos.0 as f32, self.mouse_pos.1 as f32);
|
||||||
|
self.imgui.set_mouse_down(&[self.mouse_pressed.0, self.mouse_pressed.1, self.mouse_pressed.2, false, false]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render<'fr, 'a: 'fr , F: FnMut(&Frame<'fr>) -> bool>(
|
||||||
|
&'a mut self, clear_color: (f32, f32, f32, f32), mut f: F) -> bool {
|
||||||
|
let mut result;
|
||||||
let now = SteadyTime::now();
|
let now = SteadyTime::now();
|
||||||
let delta = now - last_frame;
|
let delta = now - self.last_frame;
|
||||||
let delta_f = delta.num_nanoseconds().unwrap() as f32 / 1_000_000_000.0;
|
let delta_f = delta.num_nanoseconds().unwrap() as f32 / 1_000_000_000.0;
|
||||||
last_frame = now;
|
self.last_frame = now;
|
||||||
|
|
||||||
imgui.set_mouse_pos(mouse_pos.0 as f32, mouse_pos.1 as f32);
|
self.update_mouse();
|
||||||
imgui.set_mouse_down(&[mouse_pressed.0, mouse_pressed.1, mouse_pressed.2, false, false]);
|
|
||||||
|
|
||||||
let mut target = display.draw();
|
let mut target = self.display.draw();
|
||||||
target.clear_color(1.0, 1.0, 1.0, 1.0);
|
target.clear_color(clear_color.0, clear_color.1,
|
||||||
|
clear_color.2, clear_color.3);
|
||||||
|
|
||||||
let (width, height) = target.get_dimensions();
|
let (width, height) = target.get_dimensions();
|
||||||
let frame = imgui.frame(width, height, delta_f);
|
let frame = self.imgui.frame(width, height, delta_f);
|
||||||
f(&frame);
|
result = f(&frame);
|
||||||
renderer.render(&mut target, frame).unwrap();
|
self.renderer.render(&mut target, frame).unwrap();
|
||||||
|
|
||||||
target.finish().unwrap();
|
target.finish().unwrap();
|
||||||
|
|
||||||
for event in display.poll_events() {
|
for event in self.display.poll_events() {
|
||||||
match event {
|
match event {
|
||||||
Event::Closed |
|
Event::Closed |
|
||||||
Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Escape))
|
Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Escape))
|
||||||
=> break 'main,
|
=> result = false,
|
||||||
Event::MouseMoved(pos) => mouse_pos = pos,
|
Event::MouseMoved(pos) => self.mouse_pos = pos,
|
||||||
Event::MouseInput(state, MouseButton::Left) =>
|
Event::MouseInput(state, MouseButton::Left) =>
|
||||||
mouse_pressed.0 = state == ElementState::Pressed,
|
self.mouse_pressed.0 = state == ElementState::Pressed,
|
||||||
Event::MouseInput(state, MouseButton::Right) =>
|
Event::MouseInput(state, MouseButton::Right) =>
|
||||||
mouse_pressed.1 = state == ElementState::Pressed,
|
self.mouse_pressed.1 = state == ElementState::Pressed,
|
||||||
Event::MouseInput(state, MouseButton::Middle) =>
|
Event::MouseInput(state, MouseButton::Middle) =>
|
||||||
mouse_pressed.2 = state == ElementState::Pressed,
|
self.mouse_pressed.2 = state == ElementState::Pressed,
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,24 +4,166 @@ extern crate glium;
|
|||||||
extern crate imgui;
|
extern crate imgui;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
|
||||||
use imgui::Frame;
|
use imgui::*;
|
||||||
|
|
||||||
|
use self::support::Support;
|
||||||
|
|
||||||
mod support;
|
mod support;
|
||||||
|
|
||||||
fn main() {
|
struct State {
|
||||||
// let mut show_app_metrics = false;
|
clear_color: (f32, f32, f32, f32),
|
||||||
let show_app_main_menu_bar = true;
|
show_app_metrics: bool,
|
||||||
|
show_app_main_menu_bar: bool,
|
||||||
support::main_with_frame(|frame| {
|
show_app_console: bool,
|
||||||
// if show_app_metrics { show_metrics_window(&mut show_app_metrics) }
|
show_app_layout: bool,
|
||||||
if show_app_main_menu_bar { show_example_app_main_menu_bar(frame) }
|
show_app_long_text: bool,
|
||||||
});
|
show_app_auto_resize: bool,
|
||||||
|
show_app_fixed_overlay: bool,
|
||||||
|
show_app_custom_rendering: bool,
|
||||||
|
show_app_manipulating_window_title: bool,
|
||||||
|
show_app_about: bool,
|
||||||
|
no_titlebar: bool,
|
||||||
|
no_border: bool,
|
||||||
|
no_resize: bool,
|
||||||
|
no_move: bool,
|
||||||
|
no_scrollbar: bool,
|
||||||
|
no_collapse: bool,
|
||||||
|
no_menu: bool,
|
||||||
|
bg_alpha: f32,
|
||||||
|
file_menu: FileMenuState
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_example_app_main_menu_bar<'a>(frame: &Frame<'a>) {
|
impl Default for State {
|
||||||
|
fn default() -> Self {
|
||||||
|
State {
|
||||||
|
clear_color: (114.0 / 255.0, 144.0 / 255.0, 154.0 / 255.0, 1.0),
|
||||||
|
show_app_metrics: false,
|
||||||
|
show_app_main_menu_bar: false,
|
||||||
|
show_app_console: false,
|
||||||
|
show_app_layout: false,
|
||||||
|
show_app_long_text: false,
|
||||||
|
show_app_auto_resize: false,
|
||||||
|
show_app_fixed_overlay: false,
|
||||||
|
show_app_custom_rendering: false,
|
||||||
|
show_app_manipulating_window_title: false,
|
||||||
|
show_app_about: false,
|
||||||
|
no_titlebar: false,
|
||||||
|
no_border: false,
|
||||||
|
no_resize: false,
|
||||||
|
no_move: false,
|
||||||
|
no_scrollbar: false,
|
||||||
|
no_collapse: false,
|
||||||
|
no_menu: false,
|
||||||
|
bg_alpha: 0.65,
|
||||||
|
file_menu: Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FileMenuState {
|
||||||
|
enabled: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FileMenuState {
|
||||||
|
fn default() -> Self {
|
||||||
|
FileMenuState {
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut state = State {
|
||||||
|
.. Default::default()
|
||||||
|
};
|
||||||
|
let mut support = Support::init();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let active = support.render(state.clear_color, |frame| {
|
||||||
|
show_test_window(frame, &mut state)
|
||||||
|
});
|
||||||
|
if !active { break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_test_window<'a>(frame: &Frame<'a>, state: &mut State) -> bool {
|
||||||
|
if state.show_app_main_menu_bar { show_example_app_main_menu_bar(frame, state) }
|
||||||
|
if state.show_app_fixed_overlay {
|
||||||
|
state.show_app_fixed_overlay = show_example_app_fixed_overlay(frame);
|
||||||
|
}
|
||||||
|
if state.show_app_about {
|
||||||
|
state.show_app_about = frame.window()
|
||||||
|
.name(im_str!("About ImGui"))
|
||||||
|
.always_auto_resize(true)
|
||||||
|
.closable(true)
|
||||||
|
.build(|| {
|
||||||
|
frame.text(ImStr::from_str(&format!("ImGui {}", imgui::get_version())));
|
||||||
|
frame.separator();
|
||||||
|
frame.text(im_str!("By Omar Cornut and all github contributors."));
|
||||||
|
frame.text(im_str!("ImGui is licensed under the MIT License, see LICENSE for more information."));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.window().name(im_str!("ImGui Demo"))
|
||||||
|
.title_bar(!state.no_titlebar)
|
||||||
|
.show_borders(!state.no_border)
|
||||||
|
.resizable(!state.no_resize)
|
||||||
|
.movable(!state.no_move)
|
||||||
|
.scroll_bar(!state.no_scrollbar)
|
||||||
|
.collapsible(!state.no_collapse)
|
||||||
|
.menu_bar(!state.no_menu)
|
||||||
|
.bg_alpha(state.bg_alpha)
|
||||||
|
.size((550.0, 680.0), ImGuiSetCond_FirstUseEver)
|
||||||
|
.closable(true)
|
||||||
|
.build(|| {
|
||||||
|
frame.text(im_str!("ImGui says hello."));
|
||||||
|
frame.menu_bar(|| {
|
||||||
|
frame.menu(im_str!("Menu")).build(|| {
|
||||||
|
show_example_menu_file(frame, &mut state.file_menu);
|
||||||
|
});
|
||||||
|
frame.menu(im_str!("Examples")).build(|| {
|
||||||
|
if frame.menu_item(im_str!("Main menu bar")).build() {
|
||||||
|
state.show_app_main_menu_bar = !state.show_app_main_menu_bar;
|
||||||
|
}
|
||||||
|
if frame.menu_item(im_str!("Console")).build() {
|
||||||
|
state.show_app_console = !state.show_app_console;
|
||||||
|
}
|
||||||
|
if frame.menu_item(im_str!("Simple layout")).build() {
|
||||||
|
state.show_app_layout = !state.show_app_layout;
|
||||||
|
}
|
||||||
|
if frame.menu_item(im_str!("Long text display")).build() {
|
||||||
|
state.show_app_long_text = !state.show_app_long_text;
|
||||||
|
}
|
||||||
|
if frame.menu_item(im_str!("Auto-resizing window")).build() {
|
||||||
|
state.show_app_auto_resize = !state.show_app_auto_resize;
|
||||||
|
}
|
||||||
|
if frame.menu_item(im_str!("Simple overlay")).build() {
|
||||||
|
state.show_app_fixed_overlay = !state.show_app_fixed_overlay;
|
||||||
|
}
|
||||||
|
if frame.menu_item(im_str!("Manipulating window title")).build() {
|
||||||
|
state.show_app_manipulating_window_title =
|
||||||
|
!state.show_app_manipulating_window_title;
|
||||||
|
}
|
||||||
|
if frame.menu_item(im_str!("Custom rendering")).build() {
|
||||||
|
state.show_app_custom_rendering = !state.show_app_custom_rendering;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
frame.menu(im_str!("Help")).build(|| {
|
||||||
|
if frame.menu_item(im_str!("Metrics")).build() {
|
||||||
|
state.show_app_metrics = !state.show_app_metrics;
|
||||||
|
}
|
||||||
|
if frame.menu_item(im_str!("About ImGui")).build() {
|
||||||
|
state.show_app_about = !state.show_app_about;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_example_app_main_menu_bar<'a>(frame: &Frame<'a>, state: &mut State) {
|
||||||
frame.main_menu_bar(|| {
|
frame.main_menu_bar(|| {
|
||||||
frame.menu(im_str!("File")).build(|| {
|
frame.menu(im_str!("File")).build(|| {
|
||||||
show_example_menu_file(frame);
|
show_example_menu_file(frame, &mut state.file_menu);
|
||||||
});
|
});
|
||||||
frame.menu(im_str!("Edit")).build(|| {
|
frame.menu(im_str!("Edit")).build(|| {
|
||||||
if frame.menu_item(im_str!("Undo")).shortcut(im_str!("CTRL+Z")).build() { }
|
if frame.menu_item(im_str!("Undo")).shortcut(im_str!("CTRL+Z")).build() { }
|
||||||
@ -35,7 +177,7 @@ fn show_example_app_main_menu_bar<'a>(frame: &Frame<'a>) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_example_menu_file<'a>(frame: &Frame<'a>) {
|
fn show_example_menu_file<'a>(frame: &Frame<'a>, state: &mut FileMenuState) {
|
||||||
frame.menu_item(im_str!("(dummy menu)")).enabled(false).build();
|
frame.menu_item(im_str!("(dummy menu)")).enabled(false).build();
|
||||||
if frame.menu_item(im_str!("New")).build() { }
|
if frame.menu_item(im_str!("New")).build() { }
|
||||||
if frame.menu_item(im_str!("Open")).shortcut(im_str!("Ctrl+O")).build() { }
|
if frame.menu_item(im_str!("Open")).shortcut(im_str!("Ctrl+O")).build() { }
|
||||||
@ -47,7 +189,7 @@ fn show_example_menu_file<'a>(frame: &Frame<'a>) {
|
|||||||
frame.menu_item(im_str!("Hello"));
|
frame.menu_item(im_str!("Hello"));
|
||||||
frame.menu_item(im_str!("Sailor"));
|
frame.menu_item(im_str!("Sailor"));
|
||||||
frame.menu(im_str!("Recurse..")).build(|| {
|
frame.menu(im_str!("Recurse..")).build(|| {
|
||||||
show_example_menu_file(frame);
|
show_example_menu_file(frame, state);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -55,6 +197,9 @@ fn show_example_menu_file<'a>(frame: &Frame<'a>) {
|
|||||||
if frame.menu_item(im_str!("Save As..")).build() { }
|
if frame.menu_item(im_str!("Save As..")).build() { }
|
||||||
frame.separator();
|
frame.separator();
|
||||||
frame.menu(im_str!("Options")).build(|| {
|
frame.menu(im_str!("Options")).build(|| {
|
||||||
|
if frame.menu_item(im_str!("Enabled")).selected(state.enabled).build() {
|
||||||
|
state.enabled = !state.enabled;
|
||||||
|
}
|
||||||
// TODO
|
// TODO
|
||||||
});
|
});
|
||||||
frame.menu(im_str!("Colors")).build(|| {
|
frame.menu(im_str!("Colors")).build(|| {
|
||||||
@ -66,3 +211,20 @@ fn show_example_menu_file<'a>(frame: &Frame<'a>) {
|
|||||||
if frame.menu_item(im_str!("Checked")).selected(true).build() { }
|
if frame.menu_item(im_str!("Checked")).selected(true).build() { }
|
||||||
if frame.menu_item(im_str!("Quit")).shortcut(im_str!("Alt+F4")).build() { }
|
if frame.menu_item(im_str!("Quit")).shortcut(im_str!("Alt+F4")).build() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn show_example_app_fixed_overlay<'a>(frame: &Frame<'a>) -> bool {
|
||||||
|
frame.window()
|
||||||
|
.name(im_str!("Example: Fixed Overlay"))
|
||||||
|
.closable(true)
|
||||||
|
.bg_alpha(0.3)
|
||||||
|
.title_bar(false)
|
||||||
|
.resizable(false)
|
||||||
|
.movable(false)
|
||||||
|
.save_settings(false)
|
||||||
|
.build(|| {
|
||||||
|
frame.text(im_str!("Simple overlay\non the top-left side of the screen."));
|
||||||
|
frame.separator();
|
||||||
|
let mouse_pos = frame.imgui().mouse_pos();
|
||||||
|
frame.text(im_str!("Mouse Position: ({:.1},{:.1})", mouse_pos.0, mouse_pos.1));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -161,6 +161,13 @@ bitflags!(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl ImGuiWindowFlags {
|
||||||
|
#[inline]
|
||||||
|
pub fn with(self, mask: ImGuiWindowFlags, value: bool) -> ImGuiWindowFlags {
|
||||||
|
if value { self | mask } else { self - mask }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bitflags!(
|
bitflags!(
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
flags ImGuiSetCond: c_int {
|
flags ImGuiSetCond: c_int {
|
||||||
|
|||||||
58
src/lib.rs
58
src/lib.rs
@ -11,16 +11,31 @@ extern crate libc;
|
|||||||
extern crate sdl2;
|
extern crate sdl2;
|
||||||
|
|
||||||
use libc::{c_char, c_float, c_int, c_uchar};
|
use libc::{c_char, c_float, c_int, c_uchar};
|
||||||
use std::marker::PhantomData;
|
use std::borrow::Cow;
|
||||||
|
use std::ffi::CStr;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
pub use ffi::{ImDrawIdx, ImDrawVert, ImGuiWindowFlags, ImVec2, ImVec4};
|
pub use ffi::{
|
||||||
|
ImDrawIdx, ImDrawVert,
|
||||||
|
ImGuiSetCond,
|
||||||
|
ImGuiSetCond_Always, ImGuiSetCond_Once,
|
||||||
|
ImGuiSetCond_FirstUseEver, ImGuiSetCond_Appearing,
|
||||||
|
ImGuiWindowFlags,
|
||||||
|
ImGuiWindowFlags_NoTitleBar, ImGuiWindowFlags_NoResize, ImGuiWindowFlags_NoMove,
|
||||||
|
ImGuiWindowFlags_NoScrollbar, ImGuiWindowFlags_NoScrollWithMouse, ImGuiWindowFlags_NoCollapse,
|
||||||
|
ImGuiWindowFlags_AlwaysAutoResize, ImGuiWindowFlags_ShowBorders,
|
||||||
|
ImGuiWindowFlags_NoSavedSettings, ImGuiWindowFlags_NoInputs, ImGuiWindowFlags_MenuBar,
|
||||||
|
ImVec2, ImVec4
|
||||||
|
};
|
||||||
pub use menus::{Menu, MenuItem};
|
pub use menus::{Menu, MenuItem};
|
||||||
|
pub use window::{Window};
|
||||||
|
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
mod menus;
|
mod menus;
|
||||||
|
mod window;
|
||||||
|
|
||||||
#[cfg(feature = "glium")]
|
#[cfg(feature = "glium")]
|
||||||
pub mod glium_renderer;
|
pub mod glium_renderer;
|
||||||
@ -29,20 +44,30 @@ pub struct ImGui;
|
|||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! im_str {
|
macro_rules! im_str {
|
||||||
($e:expr) => ({
|
($e:tt) => ({
|
||||||
let value = concat!($e, "\0");
|
let value = concat!($e, "\0");
|
||||||
unsafe { ::imgui::ImStr::from_bytes(value.as_bytes()) }
|
unsafe { ::imgui::ImStr::from_bytes(value.as_bytes()) }
|
||||||
});
|
});
|
||||||
|
($e:tt, $($arg:tt)*) => ({
|
||||||
|
::imgui::ImStr::from_str(&format!($e, $($arg)*))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImStr<'a> {
|
pub struct ImStr<'a> {
|
||||||
bytes: &'a [u8]
|
bytes: Cow<'a, [u8]>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ImStr<'a> {
|
impl<'a> ImStr<'a> {
|
||||||
pub unsafe fn from_bytes(bytes: &'a [u8]) -> ImStr<'a> {
|
pub unsafe fn from_bytes(bytes: &'a [u8]) -> ImStr<'a> {
|
||||||
ImStr {
|
ImStr {
|
||||||
bytes: bytes
|
bytes: Cow::Borrowed(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn from_str(value: &str) -> ImStr<'a> {
|
||||||
|
let mut bytes: Vec<u8> = value.bytes().collect();
|
||||||
|
bytes.push(0);
|
||||||
|
ImStr {
|
||||||
|
bytes: Cow::Owned(bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn as_ptr(&self) -> *const c_char { self.bytes.as_ptr() as *const c_char }
|
fn as_ptr(&self) -> *const c_char { self.bytes.as_ptr() as *const c_char }
|
||||||
@ -54,6 +79,13 @@ pub struct TextureHandle<'a> {
|
|||||||
pub pixels: &'a [c_uchar]
|
pub pixels: &'a [c_uchar]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_version() -> &'static str {
|
||||||
|
unsafe {
|
||||||
|
let bytes = CStr::from_ptr(ffi::igGetVersion()).to_bytes();
|
||||||
|
str::from_utf8_unchecked(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ImGui {
|
impl ImGui {
|
||||||
pub fn init() -> ImGui {
|
pub fn init() -> ImGui {
|
||||||
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
||||||
@ -80,6 +112,10 @@ impl ImGui {
|
|||||||
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
||||||
io.mouse_draw_cursor = value;
|
io.mouse_draw_cursor = value;
|
||||||
}
|
}
|
||||||
|
pub fn mouse_pos(&self) -> (f32, f32) {
|
||||||
|
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
||||||
|
(io.mouse_pos.x as f32, io.mouse_pos.y as f32)
|
||||||
|
}
|
||||||
pub fn set_mouse_pos(&mut self, x: f32, y: f32) {
|
pub fn set_mouse_pos(&mut self, x: f32, y: f32) {
|
||||||
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
||||||
io.mouse_pos.x = x;
|
io.mouse_pos.x = x;
|
||||||
@ -89,7 +125,7 @@ impl ImGui {
|
|||||||
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
||||||
io.mouse_down = *states;
|
io.mouse_down = *states;
|
||||||
}
|
}
|
||||||
pub fn frame<'a>(&mut self, width: u32, height: u32, delta_time: f32) -> Frame<'a> {
|
pub fn frame<'fr, 'a: 'fr>(&'a mut self, width: u32, height: u32, delta_time: f32) -> Frame<'fr> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let io: &mut ffi::ImGuiIO = mem::transmute(ffi::igGetIO());
|
let io: &mut ffi::ImGuiIO = mem::transmute(ffi::igGetIO());
|
||||||
io.display_size.x = width as c_float;
|
io.display_size.x = width as c_float;
|
||||||
@ -99,7 +135,7 @@ impl ImGui {
|
|||||||
ffi::igNewFrame();
|
ffi::igNewFrame();
|
||||||
}
|
}
|
||||||
Frame {
|
Frame {
|
||||||
_phantom: PhantomData
|
imgui: self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +172,7 @@ pub struct DrawList<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Frame<'fr> {
|
pub struct Frame<'fr> {
|
||||||
_phantom: PhantomData<&'fr ImGui>
|
imgui: &'fr ImGui
|
||||||
}
|
}
|
||||||
|
|
||||||
static FMT: &'static [u8] = b"%s\0";
|
static FMT: &'static [u8] = b"%s\0";
|
||||||
@ -144,6 +180,7 @@ static FMT: &'static [u8] = b"%s\0";
|
|||||||
fn fmt_ptr() -> *const c_char { FMT.as_ptr() as *const c_char }
|
fn fmt_ptr() -> *const c_char { FMT.as_ptr() as *const c_char }
|
||||||
|
|
||||||
impl<'fr> Frame<'fr> {
|
impl<'fr> Frame<'fr> {
|
||||||
|
pub fn imgui(&self) -> &ImGui { self.imgui }
|
||||||
pub fn render<F, E>(self, mut f: F) -> Result<(), E>
|
pub fn render<F, E>(self, mut f: F) -> Result<(), E>
|
||||||
where F: FnMut(DrawList<'fr>) -> Result<(), E> {
|
where F: FnMut(DrawList<'fr>) -> Result<(), E> {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -173,6 +210,11 @@ impl<'fr> Frame<'fr> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Window
|
||||||
|
impl<'fr> Frame<'fr> {
|
||||||
|
pub fn window<'p>(&self) -> Window<'fr, 'p> { Window::new() }
|
||||||
|
}
|
||||||
|
|
||||||
// Widgets
|
// Widgets
|
||||||
impl<'fr> Frame<'fr> {
|
impl<'fr> Frame<'fr> {
|
||||||
pub fn text<'b>(&self, text: ImStr<'b>) {
|
pub fn text<'b>(&self, text: ImStr<'b>) {
|
||||||
|
|||||||
@ -18,6 +18,7 @@ impl<'fr, 'p> Menu<'fr, 'p> {
|
|||||||
_phantom: PhantomData
|
_phantom: PhantomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
pub fn enabled(self, enabled: bool) -> Self {
|
pub fn enabled(self, enabled: bool) -> Self {
|
||||||
Menu {
|
Menu {
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
@ -51,18 +52,21 @@ impl<'fr, 'p> MenuItem<'fr, 'p> {
|
|||||||
_phantom: PhantomData
|
_phantom: PhantomData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
pub fn shortcut(self, shortcut: ImStr<'p>) -> Self {
|
pub fn shortcut(self, shortcut: ImStr<'p>) -> Self {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
shortcut: Some(shortcut),
|
shortcut: Some(shortcut),
|
||||||
.. self
|
.. self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
pub fn selected(self, selected: bool) -> Self {
|
pub fn selected(self, selected: bool) -> Self {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
selected: selected,
|
selected: selected,
|
||||||
.. self
|
.. self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
pub fn enabled(self, enabled: bool) -> Self {
|
pub fn enabled(self, enabled: bool) -> Self {
|
||||||
MenuItem {
|
MenuItem {
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
|
|||||||
183
src/window.rs
Normal file
183
src/window.rs
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
use libc::c_float;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
use super::ffi;
|
||||||
|
use super::{
|
||||||
|
Frame,
|
||||||
|
ImGuiSetCond,
|
||||||
|
ImGuiWindowFlags,
|
||||||
|
ImGuiWindowFlags_NoTitleBar, ImGuiWindowFlags_NoResize, ImGuiWindowFlags_NoMove,
|
||||||
|
ImGuiWindowFlags_NoScrollbar, ImGuiWindowFlags_NoScrollWithMouse, ImGuiWindowFlags_NoCollapse,
|
||||||
|
ImGuiWindowFlags_AlwaysAutoResize, ImGuiWindowFlags_ShowBorders,
|
||||||
|
ImGuiWindowFlags_NoSavedSettings, ImGuiWindowFlags_NoInputs, ImGuiWindowFlags_MenuBar,
|
||||||
|
ImStr, ImVec2
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Window<'fr, 'p> {
|
||||||
|
pos: (f32, f32),
|
||||||
|
pos_cond: ImGuiSetCond,
|
||||||
|
size: (f32, f32),
|
||||||
|
size_cond: ImGuiSetCond,
|
||||||
|
name: ImStr<'p>,
|
||||||
|
closable: bool,
|
||||||
|
bg_alpha: f32,
|
||||||
|
flags: ImGuiWindowFlags,
|
||||||
|
_phantom: PhantomData<&'fr Frame<'fr>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'fr, 'p> Window<'fr, 'p> {
|
||||||
|
pub fn new() -> Window<'fr, 'p> {
|
||||||
|
Window {
|
||||||
|
pos: (0.0, 0.0),
|
||||||
|
pos_cond: ImGuiSetCond::empty(),
|
||||||
|
size: (0.0, 0.0),
|
||||||
|
size_cond: ImGuiSetCond::empty(),
|
||||||
|
name: unsafe { ImStr::from_bytes(b"Debug\0") },
|
||||||
|
closable: false,
|
||||||
|
bg_alpha: -1.0,
|
||||||
|
flags: ImGuiWindowFlags::empty(),
|
||||||
|
_phantom: PhantomData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn position(self, pos: (f32, f32), cond: ImGuiSetCond) -> Self {
|
||||||
|
Window {
|
||||||
|
pos: pos,
|
||||||
|
pos_cond: cond,
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn size(self, size: (f32, f32), cond: ImGuiSetCond) -> Self {
|
||||||
|
Window {
|
||||||
|
size: size,
|
||||||
|
size_cond: cond,
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn name(self, name: ImStr<'p>) -> Self {
|
||||||
|
Window {
|
||||||
|
name: name,
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn closable(self, closable: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
closable: closable,
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn bg_alpha(self, bg_alpha: f32) -> Self {
|
||||||
|
Window {
|
||||||
|
bg_alpha: bg_alpha,
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn flags(self, flags: ImGuiWindowFlags) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: flags,
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn title_bar(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_NoTitleBar, !value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn resizable(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_NoResize, !value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn movable(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_NoMove, !value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn scroll_bar(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_NoScrollbar, !value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn scrollable(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_NoScrollWithMouse, !value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn collapsible(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_NoCollapse, !value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn always_auto_resize(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_AlwaysAutoResize, value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn show_borders(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_ShowBorders, value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn save_settings(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_NoSavedSettings, !value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn inputs(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_NoInputs, !value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
pub fn menu_bar(self, value: bool) -> Self {
|
||||||
|
Window {
|
||||||
|
flags: self.flags.with(ImGuiWindowFlags_MenuBar, value),
|
||||||
|
.. self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn build<F: FnOnce()>(self, f: F) -> bool {
|
||||||
|
let mut opened = true;
|
||||||
|
let render = unsafe {
|
||||||
|
if !self.pos_cond.is_empty() {
|
||||||
|
ffi::igSetNextWindowPos(ImVec2::new(self.pos.0, self.pos.1), self.pos_cond);
|
||||||
|
}
|
||||||
|
if !self.size_cond.is_empty() {
|
||||||
|
ffi::igSetNextWindowSize(ImVec2::new(self.size.0, self.size.1), self.size_cond);
|
||||||
|
}
|
||||||
|
ffi::igBegin2(self.name.as_ptr(),
|
||||||
|
if self.closable { &mut opened } else { ptr::null_mut() },
|
||||||
|
ImVec2::new(0.0, 0.0), self.bg_alpha as c_float, self.flags
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if render {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
unsafe { ffi::igEnd() };
|
||||||
|
opened
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user