mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 21:48:36 +00:00
API changes + additions
This commit is contained in:
parent
e261db71ba
commit
8bf34e8ced
@ -1,55 +1,80 @@
|
||||
use glium::{DisplayBuild, Surface};
|
||||
use glium::backend::glutin_backend::GlutinFacade;
|
||||
use glium::glutin;
|
||||
use glium::glutin::{ElementState, Event, MouseButton, VirtualKeyCode};
|
||||
use imgui::{ImGui, Frame};
|
||||
use imgui::glium_renderer::Renderer;
|
||||
use time::SteadyTime;
|
||||
|
||||
pub fn main_with_frame<'a, F: Fn(&Frame<'a>)>(f: F) {
|
||||
let display = glutin::WindowBuilder::new()
|
||||
.build_glium()
|
||||
.unwrap();
|
||||
pub struct Support {
|
||||
display: GlutinFacade,
|
||||
imgui: ImGui,
|
||||
renderer: Renderer,
|
||||
last_frame: SteadyTime,
|
||||
mouse_pos: (i32, i32),
|
||||
mouse_pressed: (bool, bool, bool)
|
||||
}
|
||||
|
||||
let mut imgui = ImGui::init();
|
||||
let mut renderer = Renderer::init(&mut imgui, &display).unwrap();
|
||||
impl Support {
|
||||
pub fn init() -> Support {
|
||||
let display = glutin::WindowBuilder::new()
|
||||
.build_glium()
|
||||
.unwrap();
|
||||
|
||||
let mut last_frame = SteadyTime::now();
|
||||
let mut mouse_pos = (0, 0);
|
||||
let mut mouse_pressed = (false, false, false);
|
||||
let mut imgui = ImGui::init();
|
||||
let renderer = Renderer::init(&mut imgui, &display).unwrap();
|
||||
|
||||
'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 delta = now - last_frame;
|
||||
let delta = now - self.last_frame;
|
||||
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);
|
||||
imgui.set_mouse_down(&[mouse_pressed.0, mouse_pressed.1, mouse_pressed.2, false, false]);
|
||||
self.update_mouse();
|
||||
|
||||
let mut target = display.draw();
|
||||
target.clear_color(1.0, 1.0, 1.0, 1.0);
|
||||
let mut target = self.display.draw();
|
||||
target.clear_color(clear_color.0, clear_color.1,
|
||||
clear_color.2, clear_color.3);
|
||||
|
||||
let (width, height) = target.get_dimensions();
|
||||
let frame = imgui.frame(width, height, delta_f);
|
||||
f(&frame);
|
||||
renderer.render(&mut target, frame).unwrap();
|
||||
let frame = self.imgui.frame(width, height, delta_f);
|
||||
result = f(&frame);
|
||||
self.renderer.render(&mut target, frame).unwrap();
|
||||
|
||||
target.finish().unwrap();
|
||||
|
||||
for event in display.poll_events() {
|
||||
for event in self.display.poll_events() {
|
||||
match event {
|
||||
Event::Closed |
|
||||
Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Escape))
|
||||
=> break 'main,
|
||||
Event::MouseMoved(pos) => mouse_pos = pos,
|
||||
Event::MouseInput(state, MouseButton::Left) =>
|
||||
mouse_pressed.0 = state == ElementState::Pressed,
|
||||
Event::MouseInput(state, MouseButton::Right) =>
|
||||
mouse_pressed.1 = state == ElementState::Pressed,
|
||||
Event::MouseInput(state, MouseButton::Middle) =>
|
||||
mouse_pressed.2 = state == ElementState::Pressed,
|
||||
_ => ()
|
||||
=> result = false,
|
||||
Event::MouseMoved(pos) => self.mouse_pos = pos,
|
||||
Event::MouseInput(state, MouseButton::Left) =>
|
||||
self.mouse_pressed.0 = state == ElementState::Pressed,
|
||||
Event::MouseInput(state, MouseButton::Right) =>
|
||||
self.mouse_pressed.1 = state == ElementState::Pressed,
|
||||
Event::MouseInput(state, MouseButton::Middle) =>
|
||||
self.mouse_pressed.2 = state == ElementState::Pressed,
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,24 +4,166 @@ extern crate glium;
|
||||
extern crate imgui;
|
||||
extern crate time;
|
||||
|
||||
use imgui::Frame;
|
||||
use imgui::*;
|
||||
|
||||
use self::support::Support;
|
||||
|
||||
mod support;
|
||||
|
||||
fn main() {
|
||||
// let mut show_app_metrics = false;
|
||||
let show_app_main_menu_bar = true;
|
||||
|
||||
support::main_with_frame(|frame| {
|
||||
// if show_app_metrics { show_metrics_window(&mut show_app_metrics) }
|
||||
if show_app_main_menu_bar { show_example_app_main_menu_bar(frame) }
|
||||
});
|
||||
struct State {
|
||||
clear_color: (f32, f32, f32, f32),
|
||||
show_app_metrics: bool,
|
||||
show_app_main_menu_bar: bool,
|
||||
show_app_console: bool,
|
||||
show_app_layout: bool,
|
||||
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.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(|| {
|
||||
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();
|
||||
if frame.menu_item(im_str!("New")).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!("Sailor"));
|
||||
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() { }
|
||||
frame.separator();
|
||||
frame.menu(im_str!("Options")).build(|| {
|
||||
if frame.menu_item(im_str!("Enabled")).selected(state.enabled).build() {
|
||||
state.enabled = !state.enabled;
|
||||
}
|
||||
// TODO
|
||||
});
|
||||
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!("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!(
|
||||
#[repr(C)]
|
||||
flags ImGuiSetCond: c_int {
|
||||
|
||||
58
src/lib.rs
58
src/lib.rs
@ -11,16 +11,31 @@ extern crate libc;
|
||||
extern crate sdl2;
|
||||
|
||||
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::ptr;
|
||||
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 window::{Window};
|
||||
|
||||
pub mod ffi;
|
||||
mod menus;
|
||||
mod window;
|
||||
|
||||
#[cfg(feature = "glium")]
|
||||
pub mod glium_renderer;
|
||||
@ -29,20 +44,30 @@ pub struct ImGui;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! im_str {
|
||||
($e:expr) => ({
|
||||
($e:tt) => ({
|
||||
let value = concat!($e, "\0");
|
||||
unsafe { ::imgui::ImStr::from_bytes(value.as_bytes()) }
|
||||
});
|
||||
($e:tt, $($arg:tt)*) => ({
|
||||
::imgui::ImStr::from_str(&format!($e, $($arg)*))
|
||||
})
|
||||
}
|
||||
|
||||
pub struct ImStr<'a> {
|
||||
bytes: &'a [u8]
|
||||
bytes: Cow<'a, [u8]>
|
||||
}
|
||||
|
||||
impl<'a> ImStr<'a> {
|
||||
pub unsafe fn from_bytes(bytes: &'a [u8]) -> ImStr<'a> {
|
||||
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 }
|
||||
@ -54,6 +79,13 @@ pub struct TextureHandle<'a> {
|
||||
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 {
|
||||
pub fn init() -> ImGui {
|
||||
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()) };
|
||||
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) {
|
||||
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
||||
io.mouse_pos.x = x;
|
||||
@ -89,7 +125,7 @@ impl ImGui {
|
||||
let io: &mut ffi::ImGuiIO = unsafe { mem::transmute(ffi::igGetIO()) };
|
||||
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 {
|
||||
let io: &mut ffi::ImGuiIO = mem::transmute(ffi::igGetIO());
|
||||
io.display_size.x = width as c_float;
|
||||
@ -99,7 +135,7 @@ impl ImGui {
|
||||
ffi::igNewFrame();
|
||||
}
|
||||
Frame {
|
||||
_phantom: PhantomData
|
||||
imgui: self
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,7 +172,7 @@ pub struct DrawList<'a> {
|
||||
}
|
||||
|
||||
pub struct Frame<'fr> {
|
||||
_phantom: PhantomData<&'fr ImGui>
|
||||
imgui: &'fr ImGui
|
||||
}
|
||||
|
||||
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 }
|
||||
|
||||
impl<'fr> Frame<'fr> {
|
||||
pub fn imgui(&self) -> &ImGui { self.imgui }
|
||||
pub fn render<F, E>(self, mut f: F) -> Result<(), E>
|
||||
where F: FnMut(DrawList<'fr>) -> Result<(), E> {
|
||||
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
|
||||
impl<'fr> Frame<'fr> {
|
||||
pub fn text<'b>(&self, text: ImStr<'b>) {
|
||||
|
||||
@ -18,6 +18,7 @@ impl<'fr, 'p> Menu<'fr, 'p> {
|
||||
_phantom: PhantomData
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn enabled(self, enabled: bool) -> Self {
|
||||
Menu {
|
||||
enabled: enabled,
|
||||
@ -51,18 +52,21 @@ impl<'fr, 'p> MenuItem<'fr, 'p> {
|
||||
_phantom: PhantomData
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn shortcut(self, shortcut: ImStr<'p>) -> Self {
|
||||
MenuItem {
|
||||
shortcut: Some(shortcut),
|
||||
.. self
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn selected(self, selected: bool) -> Self {
|
||||
MenuItem {
|
||||
selected: selected,
|
||||
.. self
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn enabled(self, enabled: bool) -> Self {
|
||||
MenuItem {
|
||||
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