diff --git a/Cargo.toml b/Cargo.toml index 899379c..0da034c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ categories = ["gui", "api-bindings"] [dependencies] implot-sys = { version = "0.1.0", path = "implot-sys" } +bitflags = "1.0" [workspace] diff --git a/README.md b/README.md index ba5e2b1..831253a 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ imgui-rs requires minimum Rust version 1.40, so this project does as well by ext Currently the master branch of imgui-rs is used as a dependency until https://github.com/Gekkio/imgui-rs/pull/339 makes it into a release. -The sys crate compiles imgui, so a C++ compiler will also be required. +The sys crate compiles implot, so a C++ compiler will also be required. ## Status Currently a work in progress. The author is open to collaboration, if you'd like to @@ -19,3 +19,43 @@ help, feel free to reach out via a Github issue. At this point, raw bindings are working in implot-sys, and more idiomatic interfaces for plot creation as well as adding lines to plots are implemented. Everything else is still being built. + +- [x] "BeginPlot" + - [x] Basic hello world + - [x] Plot flags +- [ ] Plotting functionality + - [ ] Line plot + - [x] Single y axis + - [ ] Multiple y axes + - [ ] Scatter plot + - [ ] Bar plot + - [ ] Vertical + - [ ] Horizontal + - [ ] Error bar plot + - [ ] Vertical + - [ ] Horizontal + - [ ] Text + - [ ] Heatmap + - [ ] Pie chart + - [ ] Digital data +- [ ] Plot customization + - [ ] Enums + - [x] Axis flags + - [ ] Markers + - [ ] Styling colors + - [ ] Styling variables + - [ ] Colormaps +- [ ] Plot querying + - [ ] is hovered + - [ ] mouse position + - [ ] mouse limits + - [ ] is queried + - [ ] GetPlotQuery +- [ ] Utils + - [x] Plot limit setting + - [ ] Plot tick setting + - [ ] Plot y axis setting for subsequent elements + - [ ] plot position and size reading + - [ ] Pixel to plot position + - [ ] Plot to pixel position + - [ ] Push/pop plotclip rect (?) diff --git a/implot-examples/examples/hello_world.rs b/implot-examples/examples/hello_world.rs index bdf2774..bf8de18 100644 --- a/implot-examples/examples/hello_world.rs +++ b/implot-examples/examples/hello_world.rs @@ -1,5 +1,5 @@ use imgui::*; -use implot::{Plot, PlotLine}; +use implot::{AxisFlags, Plot, PlotFlags, PlotLine}; mod support; @@ -27,6 +27,8 @@ fn main() { .y_label("awesome y label") .x_limits(0.0, 6.0, Condition::FirstUseEver) .y_limits(-1.0, 3.0, Condition::FirstUseEver) + .with_plot_flags(&(PlotFlags::DEFAULT)) + .with_y_axis_flags(&(AxisFlags::INVERT)) .build(|| { PlotLine::new("Left eye").plot(&vec![2.0, 2.0], &vec![2.0, 1.0]); PlotLine::new("Right eye").plot(&vec![4.0, 4.0], &vec![2.0, 1.0]); diff --git a/src/lib.rs b/src/lib.rs index 9dc85d6..70bcfbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,9 +8,76 @@ //! //! pub extern crate implot_sys as sys; +use bitflags::bitflags; use sys::imgui::im_str; pub use sys::imgui::Condition; +const DEFAULT_PLOT_SIZE_X: f32 = 400.0; +const DEFAULT_PLOT_SIZE_Y: f32 = 400.0; + +bitflags! { + /// Window hover check option flags. Documentation copied from implot.h for convenience. + #[repr(transparent)] + pub struct PlotFlags: u32 { + /// The mouse position, in plot coordinates, will be displayed in the bottom-right + const MOUSE_POSITION = sys::ImPlotFlags__ImPlotFlags_MousePos; + /// A legend will be displayed in the top-left + const LEGEND = sys::ImPlotFlags__ImPlotFlags_Legend; + /// Plot items will be highlighted when their legend entry is hovered + const HIGHLIGHT = sys::ImPlotFlags__ImPlotFlags_Highlight; + /// The user will be able to box-select with right-mouse + const BOX_SELECT = sys::ImPlotFlags__ImPlotFlags_BoxSelect; + /// The user will be able to draw query rects with middle-mouse + const QUERY = sys::ImPlotFlags__ImPlotFlags_Query; + /// The user will be able to open a context menu with double-right click + const CONTEXT_MENU = sys::ImPlotFlags__ImPlotFlags_ContextMenu; + /// The default mouse cursor will be replaced with a crosshair when hovered + const CROSSHAIRS = sys::ImPlotFlags__ImPlotFlags_Crosshairs; + /// Plot data outside the plot area will be culled from rendering + const CULL_DATA = sys::ImPlotFlags__ImPlotFlags_CullData; + /// Lines and fills will be anti-aliased (not recommended) + const ANTIALIASED = sys::ImPlotFlags__ImPlotFlags_AntiAliased; + /// A child window region will not be used to capture mouse scroll (can boost performance + /// for single ImGui window applications) + const NO_CHILD = sys::ImPlotFlags__ImPlotFlags_NoChild; + /// Enable a 2nd y axis + const Y_AXIS_2 = sys::ImPlotFlags__ImPlotFlags_YAxis2; + /// Enable a 3nd y axis + const Y_AXIS_3 = sys::ImPlotFlags__ImPlotFlags_YAxis3; + /// Default selection of flags + const DEFAULT = sys::ImPlotFlags__ImPlotFlags_Default; + } +} + +bitflags! { + /// Axis flags. Documentation copied from implot.h for convenience. + #[repr(transparent)] + pub struct AxisFlags: u32 { + /// Grid lines will be displayed + const GRID_LINES = sys::ImPlotAxisFlags__ImPlotAxisFlags_GridLines; + /// Tick marks will be displayed for each grid line + const TICK_MARKS = sys::ImPlotAxisFlags__ImPlotAxisFlags_TickMarks; + /// Text labels will be displayed for each grid line + const TICK_LABELS = sys::ImPlotAxisFlags__ImPlotAxisFlags_TickLabels; + /// The axis will be inverted + const INVERT = sys::ImPlotAxisFlags__ImPlotAxisFlags_Invert; + /// The axis minimum value will be locked when panning/zooming + const LOCK_MIN = sys::ImPlotAxisFlags__ImPlotAxisFlags_LockMin; + /// The axis maximum value will be locked when panning/zooming + const LOCK_MAX = sys::ImPlotAxisFlags__ImPlotAxisFlags_LockMax; + /// Grid divisions will adapt to the current pixel size the axis + const ADAPTIVE = sys::ImPlotAxisFlags__ImPlotAxisFlags_Adaptive; + /// A logartithmic (base 10) axis scale will be used + const LOG_SCALE = sys::ImPlotAxisFlags__ImPlotAxisFlags_LogScale; + /// Scientific notation will be used for tick labels if displayed (WIP, not very good yet) + const SCIENTIFIC = sys::ImPlotAxisFlags__ImPlotAxisFlags_Scientific; + /// Default set of flags + const DEFAULT = sys::ImPlotAxisFlags__ImPlotAxisFlags_Default; + /// Same as defaults, but without grid lines + const AUXILIARY = sys::ImPlotAxisFlags__ImPlotAxisFlags_Auxiliary; + } +} + /// Struct to represent an ImPlot. This is the main construct used to contain all kinds of plots in ImPlot. /// /// `Plot` is to be used (within an imgui window) with the following pattern: @@ -50,12 +117,12 @@ pub struct Plot { 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, + /// Flags relating to the third y axis of the plot (if present, otherwise ignored) + /// TODO(4bb4) make those into bitflags + y3_flags: sys::ImPlotAxisFlags, } impl Plot { @@ -64,19 +131,19 @@ impl Plot { // TODO(4bb4) question these defaults, maybe remove some of them Self { title: title.to_owned(), - size_x: 400.0, - size_y: 400.0, + size_x: DEFAULT_PLOT_SIZE_X, + size_y: DEFAULT_PLOT_SIZE_Y, x_label: "".to_owned(), y_label: "".to_owned(), x_limits: None, y_limits: None, x_limit_condition: None, y_limit_condition: None, - plot_flags: 0xFF, // TODO(4bb4) define the defaults better - x_flags: 7, // TODO(4bb4) define the defaults better - y_flags: 7, // TODO(4bb4) define the defaults better - x2_flags: 0, // TODO(4bb4) define the defaults better - y2_flags: 0, // TODO(4bb4) define the defaults better + plot_flags: PlotFlags::DEFAULT.bits() as sys::ImPlotFlags, + x_flags: AxisFlags::DEFAULT.bits() as sys::ImPlotAxisFlags, + y_flags: AxisFlags::DEFAULT.bits() as sys::ImPlotAxisFlags, + y2_flags: AxisFlags::DEFAULT.bits() as sys::ImPlotAxisFlags, + y3_flags: AxisFlags::DEFAULT.bits() as sys::ImPlotAxisFlags, } } @@ -119,6 +186,41 @@ impl Plot { self } + /// Set the plot flags, see the help for `PlotFlags` for what the available flags are + #[inline] + pub fn with_plot_flags(mut self, flags: &PlotFlags) -> Self { + self.plot_flags = flags.bits() as sys::ImPlotFlags; + self + } + + /// Set the axis flags for the X axis in this plot + #[inline] + pub fn with_x_axis_flags(mut self, flags: &AxisFlags) -> Self { + self.x_flags = flags.bits() as sys::ImPlotAxisFlags; + self + } + + /// Set the axis flags for the first Y axis in this plot + #[inline] + pub fn with_y_axis_flags(mut self, flags: &AxisFlags) -> Self { + self.y_flags = flags.bits() as sys::ImPlotAxisFlags; + self + } + + /// Set the axis flags for the second Y axis in this plot + #[inline] + pub fn with_y2_axis_flags(mut self, flags: &AxisFlags) -> Self { + self.y2_flags = flags.bits() as sys::ImPlotAxisFlags; + self + } + + /// Set the axis flags for the third Y axis in this plot + #[inline] + pub fn with_y3_axis_flags(mut self, flags: &AxisFlags) -> Self { + self.y3_flags = flags.bits() as sys::ImPlotAxisFlags; + self + } + /// Attempt to show the plot. If this returns a token, the plot will actually /// be drawn. In this case, use the drawing functionality to draw things on the /// plot, and then call `end()` on the token when done with the plot. @@ -155,8 +257,8 @@ impl Plot { self.plot_flags, self.x_flags, self.y_flags, - self.x2_flags, self.y2_flags, + self.y3_flags, ) };