summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs75
-rw-r--r--src/support/clipboard.rs17
-rw-r--r--src/support/mod.rs141
3 files changed, 233 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..df1a475
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,75 @@
+use imgui::*;
+use rlua::{Lua, MultiValue};
+
+mod support;
+
+#[derive(Default)]
+struct State {
+ lua: Lua,
+ console: Vec<ImString>,
+ repl_input: ImString,
+}
+
+impl State {
+ fn new() -> State {
+ State {
+ lua: Lua::new(),
+ console: Vec::new(),
+ repl_input: ImString::with_capacity(256),
+ }
+ }
+}
+
+fn draw_console(_run: &mut bool, ui: &mut Ui, state: &mut State) {
+ let win = Window::new(im_str!("Lua Console")).size([400., 500.], Condition::Appearing);
+
+ win.build(&ui, || {
+ ChildWindow::new("console")
+ .size([0., 400.])
+ .scrollable(true)
+ .build(&ui, || {
+ for line in &state.console {
+ ui.text(line);
+ }
+ });
+
+ ui.separator();
+ ui.input_text(im_str!("Lua"), &mut state.repl_input).build();
+ ui.same_line(350.);
+ if ui.button(im_str!("Eval"), [0., 0.]) {
+ let input = state.repl_input.to_str().clone();
+ let mut new_text = String::new();
+
+ state.lua.context(|ctx| {
+ match ctx.load(input).eval::<MultiValue>() {
+ Ok(values) => {
+ new_text.push_str(
+ &values
+ .iter()
+ .map(|value| format!("{:?}", value))
+ .collect::<Vec<_>>()
+ .join("\t"),
+ );
+ }
+ Err(e) => {
+ new_text.push_str(&e.to_string());
+ }
+ };
+ });
+
+ state.console.push(ImString::new(format!("> {}", input)));
+ state.console.push(ImString::new(new_text));
+ state.repl_input.clear();
+ }
+ });
+}
+
+fn main() {
+ let system = support::init(file!());
+ let mut state = State::new();
+
+ system.main_loop(move |run, ui| {
+ ui.show_demo_window(run);
+ draw_console(run, ui, &mut state);
+ });
+}
diff --git a/src/support/clipboard.rs b/src/support/clipboard.rs
new file mode 100644
index 0000000..d970b29
--- /dev/null
+++ b/src/support/clipboard.rs
@@ -0,0 +1,17 @@
+use clipboard::{ClipboardContext, ClipboardProvider};
+use imgui::{ClipboardBackend, ImStr, ImString};
+
+pub struct ClipboardSupport(ClipboardContext);
+
+pub fn init() -> Option<ClipboardSupport> {
+ ClipboardContext::new().ok().map(ClipboardSupport)
+}
+
+impl ClipboardBackend for ClipboardSupport {
+ fn get(&mut self) -> Option<ImString> {
+ self.0.get_contents().ok().map(|text| text.into())
+ }
+ fn set(&mut self, text: &ImStr) {
+ let _ = self.0.set_contents(text.to_str().to_owned());
+ }
+}
diff --git a/src/support/mod.rs b/src/support/mod.rs
new file mode 100644
index 0000000..af894ba
--- /dev/null
+++ b/src/support/mod.rs
@@ -0,0 +1,141 @@
+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 imgui::{Context, FontConfig, FontGlyphRanges, FontSource, Ui};
+use imgui_glium_renderer::Renderer;
+use imgui_winit_support::{HiDpiMode, WinitPlatform};
+use std::path::Path;
+use std::time::Instant;
+
+mod clipboard;
+
+pub struct System {
+ pub event_loop: EventLoop<()>,
+ pub display: glium::Display,
+ pub imgui: Context,
+ pub platform: WinitPlatform,
+ pub renderer: Renderer,
+ pub font_size: f32,
+}
+
+pub fn init(title: &str) -> System {
+ let title = match Path::new(&title).file_name() {
+ Some(file_name) => file_name.to_str().unwrap(),
+ None => title,
+ };
+ let event_loop = EventLoop::new();
+ let context = glutin::ContextBuilder::new().with_vsync(true);
+ 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");
+
+ let mut imgui = Context::create();
+ imgui.set_ini_filename(None);
+
+ if let Some(backend) = clipboard::init() {
+ imgui.set_clipboard_backend(Box::new(backend));
+ } else {
+ eprintln!("Failed to initialize clipboard");
+ }
+
+ let mut platform = WinitPlatform::init(&mut imgui);
+ {
+ let gl_window = display.gl_window();
+ let window = gl_window.window();
+ platform.attach_window(imgui.io_mut(), window, HiDpiMode::Rounded);
+ }
+
+ let hidpi_factor = platform.hidpi_factor();
+ let font_size = (13.0 * hidpi_factor) as f32;
+
+ // imgui.fonts().add_font(&[
+ // FontSource::DefaultFontData {
+ // config: Some(FontConfig {
+ // size_pixels: font_size,
+ // ..FontConfig::default()
+ // }),
+ // },
+ // FontSource::TtfData {
+ // data: include_bytes!("../../../resources/mplus-1p-regular.ttf"),
+ // size_pixels: font_size,
+ // config: Some(FontConfig {
+ // rasterizer_multiply: 1.75,
+ // glyph_ranges: FontGlyphRanges::japanese(),
+ // ..FontConfig::default()
+ // }),
+ // },
+ // ]);
+
+ imgui.io_mut().font_global_scale = (1.0 / hidpi_factor) as f32;
+
+ let renderer = Renderer::init(&mut imgui, &display).expect("Failed to initialize renderer");
+
+ System {
+ event_loop,
+ display,
+ imgui,
+ platform,
+ renderer,
+ font_size,
+ }
+}
+
+impl System {
+ pub fn main_loop<F: FnMut(&mut bool, &mut Ui) + 'static>(self, mut run_ui: F) {
+ let System {
+ event_loop,
+ display,
+ mut imgui,
+ mut platform,
+ mut renderer,
+ ..
+ } = self;
+ let mut last_frame = Instant::now();
+
+ event_loop.run(move |event, _, control_flow| 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();
+ platform
+ .prepare_frame(imgui.io_mut(), gl_window.window())
+ .expect("Failed to prepare frame");
+ gl_window.window().request_redraw();
+ }
+ Event::RedrawRequested(_) => {
+ let mut ui = imgui.frame();
+
+ let mut run = true;
+ run_ui(&mut run, &mut ui);
+ if !run {
+ *control_flow = ControlFlow::Exit;
+ }
+
+ let gl_window = display.gl_window();
+ let mut target = display.draw();
+ target.clear_color_srgb(0.7, 0.7, 0.7, 0.7);
+ platform.prepare_render(&ui, gl_window.window());
+ let draw_data = ui.render();
+ renderer
+ .render(&mut target, draw_data)
+ .expect("Rendering failed");
+ target.finish().expect("Failed to swap buffers");
+ }
+ Event::WindowEvent {
+ event: WindowEvent::CloseRequested,
+ ..
+ } => *control_flow = ControlFlow::Exit,
+ event => {
+ let gl_window = display.gl_window();
+ platform.handle_event(imgui.io_mut(), gl_window.window(), &event);
+ }
+ })
+ }
+}