Added plot <-> pixel coordinate conversions
This commit is contained in:
parent
4645414624
commit
7c477ec551
3 changed files with 131 additions and 26 deletions
|
@ -93,12 +93,12 @@ created for 64-bit floats.
|
||||||
- [x] Plot limit setting
|
- [x] Plot limit setting
|
||||||
- [x] imgui-rs style safe push/pop stacks
|
- [x] imgui-rs style safe push/pop stacks
|
||||||
- [x] Plot tick setting
|
- [x] Plot tick setting
|
||||||
- [ ] Input remapping
|
- [x] Pixel to plot position
|
||||||
|
- [x] Plot to pixel position
|
||||||
- [x] Set Y axis setting for subsequent elements
|
- [x] Set Y axis setting for subsequent elements
|
||||||
|
- [ ] Input remapping
|
||||||
- [ ] Set non-default Y axis ticks and labels
|
- [ ] Set non-default Y axis ticks and labels
|
||||||
- [ ] Plot position and size reading
|
- [ ] Plot position and size reading
|
||||||
- [ ] Pixel to plot position
|
|
||||||
- [ ] Plot to pixel position
|
|
||||||
- [ ] Push/pop plotclip rect (?)
|
- [ ] Push/pop plotclip rect (?)
|
||||||
|
|
||||||
# Developer documentation
|
# Developer documentation
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
use imgui::{im_str, CollapsingHeader, Condition, Ui, Window};
|
use imgui::{im_str, CollapsingHeader, Condition, Ui, Window};
|
||||||
use implot::{
|
use implot::{
|
||||||
get_plot_limits, get_plot_mouse_position, get_plot_query, is_plot_hovered, is_plot_queried,
|
get_plot_limits, get_plot_mouse_position, get_plot_query, is_plot_hovered, is_plot_queried,
|
||||||
push_style_color, push_style_var_f32, push_style_var_i32, set_colormap_from_preset,
|
pixels_to_plot_vec2, plot_to_pixels_vec2, push_style_color, push_style_var_f32,
|
||||||
set_colormap_from_vec, set_plot_y_axis, AxisFlags, Colormap, ImPlotLimits, ImPlotPoint,
|
push_style_var_i32, set_colormap_from_preset, set_colormap_from_vec, set_plot_y_axis,
|
||||||
ImPlotRange, ImVec4, Marker, Plot, PlotColorElement, PlotFlags, PlotLine, PlotLocation,
|
AxisFlags, Colormap, ImPlotLimits, ImPlotPoint, ImPlotRange, ImVec2, ImVec4, Marker, Plot,
|
||||||
PlotOrientation, PlotUi, StyleVar, YAxisChoice,
|
PlotColorElement, PlotFlags, PlotLine, PlotLocation, PlotOrientation, PlotUi, StyleVar,
|
||||||
|
YAxisChoice,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn show_basic_plot(ui: &Ui, plot_ui: &PlotUi) {
|
pub fn show_basic_plot(ui: &Ui, plot_ui: &PlotUi) {
|
||||||
|
@ -134,7 +135,9 @@ pub fn show_query_features_plot(ui: &Ui, plot_ui: &PlotUi) {
|
||||||
let content_width = ui.window_content_region_width();
|
let content_width = ui.window_content_region_width();
|
||||||
|
|
||||||
// Create some containers for exfiltrating data from the closure below
|
// Create some containers for exfiltrating data from the closure below
|
||||||
let mut hover_pos: Option<ImPlotPoint> = None;
|
let mut hover_pos_plot: Option<ImPlotPoint> = None;
|
||||||
|
let mut hover_pos_pixels: Option<ImVec2> = None;
|
||||||
|
let mut hover_pos_from_pixels: Option<ImPlotPoint> = None;
|
||||||
let mut plot_limits: Option<ImPlotLimits> = None;
|
let mut plot_limits: Option<ImPlotLimits> = None;
|
||||||
let mut query_limits: Option<ImPlotLimits> = None;
|
let mut query_limits: Option<ImPlotLimits> = None;
|
||||||
|
|
||||||
|
@ -150,9 +153,20 @@ pub fn show_query_features_plot(ui: &Ui, plot_ui: &PlotUi) {
|
||||||
.with_plot_flags(&(PlotFlags::NONE | PlotFlags::QUERY))
|
.with_plot_flags(&(PlotFlags::NONE | PlotFlags::QUERY))
|
||||||
.build(plot_ui, || {
|
.build(plot_ui, || {
|
||||||
if is_plot_hovered() {
|
if is_plot_hovered() {
|
||||||
hover_pos = Some(get_plot_mouse_position(None));
|
hover_pos_plot = Some(get_plot_mouse_position(None));
|
||||||
|
hover_pos_pixels = Some(plot_to_pixels_vec2(&(hover_pos_plot.unwrap()), None));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Getting the plot position from pixels also works when the plot is not hovered,
|
||||||
|
// the coordinates are then simply outside the visible range.
|
||||||
|
hover_pos_from_pixels = Some(pixels_to_plot_vec2(
|
||||||
|
&ImVec2 {
|
||||||
|
x: ui.io().mouse_pos[0],
|
||||||
|
y: ui.io().mouse_pos[1],
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
|
||||||
if is_plot_queried() {
|
if is_plot_queried() {
|
||||||
query_limits = Some(get_plot_query(None));
|
query_limits = Some(get_plot_query(None));
|
||||||
}
|
}
|
||||||
|
@ -162,15 +176,33 @@ pub fn show_query_features_plot(ui: &Ui, plot_ui: &PlotUi) {
|
||||||
// Print some previously-exfiltrated info. This is because calling
|
// Print some previously-exfiltrated info. This is because calling
|
||||||
// things like is_plot_hovered or get_plot_mouse_position() outside
|
// things like is_plot_hovered or get_plot_mouse_position() outside
|
||||||
// of an actual Plot is not allowed.
|
// of an actual Plot is not allowed.
|
||||||
if let Some(pos) = hover_pos {
|
if let Some(pos) = hover_pos_plot {
|
||||||
ui.text(im_str!("hovered at {}, {}", pos.x, pos.y));
|
ui.text(im_str!("hovered at {}, {}", pos.x, pos.y));
|
||||||
}
|
}
|
||||||
|
if let Some(pixel_position) = hover_pos_pixels {
|
||||||
|
// Try out converting plot mouse position to pixel position
|
||||||
|
ui.text(im_str!(
|
||||||
|
"pixel pos from plot: {}, {}",
|
||||||
|
pixel_position.x,
|
||||||
|
pixel_position.y
|
||||||
|
));
|
||||||
|
ui.text(im_str!(
|
||||||
|
"pixel pos from imgui: {}, {}",
|
||||||
|
ui.io().mouse_pos[0],
|
||||||
|
ui.io().mouse_pos[1]
|
||||||
|
));
|
||||||
|
}
|
||||||
if let Some(limits) = plot_limits {
|
if let Some(limits) = plot_limits {
|
||||||
ui.text(im_str!("Plot limits are {:#?}", limits));
|
ui.text(im_str!("Plot limits are {:#?}", limits));
|
||||||
}
|
}
|
||||||
if let Some(query) = query_limits {
|
if let Some(query) = query_limits {
|
||||||
ui.text(im_str!("Query limits are {:#?}", query));
|
ui.text(im_str!("Query limits are {:#?}", query));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try out converting pixel position to plot position
|
||||||
|
if let Some(pos) = hover_pos_from_pixels {
|
||||||
|
ui.text(im_str!("plot pos from imgui: {}, {}", pos.x, pos.y,));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_style_plot(ui: &Ui, plot_ui: &PlotUi) {
|
pub fn show_style_plot(ui: &Ui, plot_ui: &PlotUi) {
|
||||||
|
|
105
src/lib.rs
105
src/lib.rs
|
@ -44,6 +44,14 @@ pub enum YAxisChoice {
|
||||||
Third = sys::ImPlotYAxis__ImPlotYAxis_3,
|
Third = sys::ImPlotYAxis__ImPlotYAxis_3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Turn an Option<YAxisChoice> into an i32. Picks IMPLOT_AUTO for None.
|
||||||
|
fn y_axis_choice_option_to_i32(y_axis_choice: Option<YAxisChoice>) -> i32 {
|
||||||
|
match y_axis_choice {
|
||||||
|
Some(choice) => choice as i32,
|
||||||
|
None => IMPLOT_AUTO,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A temporary reference for building plots. This does not really do anything on its own at
|
/// A temporary reference for building plots. This does not really do anything on its own at
|
||||||
/// this point, but it is used to enforce that a context is created and active for other features,
|
/// this point, but it is used to enforce that a context is created and active for other features,
|
||||||
/// such as creating plots.
|
/// such as creating plots.
|
||||||
|
@ -395,10 +403,7 @@ pub fn is_plot_queried() -> bool {
|
||||||
/// for the specified choice of Y axis. If `None` is the Y axis choice, that means the
|
/// for the specified choice of Y axis. If `None` is the Y axis choice, that means the
|
||||||
/// most recently selected Y axis is chosen.
|
/// most recently selected Y axis is chosen.
|
||||||
pub fn get_plot_mouse_position(y_axis_choice: Option<YAxisChoice>) -> ImPlotPoint {
|
pub fn get_plot_mouse_position(y_axis_choice: Option<YAxisChoice>) -> ImPlotPoint {
|
||||||
let y_axis_choice_i32 = match y_axis_choice {
|
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||||
Some(choice) => choice as i32,
|
|
||||||
None => IMPLOT_AUTO,
|
|
||||||
};
|
|
||||||
let mut point = ImPlotPoint { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
let mut point = ImPlotPoint { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||||
unsafe {
|
unsafe {
|
||||||
sys::ImPlot_GetPlotMousePos(&mut point as *mut ImPlotPoint, y_axis_choice_i32);
|
sys::ImPlot_GetPlotMousePos(&mut point as *mut ImPlotPoint, y_axis_choice_i32);
|
||||||
|
@ -406,13 +411,87 @@ pub fn get_plot_mouse_position(y_axis_choice: Option<YAxisChoice>) -> ImPlotPoin
|
||||||
point
|
point
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert pixels, given as an `ImVec2`, to a position in the current plot's coordinate system.
|
||||||
|
/// Uses the specified Y axis, if any, otherwise whatever was previously chosen.
|
||||||
|
pub fn pixels_to_plot_vec2(
|
||||||
|
pixel_position: &ImVec2,
|
||||||
|
y_axis_choice: Option<YAxisChoice>,
|
||||||
|
) -> ImPlotPoint {
|
||||||
|
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||||
|
let mut point = ImPlotPoint { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||||
|
unsafe {
|
||||||
|
sys::ImPlot_PixelsToPlotVec2(
|
||||||
|
&mut point as *mut ImPlotPoint,
|
||||||
|
*pixel_position,
|
||||||
|
y_axis_choice_i32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
point
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert pixels, given as floats `x` and `y`, to a position in the current plot's coordinate
|
||||||
|
/// system. Uses the specified Y axis, if any, otherwise whatever was previously chosen.
|
||||||
|
pub fn pixels_to_plot_f32(
|
||||||
|
pixel_position_x: f32,
|
||||||
|
pixel_position_y: f32,
|
||||||
|
y_axis_choice: Option<YAxisChoice>,
|
||||||
|
) -> ImPlotPoint {
|
||||||
|
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||||
|
let mut point = ImPlotPoint { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||||
|
unsafe {
|
||||||
|
sys::ImPlot_PixelsToPlotFloat(
|
||||||
|
&mut point as *mut ImPlotPoint,
|
||||||
|
pixel_position_x,
|
||||||
|
pixel_position_y,
|
||||||
|
y_axis_choice_i32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
point
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a position in the current plot's coordinate system to pixels. Uses the specified Y
|
||||||
|
/// axis, if any, otherwise whatever was previously chosen.
|
||||||
|
///
|
||||||
|
pub fn plot_to_pixels_vec2(
|
||||||
|
plot_position: &ImPlotPoint,
|
||||||
|
y_axis_choice: Option<YAxisChoice>,
|
||||||
|
) -> ImVec2 {
|
||||||
|
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||||
|
let mut pixel_position = ImVec2 { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||||
|
unsafe {
|
||||||
|
sys::ImPlot_PlotToPixelsPlotPoInt(
|
||||||
|
&mut pixel_position as *mut ImVec2,
|
||||||
|
*plot_position,
|
||||||
|
y_axis_choice_i32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pixel_position
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a position in the current plot's coordinate system to pixels. Uses the specified Y
|
||||||
|
/// axis, if any, otherwise whatever was previously chosen.
|
||||||
|
pub fn plot_to_pixels_f32(
|
||||||
|
plot_position_x: f64,
|
||||||
|
plot_position_y: f64,
|
||||||
|
y_axis_choice: Option<YAxisChoice>,
|
||||||
|
) -> ImVec2 {
|
||||||
|
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||||
|
let mut pixel_position = ImVec2 { x: 0.0, y: 0.0 }; // doesn't seem to have default()
|
||||||
|
unsafe {
|
||||||
|
sys::ImPlot_PlotToPixelsdouble(
|
||||||
|
&mut pixel_position as *mut ImVec2,
|
||||||
|
plot_position_x,
|
||||||
|
plot_position_y,
|
||||||
|
y_axis_choice_i32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
pixel_position
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the current or most recent plot axis range for the specified choice of Y axis. If
|
/// Returns the current or most recent plot axis range for the specified choice of Y axis. If
|
||||||
/// `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
|
/// `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
|
||||||
pub fn get_plot_limits(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
|
pub fn get_plot_limits(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
|
||||||
let y_axis_choice_i32 = match y_axis_choice {
|
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||||
Some(choice) => choice as i32,
|
|
||||||
None => IMPLOT_AUTO,
|
|
||||||
};
|
|
||||||
// ImPlotLimits doesn't seem to have default()
|
// ImPlotLimits doesn't seem to have default()
|
||||||
let mut limits = ImPlotLimits {
|
let mut limits = ImPlotLimits {
|
||||||
X: ImPlotRange { Min: 0.0, Max: 0.0 },
|
X: ImPlotRange { Min: 0.0, Max: 0.0 },
|
||||||
|
@ -427,10 +506,7 @@ pub fn get_plot_limits(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
|
||||||
/// Returns the query limits of the current or most recent plot, for the specified choice of Y
|
/// Returns the query limits of the current or most recent plot, for the specified choice of Y
|
||||||
/// axis. If `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
|
/// axis. If `None` is the Y axis choice, that means the most recently selected Y axis is chosen.
|
||||||
pub fn get_plot_query(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
|
pub fn get_plot_query(y_axis_choice: Option<YAxisChoice>) -> ImPlotLimits {
|
||||||
let y_axis_choice_i32 = match y_axis_choice {
|
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||||
Some(choice) => choice as i32,
|
|
||||||
None => IMPLOT_AUTO,
|
|
||||||
};
|
|
||||||
// ImPlotLimits doesn't seem to have default()
|
// ImPlotLimits doesn't seem to have default()
|
||||||
let mut limits = ImPlotLimits {
|
let mut limits = ImPlotLimits {
|
||||||
X: ImPlotRange { Min: 0.0, Max: 0.0 },
|
X: ImPlotRange { Min: 0.0, Max: 0.0 },
|
||||||
|
@ -457,10 +533,7 @@ pub fn is_plot_x_axis_hovered() -> bool {
|
||||||
/// Returns true if the YAxis[n] plot area in the current plot is hovered. If `None` is the Y axis
|
/// Returns true if the YAxis[n] plot area in the current plot is hovered. If `None` is the Y axis
|
||||||
/// choice, that means the most recently selected Y axis is chosen.
|
/// choice, that means the most recently selected Y axis is chosen.
|
||||||
pub fn is_plot_y_axis_hovered(y_axis_choice: Option<YAxisChoice>) -> bool {
|
pub fn is_plot_y_axis_hovered(y_axis_choice: Option<YAxisChoice>) -> bool {
|
||||||
let y_axis_choice_i32 = match y_axis_choice {
|
let y_axis_choice_i32 = y_axis_choice_option_to_i32(y_axis_choice);
|
||||||
Some(choice) => choice as i32,
|
|
||||||
None => IMPLOT_AUTO,
|
|
||||||
};
|
|
||||||
unsafe { sys::ImPlot_IsPlotYAxisHovered(y_axis_choice_i32) }
|
unsafe { sys::ImPlot_IsPlotYAxisHovered(y_axis_choice_i32) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue