diff --git a/crates/egui/src/containers/panel.rs b/crates/egui/src/containers/panel.rs
index 6fd19e186..6e7291379 100644
--- a/crates/egui/src/containers/panel.rs
+++ b/crates/egui/src/containers/panel.rs
@@ -50,39 +50,131 @@ impl PanelState {
// ----------------------------------------------------------------------------
-/// [`Left`](Side::Left) or [`Right`](Side::Right)
+/// [`Left`](VerticalSide::Left) or [`Right`](VerticalSide::Right)
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum Side {
+pub enum VerticalSide {
Left,
Right,
}
+/// [`Top`](HorizontalSide::Top) or [`Bottom`](HorizontalSide::Bottom)
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum HorizontalSide {
+ Top,
+ Bottom,
+}
+
+/// [`Horizontal`](Side::Horizontal) or [`Vertical`](Side::Vertical)
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum Side {
+ Vertical(VerticalSide),
+ Horizontal(HorizontalSide),
+}
+
impl Side {
fn opposite(self) -> Self {
match self {
- Self::Left => Self::Right,
- Self::Right => Self::Left,
+ Side::Vertical(side) => opposite_vertical(side),
+ Side::Horizontal(side) => opposite_horizontal(side),
+ }
+
+ fn opposite_vertical(
+ side: VerticalSide,
+ ) -> Side {
+ match side {
+ VerticalSide::Left => {
+ Side::Vertical(
+ VerticalSide::Right,
+ )
+ }
+ VerticalSide::Right => {
+ Side::Vertical(
+ VerticalSide::Left,
+ )
+ }
+ }
+ }
+
+ fn opposite_horizontal(
+ side: HorizontalSide,
+ ) -> Side {
+ match side {
+ HorizontalSide::Top => {
+ Side::Horizontal(
+ HorizontalSide::Bottom,
+ )
+ }
+ HorizontalSide::Bottom => {
+ Side::Horizontal(
+ HorizontalSide::Top,
+ )
+ }
+ }
}
}
- fn set_rect_width(self, rect: &mut Rect, width: f32) {
+ fn set_rect_size(self, rect: &mut Rect, size: f32) {
+ let set_rect_size_vertical = |side: VerticalSide| match side {
+ VerticalSide::Left => rect.max.x = rect.min.x + size,
+ VerticalSide::Right => rect.min.x = rect.max.x - size,
+ };
+
+ let set_rect_size_horizontal =
+ |side: HorizontalSide| match side {
+ HorizontalSide::Top => rect.max.y = rect.min.y + size,
+ HorizontalSide::Bottom => {
+ rect.min.y = rect.max.y - size
+ }
+ };
+
match self {
- Self::Left => rect.max.x = rect.min.x + width,
- Self::Right => rect.min.x = rect.max.x - width,
+ Side::Vertical(side) => set_rect_size_vertical(side),
+ Side::Horizontal(side) => set_rect_size_horizontal(side),
}
}
- fn side_x(self, rect: Rect) -> f32 {
+ fn side_axe(self, rect: Rect) -> f32 {
match self {
- Self::Left => rect.left(),
- Self::Right => rect.right(),
+ Side::Vertical(side) => side_axe_vertical(side, rect),
+ Side::Horizontal(side) => side_axe_horizontal(side, rect),
+ }
+
+ fn side_axe_vertical(side: VerticalSide, rect: Rect) -> f32 {
+ match side {
+ VerticalSide::Left => rect.left(),
+ VerticalSide::Right => rect.right(),
+ }
+ }
+
+ fn side_axe_horizontal(
+ side: HorizontalSide,
+ rect: Rect,
+ ) -> f32 {
+ match side {
+ HorizontalSide::Top => rect.top(),
+ HorizontalSide::Bottom => rect.bottom(),
+ }
}
}
fn sign(self) -> f32 {
match self {
- Self::Left => -1.0,
- Self::Right => 1.0,
+ Side::Vertical(side) => sign_vertical(side),
+ Side::Horizontal(side) => sign_horizontal(side),
+ }
+
+ fn sign_vertical(side: VerticalSide) -> f32 {
+ match side {
+ VerticalSide::Left => -1.0,
+ VerticalSide::Right => 1.0,
+ }
+ }
+
+ fn sign_horizontal(side: HorizontalSide) -> f32 {
+ match side {
+ HorizontalSide::Top => -1.0,
+ HorizontalSide::Bottom => 1.0,
+ }
}
}
}
@@ -107,7 +199,7 @@ impl Side {
/// See also [`TopBottomPanel`].
#[must_use = "You should call .show()"]
pub struct SidePanel {
- side: Side,
+ side: OldSide,
id: Id,
frame: Option,
resizable: bool,
@@ -119,16 +211,16 @@ pub struct SidePanel {
impl SidePanel {
/// The id should be globally unique, e.g. `Id::new("my_left_panel")`.
pub fn left(id: impl Into) -> Self {
- Self::new(Side::Left, id)
+ Self::new(OldSide::Left, id)
}
/// The id should be globally unique, e.g. `Id::new("my_right_panel")`.
pub fn right(id: impl Into) -> Self {
- Self::new(Side::Right, id)
+ Self::new(OldSide::Right, id)
}
/// The id should be globally unique, e.g. `Id::new("my_panel")`.
- pub fn new(side: Side, id: impl Into) -> Self {
+ pub fn new(side: OldSide, id: impl Into) -> Self {
Self {
side,
id: id.into(),
@@ -279,8 +371,8 @@ impl SidePanel {
UiBuilder::new()
.id_salt(id)
.ui_stack_info(UiStackInfo::new(match side {
- Side::Left => UiKind::LeftPanel,
- Side::Right => UiKind::RightPanel,
+ OldSide::Left => UiKind::LeftPanel,
+ OldSide::Right => UiKind::RightPanel,
}))
.max_rect(panel_rect)
.layout(Layout::top_down(Align::Min)),
@@ -300,10 +392,10 @@ impl SidePanel {
{
let mut cursor = ui.cursor();
match side {
- Side::Left => {
+ OldSide::Left => {
cursor.min.x = rect.max.x;
}
- Side::Right => {
+ OldSide::Right => {
cursor.max.x = rect.min.x;
}
}
@@ -326,15 +418,15 @@ impl SidePanel {
if resize_hover || is_resizing {
let cursor_icon = if width <= width_range.min {
match self.side {
- Side::Left => CursorIcon::ResizeEast,
- Side::Right => CursorIcon::ResizeWest,
+ OldSide::Left => CursorIcon::ResizeEast,
+ OldSide::Right => CursorIcon::ResizeWest,
}
} else if width < width_range.max {
CursorIcon::ResizeHorizontal
} else {
match self.side {
- Side::Left => CursorIcon::ResizeWest,
- Side::Right => CursorIcon::ResizeEast,
+ OldSide::Left => CursorIcon::ResizeWest,
+ OldSide::Right => CursorIcon::ResizeEast,
}
};
ui.ctx().set_cursor_icon(cursor_icon);
@@ -394,10 +486,10 @@ impl SidePanel {
let rect = inner_response.response.rect;
match side {
- Side::Left => ctx.pass_state_mut(|state| {
+ OldSide::Left => ctx.pass_state_mut(|state| {
state.allocate_left_panel(Rect::from_min_max(available_rect.min, rect.max));
}),
- Side::Right => ctx.pass_state_mut(|state| {
+ OldSide::Right => ctx.pass_state_mut(|state| {
state.allocate_right_panel(Rect::from_min_max(rect.min, available_rect.max));
}),
}
@@ -537,43 +629,6 @@ impl SidePanel {
// ----------------------------------------------------------------------------
-/// [`Top`](TopBottomSide::Top) or [`Bottom`](TopBottomSide::Bottom)
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum TopBottomSide {
- Top,
- Bottom,
-}
-
-impl TopBottomSide {
- fn opposite(self) -> Self {
- match self {
- Self::Top => Self::Bottom,
- Self::Bottom => Self::Top,
- }
- }
-
- fn set_rect_height(self, rect: &mut Rect, height: f32) {
- match self {
- Self::Top => rect.max.y = rect.min.y + height,
- Self::Bottom => rect.min.y = rect.max.y - height,
- }
- }
-
- fn side_y(self, rect: Rect) -> f32 {
- match self {
- Self::Top => rect.top(),
- Self::Bottom => rect.bottom(),
- }
- }
-
- fn sign(self) -> f32 {
- match self {
- Self::Top => -1.0,
- Self::Bottom => 1.0,
- }
- }
-}
-
/// A panel that covers the entire top or bottom of a [`Ui`] or screen.
///
/// The order in which you add panels matter!
@@ -594,7 +649,7 @@ impl TopBottomSide {
/// See also [`SidePanel`].
#[must_use = "You should call .show()"]
pub struct TopBottomPanel {
- side: TopBottomSide,
+ side: OldTopBottomSide,
id: Id,
frame: Option,
resizable: bool,
@@ -606,16 +661,16 @@ pub struct TopBottomPanel {
impl TopBottomPanel {
/// The id should be globally unique, e.g. `Id::new("my_top_panel")`.
pub fn top(id: impl Into) -> Self {
- Self::new(TopBottomSide::Top, id)
+ Self::new(OldTopBottomSide::Top, id)
}
/// The id should be globally unique, e.g. `Id::new("my_bottom_panel")`.
pub fn bottom(id: impl Into) -> Self {
- Self::new(TopBottomSide::Bottom, id)
+ Self::new(OldTopBottomSide::Bottom, id)
}
/// The id should be globally unique, e.g. `Id::new("my_panel")`.
- pub fn new(side: TopBottomSide, id: impl Into) -> Self {
+ pub fn new(side: OldTopBottomSide, id: impl Into) -> Self {
Self {
side,
id: id.into(),
@@ -776,8 +831,8 @@ impl TopBottomPanel {
UiBuilder::new()
.id_salt(id)
.ui_stack_info(UiStackInfo::new(match side {
- TopBottomSide::Top => UiKind::TopPanel,
- TopBottomSide::Bottom => UiKind::BottomPanel,
+ OldTopBottomSide::Top => UiKind::TopPanel,
+ OldTopBottomSide::Bottom => UiKind::BottomPanel,
}))
.max_rect(panel_rect)
.layout(Layout::top_down(Align::Min)),
@@ -796,10 +851,10 @@ impl TopBottomPanel {
{
let mut cursor = ui.cursor();
match side {
- TopBottomSide::Top => {
+ OldTopBottomSide::Top => {
cursor.min.y = rect.max.y;
}
- TopBottomSide::Bottom => {
+ OldTopBottomSide::Bottom => {
cursor.max.y = rect.min.y;
}
}
@@ -823,15 +878,15 @@ impl TopBottomPanel {
if resize_hover || is_resizing {
let cursor_icon = if height <= height_range.min {
match self.side {
- TopBottomSide::Top => CursorIcon::ResizeSouth,
- TopBottomSide::Bottom => CursorIcon::ResizeNorth,
+ OldTopBottomSide::Top => CursorIcon::ResizeSouth,
+ OldTopBottomSide::Bottom => CursorIcon::ResizeNorth,
}
} else if height < height_range.max {
CursorIcon::ResizeVertical
} else {
match self.side {
- TopBottomSide::Top => CursorIcon::ResizeNorth,
- TopBottomSide::Bottom => CursorIcon::ResizeSouth,
+ OldTopBottomSide::Top => CursorIcon::ResizeNorth,
+ OldTopBottomSide::Bottom => CursorIcon::ResizeSouth,
}
};
ui.ctx().set_cursor_icon(cursor_icon);
@@ -892,12 +947,12 @@ impl TopBottomPanel {
let rect = inner_response.response.rect;
match side {
- TopBottomSide::Top => {
+ OldTopBottomSide::Top => {
ctx.pass_state_mut(|state| {
state.allocate_top_panel(Rect::from_min_max(available_rect.min, rect.max));
});
}
- TopBottomSide::Bottom => {
+ OldTopBottomSide::Bottom => {
ctx.pass_state_mut(|state| {
state.allocate_bottom_panel(Rect::from_min_max(rect.min, available_rect.max));
});
diff --git a/crates/egui_demo_app/src/apps/image_viewer.rs b/crates/egui_demo_app/src/apps/image_viewer.rs
index 326718a23..c8f49e88b 100644
--- a/crates/egui_demo_app/src/apps/image_viewer.rs
+++ b/crates/egui_demo_app/src/apps/image_viewer.rs
@@ -1,6 +1,7 @@
use egui::emath::Rot2;
+use egui::panel::HorizontalSide;
use egui::panel::Side;
-use egui::panel::TopBottomSide;
+use egui::panel::VerticalSide;
use egui::ImageFit;
use egui::Slider;
use egui::Vec2;
@@ -52,28 +53,31 @@ impl Default for ImageViewer {
impl eframe::App for ImageViewer {
fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
- egui::TopBottomPanel::new(TopBottomSide::Top, "url bar").show(ctx, |ui| {
- ui.horizontal_centered(|ui| {
- let label = ui.label("URI:");
- ui.text_edit_singleline(&mut self.uri_edit_text)
- .labelled_by(label.id);
- if ui.small_button("✔").clicked() {
- ctx.forget_image(&self.current_uri);
- self.uri_edit_text = self.uri_edit_text.trim().to_owned();
- self.current_uri = self.uri_edit_text.clone();
- };
-
- #[cfg(not(target_arch = "wasm32"))]
- if ui.button("file…").clicked() {
- if let Some(path) = rfd::FileDialog::new().pick_file() {
- self.uri_edit_text = format!("file://{}", path.display());
+ egui::TopBottomPanel::new(Side::Horizontal(HorizontalSide::Top), "url bar").show(
+ ctx,
+ |ui| {
+ ui.horizontal_centered(|ui| {
+ let label = ui.label("URI:");
+ ui.text_edit_singleline(&mut self.uri_edit_text)
+ .labelled_by(label.id);
+ if ui.small_button("✔").clicked() {
+ ctx.forget_image(&self.current_uri);
+ self.uri_edit_text = self.uri_edit_text.trim().to_owned();
self.current_uri = self.uri_edit_text.clone();
- }
- }
- });
- });
+ };
- egui::SidePanel::new(Side::Left, "controls").show(ctx, |ui| {
+ #[cfg(not(target_arch = "wasm32"))]
+ if ui.button("file…").clicked() {
+ if let Some(path) = rfd::FileDialog::new().pick_file() {
+ self.uri_edit_text = format!("file://{}", path.display());
+ self.current_uri = self.uri_edit_text.clone();
+ }
+ }
+ });
+ },
+ );
+
+ egui::SidePanel::new(Side::Vertical(VerticalSide::Left), "controls").show(ctx, |ui| {
// uv
ui.label("UV");
ui.add(Slider::new(&mut self.image_options.uv.min.x, 0.0..=1.0).text("min x"));