1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 15:13:12 -04:00

Add HPlacement and VPlacement

This commit is contained in:
Emil Ernerfeldt
2023-08-14 16:08:11 +02:00
parent 097dde71cd
commit a96e503295
3 changed files with 72 additions and 35 deletions

View File

@@ -17,14 +17,48 @@ pub(super) const X_AXIS: usize = 0;
/// Generic constant for y-Axis
pub(super) const Y_AXIS: usize = 1;
/// Placement of an Axis.
///
/// `Default` means bottom for x-axis and left for y-axis.
/// `Opposite` means top for x-axis and right for y-axis.
/// Placement of the horizontal X-Axis.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VPlacement {
Top,
Bottom,
}
/// Placement of the vertical Y-Axis.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HPlacement {
Left,
Right,
}
/// Placement of an axis.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Placement {
Default,
Opposite,
/// Bottom for X-axis, or left for Y-axis.
LeftBottom,
/// Top for x-axis and right for y-axis.
RightTop,
}
impl From<HPlacement> for Placement {
#[inline]
fn from(placement: HPlacement) -> Self {
match placement {
HPlacement::Left => Placement::LeftBottom,
HPlacement::Right => Placement::RightTop,
}
}
}
impl From<VPlacement> for Placement {
#[inline]
fn from(placement: VPlacement) -> Self {
match placement {
VPlacement::Top => Placement::RightTop,
VPlacement::Bottom => Placement::LeftBottom,
}
}
}
// shorthand types for AxisHints, public API
@@ -64,7 +98,7 @@ impl<const AXIS: usize> Default for AxisHints<AXIS> {
label: Default::default(),
formatter: Self::default_formatter,
digits: 5,
placement: Placement::Default,
placement: Placement::LeftBottom,
}
}
}
@@ -109,8 +143,11 @@ impl<const AXIS: usize> AxisHints<AXIS> {
}
/// Specify the placement of the axis.
pub fn placement(mut self, placement: Placement) -> Self {
self.placement = placement;
///
/// For X-axis, use [`VPlacement`].
/// For Y-axis, use [`HPlacement`].
pub fn placement(mut self, placement: impl Into<Placement>) -> Self {
self.placement = placement.into();
self
}
@@ -175,7 +212,7 @@ impl<const AXIS: usize> Widget for AxisWidget<AXIS> {
};
// select text_pos and angle depending on placement and orientation of widget
let text_pos = match self.hints.placement {
Placement::Default => match AXIS {
Placement::LeftBottom => match AXIS {
X_AXIS => {
let pos = response.rect.center_bottom();
Pos2 {
@@ -192,7 +229,7 @@ impl<const AXIS: usize> Widget for AxisWidget<AXIS> {
}
_ => unreachable!(),
},
Placement::Opposite => match AXIS {
Placement::RightTop => match AXIS {
X_AXIS => {
let pos = response.rect.center_top();
Pos2 {
@@ -250,8 +287,8 @@ impl<const AXIS: usize> Widget for AxisWidget<AXIS> {
let text_pos = match AXIS {
X_AXIS => {
let y = match self.hints.placement {
Placement::Default => self.rect.min.y,
Placement::Opposite => self.rect.max.y - galley.size().y,
Placement::LeftBottom => self.rect.min.y,
Placement::RightTop => self.rect.max.y - galley.size().y,
};
let projected_point = super::PlotPoint::new(step.value, 0.0);
Pos2 {
@@ -262,8 +299,8 @@ impl<const AXIS: usize> Widget for AxisWidget<AXIS> {
}
Y_AXIS => {
let x = match self.hints.placement {
Placement::Default => self.rect.max.x - galley.size().x,
Placement::Opposite => self.rect.min.x,
Placement::LeftBottom => self.rect.max.x - galley.size().x,
Placement::RightTop => self.rect.min.x,
};
let projected_point = super::PlotPoint::new(0.0, step.value);
Pos2 {

View File

@@ -21,7 +21,7 @@ pub use transform::{PlotBounds, PlotTransform};
use items::{horizontal_line, rulers_color, vertical_line};
pub use axis::{Placement, XAxisHints, YAxisHints};
pub use axis::{HPlacement, Placement, VPlacement, XAxisHints, YAxisHints};
mod axis;
mod items;
@@ -596,17 +596,17 @@ impl Plot {
}
/// Set the position of the main X-axis.
pub fn x_axis_position(mut self, placement: axis::Placement) -> Self {
pub fn x_axis_position(mut self, placement: axis::VPlacement) -> Self {
if let Some(main) = self.x_axes.first_mut() {
main.placement = placement;
main.placement = placement.into();
}
self
}
/// Set the position of the main Y-axis.
pub fn y_axis_position(mut self, placement: axis::Placement) -> Self {
pub fn y_axis_position(mut self, placement: axis::HPlacement) -> Self {
if let Some(main) = self.y_axes.first_mut() {
main.placement = placement;
main.placement = placement.into();
}
self
}
@@ -768,10 +768,10 @@ impl Plot {
if show_axes.x {
for cfg in &x_axes {
match cfg.placement {
axis::Placement::Default => {
axis::Placement::LeftBottom => {
margin.bottom += cfg.thickness();
}
axis::Placement::Opposite => {
axis::Placement::RightTop => {
margin.top += cfg.thickness();
}
}
@@ -780,10 +780,10 @@ impl Plot {
if show_axes.y {
for cfg in &y_axes {
match cfg.placement {
axis::Placement::Default => {
axis::Placement::LeftBottom => {
margin.left += cfg.thickness();
}
axis::Placement::Opposite => {
axis::Placement::RightTop => {
margin.right += cfg.thickness();
}
}
@@ -815,7 +815,7 @@ impl Plot {
for cfg in &x_axes {
let size_y = Vec2::new(0.0, cfg.thickness());
let rect = match cfg.placement {
axis::Placement::Default => {
axis::Placement::LeftBottom => {
let off = num_widgets.bottom as f32;
num_widgets.bottom += 1;
Rect {
@@ -823,7 +823,7 @@ impl Plot {
max: plot_rect.right_bottom() + size_y * (off + 1.0),
}
}
axis::Placement::Opposite => {
axis::Placement::RightTop => {
let off = num_widgets.top as f32;
num_widgets.top += 1;
Rect {
@@ -839,7 +839,7 @@ impl Plot {
for cfg in &y_axes {
let size_x = Vec2::new(cfg.thickness(), 0.0);
let rect = match cfg.placement {
axis::Placement::Default => {
axis::Placement::LeftBottom => {
let off = num_widgets.left as f32;
num_widgets.left += 1;
Rect {
@@ -847,7 +847,7 @@ impl Plot {
max: plot_rect.left_bottom() - size_x * off,
}
}
axis::Placement::Opposite => {
axis::Placement::RightTop => {
let off = num_widgets.right as f32;
num_widgets.right += 1;
Rect {

View File

@@ -1,12 +1,12 @@
use std::f64::consts::TAU;
use std::ops::RangeInclusive;
use egui::plot::{AxisBools, GridInput, GridMark, Placement, PlotResponse, XAxisHints, YAxisHints};
use egui::*;
use plot::{
Arrows, Bar, BarChart, BoxElem, BoxPlot, BoxSpread, CoordinatesFormatter, Corner, HLine,
Legend, Line, LineStyle, MarkerShape, Plot, PlotImage, PlotPoint, PlotPoints, Points, Polygon,
Text, VLine,
use egui::plot::{
Arrows, AxisBools, Bar, BarChart, BoxElem, BoxPlot, BoxSpread, CoordinatesFormatter, Corner,
GridInput, GridMark, HLine, Legend, Line, LineStyle, MarkerShape, Plot, PlotImage, PlotPoint,
PlotPoints, PlotResponse, Points, Polygon, Text, VLine, XAxisHints, YAxisHints,
};
// ----------------------------------------------------------------------------
@@ -575,7 +575,7 @@ impl CustomAxesDemo {
.max_digits(4),
YAxisHints::default()
.label("Absolute")
.placement(Placement::Opposite),
.placement(plot::HPlacement::Right),
];
Plot::new("custom_axes")
.data_aspect(2.0 * MINS_PER_DAY as f32)
@@ -675,7 +675,7 @@ impl LinkedAxesDemo {
.height(250.0)
.y_axis_width(3)
.y_axis_label("y")
.y_axis_position(Placement::Opposite)
.y_axis_position(plot::HPlacement::Right)
.link_axis(link_group_id, self.link_x, self.link_y)
.link_cursor(link_group_id, self.link_cursor_x, self.link_cursor_y)
.show(ui, LinkedAxesDemo::configure_plot);