Browse Source

Add `emath::Vec2b`, replacing `egui_plot::AxisBools` (#3543)

Thanks to `impl From<bool> for Vec2b` one can now shorten some builder
calls, like:

Previous:
```rust
 egui::ScrollArea::vertical()
        .auto_shrink([false; 2])
```

New:
```rust
 egui::ScrollArea::vertical()
        .auto_shrink(false)
```
pull/3548/head
Emil Ernerfeldt 1 year ago
committed by GitHub
parent
commit
b27aa27e94
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 64
      crates/egui/src/containers/scroll_area.rs
  2. 2
      crates/egui/src/containers/window.rs
  3. 2
      crates/egui/src/lib.rs
  4. 2
      crates/egui_demo_app/src/apps/custom3d_glow.rs
  5. 2
      crates/egui_demo_app/src/apps/custom3d_wgpu.rs
  6. 2
      crates/egui_demo_app/src/apps/http_app.rs
  7. 2
      crates/egui_demo_app/src/apps/image_viewer.rs
  8. 2
      crates/egui_demo_app/src/wrap_app.rs
  9. 6
      crates/egui_demo_lib/src/demo/context_menu.rs
  10. 10
      crates/egui_demo_lib/src/demo/plot_demo.rs
  11. 10
      crates/egui_demo_lib/src/demo/scrolling.rs
  12. 2
      crates/egui_demo_lib/src/demo/text_layout.rs
  13. 6
      crates/egui_demo_lib/src/demo/window_options.rs
  14. 14
      crates/egui_extras/src/table.rs
  15. 75
      crates/egui_plot/src/lib.rs
  16. 2
      crates/emath/src/lib.rs
  17. 60
      crates/emath/src/vec2b.rs
  18. 2
      examples/images/src/main.rs
  19. 2
      examples/keyboard_events/src/main.rs

64
crates/egui/src/containers/scroll_area.rs

@ -10,13 +10,13 @@ pub struct State {
pub offset: Vec2, pub offset: Vec2,
/// Were the scroll bars visible last frame? /// Were the scroll bars visible last frame?
show_scroll: [bool; 2], show_scroll: Vec2b,
/// The content were to large to fit large frame. /// The content were to large to fit large frame.
content_is_too_large: [bool; 2], content_is_too_large: Vec2b,
/// Did the user interact (hover or drag) the scroll bars last frame? /// Did the user interact (hover or drag) the scroll bars last frame?
scroll_bar_interaction: [bool; 2], scroll_bar_interaction: Vec2b,
/// Momentum, used for kinetic scrolling /// Momentum, used for kinetic scrolling
#[cfg_attr(feature = "serde", serde(skip))] #[cfg_attr(feature = "serde", serde(skip))]
@ -28,19 +28,19 @@ pub struct State {
/// Is the scroll sticky. This is true while scroll handle is in the end position /// Is the scroll sticky. This is true while scroll handle is in the end position
/// and remains that way until the user moves the scroll_handle. Once unstuck (false) /// and remains that way until the user moves the scroll_handle. Once unstuck (false)
/// it remains false until the scroll touches the end position, which reenables stickiness. /// it remains false until the scroll touches the end position, which reenables stickiness.
scroll_stuck_to_end: [bool; 2], scroll_stuck_to_end: Vec2b,
} }
impl Default for State { impl Default for State {
fn default() -> Self { fn default() -> Self {
Self { Self {
offset: Vec2::ZERO, offset: Vec2::ZERO,
show_scroll: [false; 2], show_scroll: Vec2b::FALSE,
content_is_too_large: [false; 2], content_is_too_large: Vec2b::FALSE,
scroll_bar_interaction: [false; 2], scroll_bar_interaction: Vec2b::FALSE,
vel: Vec2::ZERO, vel: Vec2::ZERO,
scroll_start_offset_from_top_left: [None; 2], scroll_start_offset_from_top_left: [None; 2],
scroll_stuck_to_end: [true; 2], scroll_stuck_to_end: Vec2b::TRUE,
} }
} }
} }
@ -147,9 +147,9 @@ impl ScrollBarVisibility {
#[must_use = "You should call .show()"] #[must_use = "You should call .show()"]
pub struct ScrollArea { pub struct ScrollArea {
/// Do we have horizontal/vertical scrolling enabled? /// Do we have horizontal/vertical scrolling enabled?
scroll_enabled: [bool; 2], scroll_enabled: Vec2b,
auto_shrink: [bool; 2], auto_shrink: Vec2b,
max_size: Vec2, max_size: Vec2,
min_scrolled_size: Vec2, min_scrolled_size: Vec2,
scroll_bar_visibility: ScrollBarVisibility, scroll_bar_visibility: ScrollBarVisibility,
@ -164,7 +164,7 @@ pub struct ScrollArea {
/// If true for vertical or horizontal the scroll wheel will stick to the /// If true for vertical or horizontal the scroll wheel will stick to the
/// end position until user manually changes position. It will become true /// end position until user manually changes position. It will become true
/// again once scroll handle makes contact with end. /// again once scroll handle makes contact with end.
stick_to_end: [bool; 2], stick_to_end: Vec2b,
} }
impl ScrollArea { impl ScrollArea {
@ -195,10 +195,10 @@ impl ScrollArea {
/// Create a scroll area where you decide which axis has scrolling enabled. /// Create a scroll area where you decide which axis has scrolling enabled.
/// For instance, `ScrollArea::new([true, false])` enables horizontal scrolling. /// For instance, `ScrollArea::new([true, false])` enables horizontal scrolling.
pub fn new(scroll_enabled: [bool; 2]) -> Self { pub fn new(scroll_enabled: impl Into<Vec2b>) -> Self {
Self { Self {
scroll_enabled, scroll_enabled: scroll_enabled.into(),
auto_shrink: [true; 2], auto_shrink: Vec2b::TRUE,
max_size: Vec2::INFINITY, max_size: Vec2::INFINITY,
min_scrolled_size: Vec2::splat(64.0), min_scrolled_size: Vec2::splat(64.0),
scroll_bar_visibility: Default::default(), scroll_bar_visibility: Default::default(),
@ -207,7 +207,7 @@ impl ScrollArea {
offset_y: None, offset_y: None,
scrolling_enabled: true, scrolling_enabled: true,
drag_to_scroll: true, drag_to_scroll: true,
stick_to_end: [false; 2], stick_to_end: Vec2b::FALSE,
} }
} }
@ -327,8 +327,8 @@ impl ScrollArea {
/// Turn on/off scrolling on the horizontal/vertical axes. /// Turn on/off scrolling on the horizontal/vertical axes.
#[inline] #[inline]
pub fn scroll2(mut self, scroll_enabled: [bool; 2]) -> Self { pub fn scroll2(mut self, scroll_enabled: impl Into<Vec2b>) -> Self {
self.scroll_enabled = scroll_enabled; self.scroll_enabled = scroll_enabled.into();
self self
} }
@ -365,10 +365,10 @@ impl ScrollArea {
/// * If `true`, egui will add blank space outside the scroll area. /// * If `true`, egui will add blank space outside the scroll area.
/// * If `false`, egui will add blank space inside the scroll area. /// * If `false`, egui will add blank space inside the scroll area.
/// ///
/// Default: `[true; 2]`. /// Default: `true`.
#[inline] #[inline]
pub fn auto_shrink(mut self, auto_shrink: [bool; 2]) -> Self { pub fn auto_shrink(mut self, auto_shrink: impl Into<Vec2b>) -> Self {
self.auto_shrink = auto_shrink; self.auto_shrink = auto_shrink.into();
self self
} }
@ -406,10 +406,10 @@ struct Prepared {
id: Id, id: Id,
state: State, state: State,
auto_shrink: [bool; 2], auto_shrink: Vec2b,
/// Does this `ScrollArea` have horizontal/vertical scrolling enabled? /// Does this `ScrollArea` have horizontal/vertical scrolling enabled?
scroll_enabled: [bool; 2], scroll_enabled: Vec2b,
/// Smoothly interpolated boolean of whether or not to show the scroll bars. /// Smoothly interpolated boolean of whether or not to show the scroll bars.
show_bars_factor: Vec2, show_bars_factor: Vec2,
@ -437,7 +437,7 @@ struct Prepared {
viewport: Rect, viewport: Rect,
scrolling_enabled: bool, scrolling_enabled: bool,
stick_to_end: [bool; 2], stick_to_end: Vec2b,
} }
impl ScrollArea { impl ScrollArea {
@ -470,8 +470,8 @@ impl ScrollArea {
state.offset.x = offset_x.unwrap_or(state.offset.x); state.offset.x = offset_x.unwrap_or(state.offset.x);
state.offset.y = offset_y.unwrap_or(state.offset.y); state.offset.y = offset_y.unwrap_or(state.offset.y);
let show_bars: [bool; 2] = match scroll_bar_visibility { let show_bars: Vec2b = match scroll_bar_visibility {
ScrollBarVisibility::AlwaysHidden => [false; 2], ScrollBarVisibility::AlwaysHidden => Vec2b::FALSE,
ScrollBarVisibility::VisibleWhenNeeded => state.show_scroll, ScrollBarVisibility::VisibleWhenNeeded => state.show_scroll,
ScrollBarVisibility::AlwaysVisible => scroll_enabled, ScrollBarVisibility::AlwaysVisible => scroll_enabled,
}; };
@ -769,10 +769,10 @@ impl Prepared {
let outer_rect = Rect::from_min_size(inner_rect.min, inner_rect.size() + current_bar_use); let outer_rect = Rect::from_min_size(inner_rect.min, inner_rect.size() + current_bar_use);
let content_is_too_large = [ let content_is_too_large = Vec2b::new(
scroll_enabled[0] && inner_rect.width() < content_size.x, scroll_enabled[0] && inner_rect.width() < content_size.x,
scroll_enabled[1] && inner_rect.height() < content_size.y, scroll_enabled[1] && inner_rect.height() < content_size.y,
]; );
let max_offset = content_size - inner_rect.size(); let max_offset = content_size - inner_rect.size();
let is_hovering_outer_rect = ui.rect_contains_pointer(outer_rect); let is_hovering_outer_rect = ui.rect_contains_pointer(outer_rect);
@ -795,10 +795,8 @@ impl Prepared {
} }
let show_scroll_this_frame = match scroll_bar_visibility { let show_scroll_this_frame = match scroll_bar_visibility {
ScrollBarVisibility::AlwaysHidden => [false, false], ScrollBarVisibility::AlwaysHidden => Vec2b::FALSE,
ScrollBarVisibility::VisibleWhenNeeded => { ScrollBarVisibility::VisibleWhenNeeded => content_is_too_large,
[content_is_too_large[0], content_is_too_large[1]]
}
ScrollBarVisibility::AlwaysVisible => scroll_enabled, ScrollBarVisibility::AlwaysVisible => scroll_enabled,
}; };
@ -1065,12 +1063,12 @@ impl Prepared {
// Only has an effect if stick_to_end is enabled but we save in // Only has an effect if stick_to_end is enabled but we save in
// state anyway so that entering sticky mode at an arbitrary time // state anyway so that entering sticky mode at an arbitrary time
// has appropriate effect. // has appropriate effect.
state.scroll_stuck_to_end = [ state.scroll_stuck_to_end = Vec2b::new(
(state.offset[0] == available_offset[0]) (state.offset[0] == available_offset[0])
|| (self.stick_to_end[0] && available_offset[0] < 0.0), || (self.stick_to_end[0] && available_offset[0] < 0.0),
(state.offset[1] == available_offset[1]) (state.offset[1] == available_offset[1])
|| (self.stick_to_end[1] && available_offset[1] < 0.0), || (self.stick_to_end[1] && available_offset[1] < 0.0),
]; );
state.show_scroll = show_scroll_this_frame; state.show_scroll = show_scroll_this_frame;
state.content_is_too_large = content_is_too_large; state.content_is_too_large = content_is_too_large;

2
crates/egui/src/containers/window.rs

@ -272,7 +272,7 @@ impl<'open> Window<'open> {
} }
/// Enable/disable horizontal/vertical scrolling. `false` by default. /// Enable/disable horizontal/vertical scrolling. `false` by default.
pub fn scroll2(mut self, scroll: [bool; 2]) -> Self { pub fn scroll2(mut self, scroll: impl Into<Vec2b>) -> Self {
self.scroll = self.scroll.scroll2(scroll); self.scroll = self.scroll.scroll2(scroll);
self self
} }

2
crates/egui/src/lib.rs

@ -377,7 +377,7 @@ pub use epaint::emath;
pub use ecolor::hex_color; pub use ecolor::hex_color;
pub use ecolor::{Color32, Rgba}; pub use ecolor::{Color32, Rgba};
pub use emath::{ pub use emath::{
lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rangef, Rect, Vec2, lerp, pos2, remap, remap_clamp, vec2, Align, Align2, NumExt, Pos2, Rangef, Rect, Vec2, Vec2b,
}; };
pub use epaint::{ pub use epaint::{
mutex, mutex,

2
crates/egui_demo_app/src/apps/custom3d_glow.rs

@ -24,7 +24,7 @@ impl eframe::App for Custom3d {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
egui::ScrollArea::both() egui::ScrollArea::both()
.auto_shrink([false; 2]) .auto_shrink(false)
.show(ui, |ui| { .show(ui, |ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0; ui.spacing_mut().item_spacing.x = 0.0;

2
crates/egui_demo_app/src/apps/custom3d_wgpu.rs

@ -99,7 +99,7 @@ impl eframe::App for Custom3d {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
egui::ScrollArea::both() egui::ScrollArea::both()
.auto_shrink([false; 2]) .auto_shrink(false)
.show(ui, |ui| { .show(ui, |ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 0.0; ui.spacing_mut().item_spacing.x = 0.0;

2
crates/egui_demo_app/src/apps/http_app.rs

@ -174,7 +174,7 @@ fn ui_resource(ui: &mut egui::Ui, resource: &Resource) {
ui.separator(); ui.separator();
egui::ScrollArea::vertical() egui::ScrollArea::vertical()
.auto_shrink([false; 2]) .auto_shrink(false)
.show(ui, |ui| { .show(ui, |ui| {
egui::CollapsingHeader::new("Response headers") egui::CollapsingHeader::new("Response headers")
.default_open(false) .default_open(false)

2
crates/egui_demo_app/src/apps/image_viewer.rs

@ -187,7 +187,7 @@ impl eframe::App for ImageViewer {
}); });
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
egui::ScrollArea::new([true, true]).show(ui, |ui| { egui::ScrollArea::both().show(ui, |ui| {
let mut image = egui::Image::from_uri(&self.current_uri); let mut image = egui::Image::from_uri(&self.current_uri);
image = image.uv(self.image_options.uv); image = image.uv(self.image_options.uv);
image = image.bg_fill(self.image_options.bg_fill); image = image.bg_fill(self.image_options.bg_fill);

2
crates/egui_demo_app/src/wrap_app.rs

@ -68,7 +68,7 @@ impl eframe::App for ColorTestApp {
); );
ui.separator(); ui.separator();
} }
egui::ScrollArea::both().auto_shrink([false; 2]).show(ui, |ui| { egui::ScrollArea::both().auto_shrink(false).show(ui, |ui| {
self.color_test.ui(ui); self.color_test.ui(ui);
}); });
}); });

6
crates/egui_demo_lib/src/demo/context_menu.rs

@ -1,3 +1,5 @@
use egui::Vec2b;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
enum Plot { enum Plot {
@ -19,7 +21,7 @@ fn sigmoid(x: f64) -> f64 {
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct ContextMenus { pub struct ContextMenus {
plot: Plot, plot: Plot,
show_axes: [bool; 2], show_axes: Vec2b,
allow_drag: bool, allow_drag: bool,
allow_zoom: bool, allow_zoom: bool,
allow_scroll: bool, allow_scroll: bool,
@ -33,7 +35,7 @@ impl Default for ContextMenus {
fn default() -> Self { fn default() -> Self {
Self { Self {
plot: Plot::Sin, plot: Plot::Sin,
show_axes: [true, true], show_axes: Vec2b::TRUE,
allow_drag: true, allow_drag: true,
allow_zoom: true, allow_zoom: true,
allow_scroll: true, allow_scroll: true,

10
crates/egui_demo_lib/src/demo/plot_demo.rs

@ -4,9 +4,9 @@ use std::ops::RangeInclusive;
use egui::*; use egui::*;
use egui_plot::{ use egui_plot::{
Arrows, AxisBools, AxisHints, Bar, BarChart, BoxElem, BoxPlot, BoxSpread, CoordinatesFormatter, Arrows, AxisHints, Bar, BarChart, BoxElem, BoxPlot, BoxSpread, CoordinatesFormatter, Corner,
Corner, GridInput, GridMark, HLine, Legend, Line, LineStyle, MarkerShape, Plot, PlotImage, GridInput, GridMark, HLine, Legend, Line, LineStyle, MarkerShape, Plot, PlotImage, PlotPoint,
PlotPoint, PlotPoints, PlotResponse, Points, Polygon, Text, VLine, PlotPoints, PlotResponse, Points, Polygon, Text, VLine,
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -830,8 +830,8 @@ impl Default for Chart {
struct ChartsDemo { struct ChartsDemo {
chart: Chart, chart: Chart,
vertical: bool, vertical: bool,
allow_zoom: AxisBools, allow_zoom: Vec2b,
allow_drag: AxisBools, allow_drag: Vec2b,
} }
impl Default for ChartsDemo { impl Default for ChartsDemo {

10
crates/egui_demo_lib/src/demo/scrolling.rs

@ -146,7 +146,7 @@ impl ScrollAppearance {
ui.separator(); ui.separator();
ScrollArea::vertical() ScrollArea::vertical()
.auto_shrink([false; 2]) .auto_shrink(false)
.scroll_bar_visibility(*visibility) .scroll_bar_visibility(*visibility)
.show(ui, |ui| { .show(ui, |ui| {
ui.with_layout( ui.with_layout(
@ -170,7 +170,7 @@ fn huge_content_lines(ui: &mut egui::Ui) {
let text_style = TextStyle::Body; let text_style = TextStyle::Body;
let row_height = ui.text_style_height(&text_style); let row_height = ui.text_style_height(&text_style);
let num_rows = 10_000; let num_rows = 10_000;
ScrollArea::vertical().auto_shrink([false; 2]).show_rows( ScrollArea::vertical().auto_shrink(false).show_rows(
ui, ui,
row_height, row_height,
num_rows, num_rows,
@ -193,7 +193,7 @@ fn huge_content_painter(ui: &mut egui::Ui) {
let num_rows = 10_000; let num_rows = 10_000;
ScrollArea::vertical() ScrollArea::vertical()
.auto_shrink([false; 2]) .auto_shrink(false)
.show_viewport(ui, |ui, viewport| { .show_viewport(ui, |ui, viewport| {
ui.set_height(row_height * num_rows as f32); ui.set_height(row_height * num_rows as f32);
@ -292,9 +292,7 @@ impl super::View for ScrollTo {
scroll_bottom |= ui.button("Scroll to bottom").clicked(); scroll_bottom |= ui.button("Scroll to bottom").clicked();
}); });
let mut scroll_area = ScrollArea::vertical() let mut scroll_area = ScrollArea::vertical().max_height(200.0).auto_shrink(false);
.max_height(200.0)
.auto_shrink([false; 2]);
if go_to_scroll_offset { if go_to_scroll_offset {
scroll_area = scroll_area.vertical_scroll_offset(self.offset); scroll_area = scroll_area.vertical_scroll_offset(self.offset);
} }

2
crates/egui_demo_lib/src/demo/text_layout.rs

@ -124,7 +124,7 @@ impl super::View for TextLayoutDemo {
}; };
egui::ScrollArea::vertical() egui::ScrollArea::vertical()
.auto_shrink([false; 2]) .auto_shrink(false)
.show(ui, |ui| { .show(ui, |ui| {
let extra_letter_spacing = points_per_pixel * *extra_letter_spacing_pixels as f32; let extra_letter_spacing = points_per_pixel * *extra_letter_spacing_pixels as f32;
let line_height = (*line_height_pixels != 0) let line_height = (*line_height_pixels != 0)

6
crates/egui_demo_lib/src/demo/window_options.rs

@ -1,3 +1,5 @@
use egui::Vec2b;
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct WindowOptions { pub struct WindowOptions {
@ -7,7 +9,7 @@ pub struct WindowOptions {
collapsible: bool, collapsible: bool,
resizable: bool, resizable: bool,
constrain: bool, constrain: bool,
scroll2: [bool; 2], scroll2: Vec2b,
disabled_time: f64, disabled_time: f64,
anchored: bool, anchored: bool,
@ -24,7 +26,7 @@ impl Default for WindowOptions {
collapsible: true, collapsible: true,
resizable: true, resizable: true,
constrain: true, constrain: true,
scroll2: [true; 2], scroll2: Vec2b::TRUE,
disabled_time: f64::NEG_INFINITY, disabled_time: f64::NEG_INFINITY,
anchored: false, anchored: false,
anchor: egui::Align2::RIGHT_TOP, anchor: egui::Align2::RIGHT_TOP,

14
crates/egui_extras/src/table.rs

@ -3,7 +3,7 @@
//! | fixed size | all available space/minimum | 30% of available width | fixed size | //! | fixed size | all available space/minimum | 30% of available width | fixed size |
//! Takes all available height, so if you want something below the table, put it in a strip. //! Takes all available height, so if you want something below the table, put it in a strip.
use egui::{Align, NumExt as _, Rangef, Rect, Response, ScrollArea, Ui, Vec2}; use egui::{Align, NumExt as _, Rangef, Rect, Response, ScrollArea, Ui, Vec2, Vec2b};
use crate::{ use crate::{
layout::{CellDirection, CellSize}, layout::{CellDirection, CellSize},
@ -165,7 +165,7 @@ struct TableScrollOptions {
scroll_offset_y: Option<f32>, scroll_offset_y: Option<f32>,
min_scrolled_height: f32, min_scrolled_height: f32,
max_scroll_height: f32, max_scroll_height: f32,
auto_shrink: [bool; 2], auto_shrink: Vec2b,
} }
impl Default for TableScrollOptions { impl Default for TableScrollOptions {
@ -178,7 +178,7 @@ impl Default for TableScrollOptions {
scroll_offset_y: None, scroll_offset_y: None,
min_scrolled_height: 200.0, min_scrolled_height: 200.0,
max_scroll_height: 800.0, max_scroll_height: 800.0,
auto_shrink: [true; 2], auto_shrink: Vec2b::TRUE,
} }
} }
} }
@ -335,11 +335,11 @@ impl<'a> TableBuilder<'a> {
/// * If true, add blank space outside the table, keeping the table small. /// * If true, add blank space outside the table, keeping the table small.
/// * If false, add blank space inside the table, expanding the table to fit the containing ui. /// * If false, add blank space inside the table, expanding the table to fit the containing ui.
/// ///
/// Default: `[true; 2]`. /// Default: `true`.
/// ///
/// See [`ScrollArea::auto_shrink`] for more. /// See [`ScrollArea::auto_shrink`] for more.
pub fn auto_shrink(mut self, auto_shrink: [bool; 2]) -> Self { pub fn auto_shrink(mut self, auto_shrink: impl Into<Vec2b>) -> Self {
self.scroll_options.auto_shrink = auto_shrink; self.scroll_options.auto_shrink = auto_shrink.into();
self self
} }
@ -577,7 +577,7 @@ impl<'a> Table<'a> {
let avail_rect = ui.available_rect_before_wrap(); let avail_rect = ui.available_rect_before_wrap();
let mut scroll_area = ScrollArea::new([false, vscroll]) let mut scroll_area = ScrollArea::new([false, vscroll])
.auto_shrink([true; 2]) .auto_shrink(true)
.drag_to_scroll(drag_to_scroll) .drag_to_scroll(drag_to_scroll)
.stick_to_bottom(stick_to_bottom) .stick_to_bottom(stick_to_bottom)
.min_scrolled_height(min_scrolled_height) .min_scrolled_height(min_scrolled_height)

75
crates/egui_plot/src/lib.rs

@ -77,47 +77,13 @@ impl Default for CoordinatesFormatter {
const MIN_LINE_SPACING_IN_POINTS: f64 = 6.0; // TODO(emilk): large enough for a wide label const MIN_LINE_SPACING_IN_POINTS: f64 = 6.0; // TODO(emilk): large enough for a wide label
/// Two bools, one for each axis (X and Y).
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct AxisBools {
pub x: bool,
pub y: bool,
}
impl AxisBools {
#[inline]
pub fn new(x: bool, y: bool) -> Self {
Self { x, y }
}
#[inline]
pub fn any(&self) -> bool {
self.x || self.y
}
}
impl From<bool> for AxisBools {
#[inline]
fn from(val: bool) -> Self {
AxisBools { x: val, y: val }
}
}
impl From<[bool; 2]> for AxisBools {
#[inline]
fn from([x, y]: [bool; 2]) -> Self {
AxisBools { x, y }
}
}
/// Information about the plot that has to persist between frames. /// Information about the plot that has to persist between frames.
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Clone)] #[derive(Clone)]
struct PlotMemory { struct PlotMemory {
/// Indicates if the user has modified the bounds, for example by moving or zooming, /// Indicates if the user has modified the bounds, for example by moving or zooming,
/// or if the bounds should be calculated based by included point or auto bounds. /// or if the bounds should be calculated based by included point or auto bounds.
bounds_modified: AxisBools, bounds_modified: Vec2b,
hovered_entry: Option<String>, hovered_entry: Option<String>,
hidden_items: ahash::HashSet<String>, hidden_items: ahash::HashSet<String>,
@ -171,7 +137,7 @@ struct CursorLinkGroups(HashMap<Id, Vec<PlotFrameCursors>>);
#[derive(Clone)] #[derive(Clone)]
struct LinkedBounds { struct LinkedBounds {
bounds: PlotBounds, bounds: PlotBounds,
bounds_modified: AxisBools, bounds_modified: Vec2b,
} }
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -211,18 +177,18 @@ pub struct PlotResponse<R> {
pub struct Plot { pub struct Plot {
id_source: Id, id_source: Id,
center_axis: AxisBools, center_axis: Vec2b,
allow_zoom: AxisBools, allow_zoom: Vec2b,
allow_drag: AxisBools, allow_drag: Vec2b,
allow_scroll: bool, allow_scroll: bool,
allow_double_click_reset: bool, allow_double_click_reset: bool,
allow_boxed_zoom: bool, allow_boxed_zoom: bool,
auto_bounds: AxisBools, auto_bounds: Vec2b,
min_auto_bounds: PlotBounds, min_auto_bounds: PlotBounds,
margin_fraction: Vec2, margin_fraction: Vec2,
boxed_zoom_pointer_button: PointerButton, boxed_zoom_pointer_button: PointerButton,
linked_axes: Option<(Id, AxisBools)>, linked_axes: Option<(Id, Vec2b)>,
linked_cursors: Option<(Id, AxisBools)>, linked_cursors: Option<(Id, Vec2b)>,
min_size: Vec2, min_size: Vec2,
width: Option<f32>, width: Option<f32>,
@ -240,8 +206,8 @@ pub struct Plot {
y_axes: Vec<AxisHints>, // default y axes y_axes: Vec<AxisHints>, // default y axes
legend_config: Option<Legend>, legend_config: Option<Legend>,
show_background: bool, show_background: bool,
show_axes: AxisBools, show_axes: Vec2b,
show_grid: AxisBools, show_grid: Vec2b,
grid_spacers: [GridSpacer; 2], grid_spacers: [GridSpacer; 2],
sharp_grid_lines: bool, sharp_grid_lines: bool,
clamp_grid: bool, clamp_grid: bool,
@ -357,7 +323,7 @@ impl Plot {
/// Note: Allowing zoom in one axis but not the other may lead to unexpected results if used in combination with `data_aspect`. /// Note: Allowing zoom in one axis but not the other may lead to unexpected results if used in combination with `data_aspect`.
pub fn allow_zoom<T>(mut self, on: T) -> Self pub fn allow_zoom<T>(mut self, on: T) -> Self
where where
T: Into<AxisBools>, T: Into<Vec2b>,
{ {
self.allow_zoom = on.into(); self.allow_zoom = on.into();
self self
@ -401,7 +367,7 @@ impl Plot {
/// Whether to allow dragging in the plot to move the bounds. Default: `true`. /// Whether to allow dragging in the plot to move the bounds. Default: `true`.
pub fn allow_drag<T>(mut self, on: T) -> Self pub fn allow_drag<T>(mut self, on: T) -> Self
where where
T: Into<AxisBools>, T: Into<Vec2b>,
{ {
self.allow_drag = on.into(); self.allow_drag = on.into();
self self
@ -530,6 +496,7 @@ impl Plot {
} }
/// Whether or not to show the background [`Rect`]. /// Whether or not to show the background [`Rect`].
///
/// Can be useful to disable if the plot is overlaid over existing content. /// Can be useful to disable if the plot is overlaid over existing content.
/// Default: `true`. /// Default: `true`.
pub fn show_background(mut self, show: bool) -> Self { pub fn show_background(mut self, show: bool) -> Self {
@ -539,16 +506,16 @@ impl Plot {
/// Show axis labels and grid tick values on the side of the plot. /// Show axis labels and grid tick values on the side of the plot.
/// ///
/// Default: `[true; 2]`. /// Default: `true`.
pub fn show_axes(mut self, show: impl Into<AxisBools>) -> Self { pub fn show_axes(mut self, show: impl Into<Vec2b>) -> Self {
self.show_axes = show.into(); self.show_axes = show.into();
self self
} }
/// Show a grid overlay on the plot. /// Show a grid overlay on the plot.
/// ///
/// Default: `[true; 2]`. /// Default: `true`.
pub fn show_grid(mut self, show: impl Into<AxisBools>) -> Self { pub fn show_grid(mut self, show: impl Into<Vec2b>) -> Self {
self.show_grid = show.into(); self.show_grid = show.into();
self self
} }
@ -558,7 +525,7 @@ impl Plot {
pub fn link_axis(mut self, group_id: impl Into<Id>, link_x: bool, link_y: bool) -> Self { pub fn link_axis(mut self, group_id: impl Into<Id>, link_x: bool, link_y: bool) -> Self {
self.linked_axes = Some(( self.linked_axes = Some((
group_id.into(), group_id.into(),
AxisBools { Vec2b {
x: link_x, x: link_x,
y: link_y, y: link_y,
}, },
@ -571,7 +538,7 @@ impl Plot {
pub fn link_cursor(mut self, group_id: impl Into<Id>, link_x: bool, link_y: bool) -> Self { pub fn link_cursor(mut self, group_id: impl Into<Id>, link_x: bool, link_y: bool) -> Self {
self.linked_cursors = Some(( self.linked_cursors = Some((
group_id.into(), group_id.into(),
AxisBools { Vec2b {
x: link_x, x: link_x,
y: link_y, y: link_y,
}, },
@ -1245,7 +1212,7 @@ impl Plot {
} }
fn axis_widgets( fn axis_widgets(
show_axes: AxisBools, show_axes: Vec2b,
plot_rect: Rect, plot_rect: Rect,
[x_axes, y_axes]: [&[AxisHints]; 2], [x_axes, y_axes]: [&[AxisHints]; 2],
) -> [Vec<AxisWidget>; 2] { ) -> [Vec<AxisWidget>; 2] {
@ -1616,7 +1583,7 @@ struct PreparedPlot {
coordinates_formatter: Option<(Corner, CoordinatesFormatter)>, coordinates_formatter: Option<(Corner, CoordinatesFormatter)>,
// axis_formatters: [AxisFormatter; 2], // axis_formatters: [AxisFormatter; 2],
transform: PlotTransform, transform: PlotTransform,
show_grid: AxisBools, show_grid: Vec2b,
grid_spacers: [GridSpacer; 2], grid_spacers: [GridSpacer; 2],
draw_cursor_x: bool, draw_cursor_x: bool,
draw_cursor_y: bool, draw_cursor_y: bool,

2
crates/emath/src/lib.rs

@ -36,6 +36,7 @@ mod rect_transform;
mod rot2; mod rot2;
pub mod smart_aim; pub mod smart_aim;
mod vec2; mod vec2;
mod vec2b;
pub use { pub use {
align::{Align, Align2}, align::{Align, Align2},
@ -47,6 +48,7 @@ pub use {
rect_transform::*, rect_transform::*,
rot2::*, rot2::*,
vec2::*, vec2::*,
vec2b::*,
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

60
crates/emath/src/vec2b.rs

@ -0,0 +1,60 @@
/// Two bools, one for each axis (X and Y).
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Vec2b {
pub x: bool,
pub y: bool,
}
impl Vec2b {
pub const FALSE: Self = Self { x: false, y: false };
pub const TRUE: Self = Self { x: true, y: true };
#[inline]
pub fn new(x: bool, y: bool) -> Self {
Self { x, y }
}
#[inline]
pub fn any(&self) -> bool {
self.x || self.y
}
}
impl From<bool> for Vec2b {
#[inline]
fn from(val: bool) -> Self {
Vec2b { x: val, y: val }
}
}
impl From<[bool; 2]> for Vec2b {
#[inline]
fn from([x, y]: [bool; 2]) -> Self {
Vec2b { x, y }
}
}
impl std::ops::Index<usize> for Vec2b {
type Output = bool;
#[inline(always)]
fn index(&self, index: usize) -> &bool {
match index {
0 => &self.x,
1 => &self.y,
_ => panic!("Vec2b index out of bounds: {index}"),
}
}
}
impl std::ops::IndexMut<usize> for Vec2b {
#[inline(always)]
fn index_mut(&mut self, index: usize) -> &mut bool {
match index {
0 => &mut self.x,
1 => &mut self.y,
_ => panic!("Vec2b index out of bounds: {index}"),
}
}
}

2
examples/images/src/main.rs

@ -25,7 +25,7 @@ struct MyApp {}
impl eframe::App for MyApp { impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
egui::ScrollArea::new([true, true]).show(ui, |ui| { egui::ScrollArea::both().show(ui, |ui| {
ui.image(egui::include_image!("ferris.svg")); ui.image(egui::include_image!("ferris.svg"));
ui.add( ui.add(

2
examples/keyboard_events/src/main.rs

@ -26,7 +26,7 @@ impl eframe::App for Content {
self.text.clear(); self.text.clear();
} }
ScrollArea::vertical() ScrollArea::vertical()
.auto_shrink([false; 2]) .auto_shrink(false)
.stick_to_bottom(true) .stick_to_bottom(true)
.show(ui, |ui| { .show(ui, |ui| {
ui.label(&self.text); ui.label(&self.text);

Loading…
Cancel
Save