From ee910152b72c18db9d1fc8c181e5bf3e6c99816b Mon Sep 17 00:00:00 2001 From: 4bb4 <67376761+4bb4@users.noreply.github.com> Date: Tue, 4 Aug 2020 22:05:04 +0200 Subject: [PATCH] Added main crate and some initial code for idiomatic bindings --- Cargo.toml | 23 +++++++++++ implot-sys/Cargo.toml | 2 + implot-sys/src/lib.rs | 2 + src/lib.rs | 92 +++++++++++++++++++++++++++++++++++++++++ testexample/Cargo.toml | 1 + testexample/src/main.rs | 53 +++++------------------- 6 files changed, 130 insertions(+), 43 deletions(-) create mode 100644 Cargo.toml create mode 100644 src/lib.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..bcf27f4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "implot" +version = "0.1.0" +edition = "2018" +authors = ["Sandro Merkli", "implot-rs contributors"] +description = "High-level Rust bindings to implot" +homepage = "https://github.com/4bb4/implot-rs" +repository = "https://github.com/4bb4/implot-rs" +license = "MIT/Apache-2.0" +categories = ["gui", "api-bindings"] + +[dependencies] +implot-sys = { version = "0.1.0", path = "implot-sys" } + + +[workspace] +members = [ + "implot-sys", +] +exclude = [ + "implot-sys-bindgen", + "testexample", +] diff --git a/implot-sys/Cargo.toml b/implot-sys/Cargo.toml index b3aa8fe..fa6c98b 100644 --- a/implot-sys/Cargo.toml +++ b/implot-sys/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" edition = "2018" authors = ["Sandro Merkli", "implot-rs contributors"] description = "Raw FFI bindings to implot" +homepage = "https://github.com/4bb4/implot-rs" +repository = "https://github.com/4bb4/implot-rs" license = "MIT/Apache-2.0" categories = ["gui", "external-ffi-bindings"] build = "build.rs" diff --git a/implot-sys/src/lib.rs b/implot-sys/src/lib.rs index dad9d32..29aba43 100644 --- a/implot-sys/src/lib.rs +++ b/implot-sys/src/lib.rs @@ -2,4 +2,6 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] +pub use imgui; + include!("bindings.rs"); diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..6fbf772 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,92 @@ +//! # Rust bindings to ImPlot +//! +//! This crate contains idiomatic bindings to the C++ implot library, which +//! use the bindings exposed by the `implot-sys` crate. +pub extern crate implot_sys as sys; +use sys::imgui::im_str; + +/// Struct to represent an ImPlot. +pub struct Plot { + /// Title of the plot, shown on top. + title: String, + /// Label of the x axis, shown on the bottom + x_label: String, + /// Label of the y axis, shown on the left + y_label: String, + /// Size of the plot in x direction, in pixels. + size_x: u32, + /// Size of the plot in y direction, in pixels. + size_y: u32, + /// Flags relating to the plot TODO(4bb4) make those into bitflags + plot_flags: sys::ImPlotFlags, + /// Flags relating to the first x axis of the plot TODO(4bb4) make those into bitflags + x_flags: sys::ImPlotAxisFlags, + /// Flags relating to the first y axis of the plot TODO(4bb4) make those into bitflags + y_flags: sys::ImPlotAxisFlags, + /// Flags relating to the second x axis of the plot (if present, otherwise ignored) + /// TODO(4bb4) make those into bitflags + x2_flags: sys::ImPlotAxisFlags, + /// Flags relating to the second y axis of the plot (if present, otherwise ignored) + /// TODO(4bb4) make those into bitflags + y2_flags: sys::ImPlotAxisFlags, +} + +impl Plot { + /// Create a new plot with some defaults set. Does not draw anything yet. + pub fn new() -> Self { + // TODO(4bb4) question these defaults, maybe remove some of them + Self { + title: "".to_owned(), + x_label: "".to_owned(), + y_label: "".to_owned(), + size_x: 400, + size_y: 400, + plot_flags: 0xFF, + x_flags: 7, + y_flags: 7, + x2_flags: 0, + y2_flags: 0, + } + } + + /// Attempt to show the plot. Only do things with it and call `end()` after that + /// if this returns `true`. + pub fn begin(&self) -> bool { + unsafe { + sys::ImPlot_BeginPlot( + im_str!("{}", self.title).as_ptr(), + im_str!("{}", self.x_label).as_ptr(), + im_str!("{}", self.y_label).as_ptr(), + sys::ImVec2 { + x: self.size_x as f32, + y: self.size_y as f32, + }, + self.plot_flags, + self.x_flags, + self.y_flags, + self.x2_flags, + self.y2_flags, + ) + } + } + + /// End a previously-`begin()`ed plot. Only call if `begin()` returned `true`. + pub fn end(&self) { + unsafe { sys::ImPlot_EndPlot() } + } +} + +// TODO(4bb4) convert to struct and add methods to set title and flags +/// Plot a line. Use this between Plot::begin() and Plot::end(). +pub fn plot_line(x: &Vec, y: &Vec, label: &str) { + unsafe { + implot_sys::ImPlot_PlotLinedoublePtrdoublePtr( + im_str!("{}", label).as_ptr() as *const i8, + x.as_ptr(), + y.as_ptr(), + x.len().min(y.len()) as i32, // "as" casts saturate as of Rust 1.45 + 0, + 8, + ); + } +} diff --git a/testexample/Cargo.toml b/testexample/Cargo.toml index 4d13a1c..d2e28d8 100644 --- a/testexample/Cargo.toml +++ b/testexample/Cargo.toml @@ -19,3 +19,4 @@ imgui-glium-renderer = { git = "https://github.com/Gekkio/imgui-rs/", branch = " imgui-winit-support = { git = "https://github.com/Gekkio/imgui-rs/", branch = "master" } implot-sys = { path = "../implot-sys" } +implot = { path = "../" } diff --git a/testexample/src/main.rs b/testexample/src/main.rs index ba751dc..72f04bd 100644 --- a/testexample/src/main.rs +++ b/testexample/src/main.rs @@ -1,5 +1,5 @@ use imgui::*; -use implot_sys; +use implot; mod support; @@ -19,48 +19,15 @@ fn main() { mouse_pos[0], mouse_pos[1] )); - // TODO(4bb4) Replace this with safe bindings once those are written - - let x_values: [f64; 4] = [1.0, 2.0, 4.0, 5.0]; - let y_values: [f64; 4] = [1.0, 0.0, 0.0, 1.0]; - unsafe { - if implot_sys::ImPlot_BeginPlot( - im_str!("My Plot").as_ptr() as *const i8, - im_str!("x").as_ptr() as *const i8, - im_str!("y").as_ptr() as *const i8, - implot_sys::ImVec2 { x: 600.0, y: 600.0 }, - 0xFF, - 7, - 7, - 0, - 0, - ) { - implot_sys::ImPlot_PlotLinedoublePtrdoublePtr( - im_str!("Mouth").as_ptr() as *const i8, - x_values.as_ptr(), - y_values.as_ptr(), - x_values.len() as i32, - 0, - 8, - ); - implot_sys::ImPlot_PlotLinedoublePtrdoublePtr( - im_str!("Left eye").as_ptr() as *const i8, - [2.0, 2.0].as_ptr(), - [2.0, 1.0].as_ptr(), - 2i32, - 0, - 8, - ); - implot_sys::ImPlot_PlotLinedoublePtrdoublePtr( - im_str!("Right eye").as_ptr() as *const i8, - [4.0, 4.0].as_ptr(), - [2.0, 1.0].as_ptr(), - 2i32, - 0, - 8, - ); - implot_sys::ImPlot_EndPlot(); - } + // Demo some implot stuff :D + let x_values = vec![1.0, 2.0, 4.0, 5.0]; + let y_values = vec![1.0, 0.0, 0.0, 1.0]; + let plot = implot::Plot::new(); + if plot.begin() { + implot::plot_line(&vec![2.0, 2.0], &vec![2.0, 1.0], "Left eye"); + implot::plot_line(&vec![4.0, 4.0], &vec![2.0, 1.0], "Right eye"); + implot::plot_line(&x_values, &y_values, "Mouth"); + plot.end(); } }); });