mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 23:00:04 -04:00
modify enum Side to combine both vertical and horizontal sides & remove TopBottomSide
NOTE: Non-working commit
This commit is contained in:
@@ -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)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum Side {
|
pub enum VerticalSide {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
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 {
|
impl Side {
|
||||||
fn opposite(self) -> Self {
|
fn opposite(self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
Self::Left => Self::Right,
|
Side::Vertical(side) => opposite_vertical(side),
|
||||||
Self::Right => Self::Left,
|
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 {
|
match self {
|
||||||
Self::Left => rect.max.x = rect.min.x + width,
|
Side::Vertical(side) => set_rect_size_vertical(side),
|
||||||
Self::Right => rect.min.x = rect.max.x - width,
|
Side::Horizontal(side) => set_rect_size_horizontal(side),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn side_x(self, rect: Rect) -> f32 {
|
fn side_axe(self, rect: Rect) -> f32 {
|
||||||
match self {
|
match self {
|
||||||
Self::Left => rect.left(),
|
Side::Vertical(side) => side_axe_vertical(side, rect),
|
||||||
Self::Right => rect.right(),
|
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 {
|
fn sign(self) -> f32 {
|
||||||
match self {
|
match self {
|
||||||
Self::Left => -1.0,
|
Side::Vertical(side) => sign_vertical(side),
|
||||||
Self::Right => 1.0,
|
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`].
|
/// See also [`TopBottomPanel`].
|
||||||
#[must_use = "You should call .show()"]
|
#[must_use = "You should call .show()"]
|
||||||
pub struct SidePanel {
|
pub struct SidePanel {
|
||||||
side: Side,
|
side: OldSide,
|
||||||
id: Id,
|
id: Id,
|
||||||
frame: Option<Frame>,
|
frame: Option<Frame>,
|
||||||
resizable: bool,
|
resizable: bool,
|
||||||
@@ -119,16 +211,16 @@ pub struct SidePanel {
|
|||||||
impl SidePanel {
|
impl SidePanel {
|
||||||
/// The id should be globally unique, e.g. `Id::new("my_left_panel")`.
|
/// The id should be globally unique, e.g. `Id::new("my_left_panel")`.
|
||||||
pub fn left(id: impl Into<Id>) -> Self {
|
pub fn left(id: impl Into<Id>) -> Self {
|
||||||
Self::new(Side::Left, id)
|
Self::new(OldSide::Left, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The id should be globally unique, e.g. `Id::new("my_right_panel")`.
|
/// The id should be globally unique, e.g. `Id::new("my_right_panel")`.
|
||||||
pub fn right(id: impl Into<Id>) -> Self {
|
pub fn right(id: impl Into<Id>) -> Self {
|
||||||
Self::new(Side::Right, id)
|
Self::new(OldSide::Right, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The id should be globally unique, e.g. `Id::new("my_panel")`.
|
/// The id should be globally unique, e.g. `Id::new("my_panel")`.
|
||||||
pub fn new(side: Side, id: impl Into<Id>) -> Self {
|
pub fn new(side: OldSide, id: impl Into<Id>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
side,
|
side,
|
||||||
id: id.into(),
|
id: id.into(),
|
||||||
@@ -279,8 +371,8 @@ impl SidePanel {
|
|||||||
UiBuilder::new()
|
UiBuilder::new()
|
||||||
.id_salt(id)
|
.id_salt(id)
|
||||||
.ui_stack_info(UiStackInfo::new(match side {
|
.ui_stack_info(UiStackInfo::new(match side {
|
||||||
Side::Left => UiKind::LeftPanel,
|
OldSide::Left => UiKind::LeftPanel,
|
||||||
Side::Right => UiKind::RightPanel,
|
OldSide::Right => UiKind::RightPanel,
|
||||||
}))
|
}))
|
||||||
.max_rect(panel_rect)
|
.max_rect(panel_rect)
|
||||||
.layout(Layout::top_down(Align::Min)),
|
.layout(Layout::top_down(Align::Min)),
|
||||||
@@ -300,10 +392,10 @@ impl SidePanel {
|
|||||||
{
|
{
|
||||||
let mut cursor = ui.cursor();
|
let mut cursor = ui.cursor();
|
||||||
match side {
|
match side {
|
||||||
Side::Left => {
|
OldSide::Left => {
|
||||||
cursor.min.x = rect.max.x;
|
cursor.min.x = rect.max.x;
|
||||||
}
|
}
|
||||||
Side::Right => {
|
OldSide::Right => {
|
||||||
cursor.max.x = rect.min.x;
|
cursor.max.x = rect.min.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -326,15 +418,15 @@ impl SidePanel {
|
|||||||
if resize_hover || is_resizing {
|
if resize_hover || is_resizing {
|
||||||
let cursor_icon = if width <= width_range.min {
|
let cursor_icon = if width <= width_range.min {
|
||||||
match self.side {
|
match self.side {
|
||||||
Side::Left => CursorIcon::ResizeEast,
|
OldSide::Left => CursorIcon::ResizeEast,
|
||||||
Side::Right => CursorIcon::ResizeWest,
|
OldSide::Right => CursorIcon::ResizeWest,
|
||||||
}
|
}
|
||||||
} else if width < width_range.max {
|
} else if width < width_range.max {
|
||||||
CursorIcon::ResizeHorizontal
|
CursorIcon::ResizeHorizontal
|
||||||
} else {
|
} else {
|
||||||
match self.side {
|
match self.side {
|
||||||
Side::Left => CursorIcon::ResizeWest,
|
OldSide::Left => CursorIcon::ResizeWest,
|
||||||
Side::Right => CursorIcon::ResizeEast,
|
OldSide::Right => CursorIcon::ResizeEast,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ui.ctx().set_cursor_icon(cursor_icon);
|
ui.ctx().set_cursor_icon(cursor_icon);
|
||||||
@@ -394,10 +486,10 @@ impl SidePanel {
|
|||||||
let rect = inner_response.response.rect;
|
let rect = inner_response.response.rect;
|
||||||
|
|
||||||
match side {
|
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));
|
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));
|
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.
|
/// A panel that covers the entire top or bottom of a [`Ui`] or screen.
|
||||||
///
|
///
|
||||||
/// The order in which you add panels matter!
|
/// The order in which you add panels matter!
|
||||||
@@ -594,7 +649,7 @@ impl TopBottomSide {
|
|||||||
/// See also [`SidePanel`].
|
/// See also [`SidePanel`].
|
||||||
#[must_use = "You should call .show()"]
|
#[must_use = "You should call .show()"]
|
||||||
pub struct TopBottomPanel {
|
pub struct TopBottomPanel {
|
||||||
side: TopBottomSide,
|
side: OldTopBottomSide,
|
||||||
id: Id,
|
id: Id,
|
||||||
frame: Option<Frame>,
|
frame: Option<Frame>,
|
||||||
resizable: bool,
|
resizable: bool,
|
||||||
@@ -606,16 +661,16 @@ pub struct TopBottomPanel {
|
|||||||
impl TopBottomPanel {
|
impl TopBottomPanel {
|
||||||
/// The id should be globally unique, e.g. `Id::new("my_top_panel")`.
|
/// The id should be globally unique, e.g. `Id::new("my_top_panel")`.
|
||||||
pub fn top(id: impl Into<Id>) -> Self {
|
pub fn top(id: impl Into<Id>) -> Self {
|
||||||
Self::new(TopBottomSide::Top, id)
|
Self::new(OldTopBottomSide::Top, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The id should be globally unique, e.g. `Id::new("my_bottom_panel")`.
|
/// The id should be globally unique, e.g. `Id::new("my_bottom_panel")`.
|
||||||
pub fn bottom(id: impl Into<Id>) -> Self {
|
pub fn bottom(id: impl Into<Id>) -> Self {
|
||||||
Self::new(TopBottomSide::Bottom, id)
|
Self::new(OldTopBottomSide::Bottom, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The id should be globally unique, e.g. `Id::new("my_panel")`.
|
/// The id should be globally unique, e.g. `Id::new("my_panel")`.
|
||||||
pub fn new(side: TopBottomSide, id: impl Into<Id>) -> Self {
|
pub fn new(side: OldTopBottomSide, id: impl Into<Id>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
side,
|
side,
|
||||||
id: id.into(),
|
id: id.into(),
|
||||||
@@ -776,8 +831,8 @@ impl TopBottomPanel {
|
|||||||
UiBuilder::new()
|
UiBuilder::new()
|
||||||
.id_salt(id)
|
.id_salt(id)
|
||||||
.ui_stack_info(UiStackInfo::new(match side {
|
.ui_stack_info(UiStackInfo::new(match side {
|
||||||
TopBottomSide::Top => UiKind::TopPanel,
|
OldTopBottomSide::Top => UiKind::TopPanel,
|
||||||
TopBottomSide::Bottom => UiKind::BottomPanel,
|
OldTopBottomSide::Bottom => UiKind::BottomPanel,
|
||||||
}))
|
}))
|
||||||
.max_rect(panel_rect)
|
.max_rect(panel_rect)
|
||||||
.layout(Layout::top_down(Align::Min)),
|
.layout(Layout::top_down(Align::Min)),
|
||||||
@@ -796,10 +851,10 @@ impl TopBottomPanel {
|
|||||||
{
|
{
|
||||||
let mut cursor = ui.cursor();
|
let mut cursor = ui.cursor();
|
||||||
match side {
|
match side {
|
||||||
TopBottomSide::Top => {
|
OldTopBottomSide::Top => {
|
||||||
cursor.min.y = rect.max.y;
|
cursor.min.y = rect.max.y;
|
||||||
}
|
}
|
||||||
TopBottomSide::Bottom => {
|
OldTopBottomSide::Bottom => {
|
||||||
cursor.max.y = rect.min.y;
|
cursor.max.y = rect.min.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -823,15 +878,15 @@ impl TopBottomPanel {
|
|||||||
if resize_hover || is_resizing {
|
if resize_hover || is_resizing {
|
||||||
let cursor_icon = if height <= height_range.min {
|
let cursor_icon = if height <= height_range.min {
|
||||||
match self.side {
|
match self.side {
|
||||||
TopBottomSide::Top => CursorIcon::ResizeSouth,
|
OldTopBottomSide::Top => CursorIcon::ResizeSouth,
|
||||||
TopBottomSide::Bottom => CursorIcon::ResizeNorth,
|
OldTopBottomSide::Bottom => CursorIcon::ResizeNorth,
|
||||||
}
|
}
|
||||||
} else if height < height_range.max {
|
} else if height < height_range.max {
|
||||||
CursorIcon::ResizeVertical
|
CursorIcon::ResizeVertical
|
||||||
} else {
|
} else {
|
||||||
match self.side {
|
match self.side {
|
||||||
TopBottomSide::Top => CursorIcon::ResizeNorth,
|
OldTopBottomSide::Top => CursorIcon::ResizeNorth,
|
||||||
TopBottomSide::Bottom => CursorIcon::ResizeSouth,
|
OldTopBottomSide::Bottom => CursorIcon::ResizeSouth,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ui.ctx().set_cursor_icon(cursor_icon);
|
ui.ctx().set_cursor_icon(cursor_icon);
|
||||||
@@ -892,12 +947,12 @@ impl TopBottomPanel {
|
|||||||
let rect = inner_response.response.rect;
|
let rect = inner_response.response.rect;
|
||||||
|
|
||||||
match side {
|
match side {
|
||||||
TopBottomSide::Top => {
|
OldTopBottomSide::Top => {
|
||||||
ctx.pass_state_mut(|state| {
|
ctx.pass_state_mut(|state| {
|
||||||
state.allocate_top_panel(Rect::from_min_max(available_rect.min, rect.max));
|
state.allocate_top_panel(Rect::from_min_max(available_rect.min, rect.max));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
TopBottomSide::Bottom => {
|
OldTopBottomSide::Bottom => {
|
||||||
ctx.pass_state_mut(|state| {
|
ctx.pass_state_mut(|state| {
|
||||||
state.allocate_bottom_panel(Rect::from_min_max(rect.min, available_rect.max));
|
state.allocate_bottom_panel(Rect::from_min_max(rect.min, available_rect.max));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use egui::emath::Rot2;
|
use egui::emath::Rot2;
|
||||||
|
use egui::panel::HorizontalSide;
|
||||||
use egui::panel::Side;
|
use egui::panel::Side;
|
||||||
use egui::panel::TopBottomSide;
|
use egui::panel::VerticalSide;
|
||||||
use egui::ImageFit;
|
use egui::ImageFit;
|
||||||
use egui::Slider;
|
use egui::Slider;
|
||||||
use egui::Vec2;
|
use egui::Vec2;
|
||||||
@@ -52,28 +53,31 @@ impl Default for ImageViewer {
|
|||||||
|
|
||||||
impl eframe::App for ImageViewer {
|
impl eframe::App for ImageViewer {
|
||||||
fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
|
||||||
egui::TopBottomPanel::new(TopBottomSide::Top, "url bar").show(ctx, |ui| {
|
egui::TopBottomPanel::new(Side::Horizontal(HorizontalSide::Top), "url bar").show(
|
||||||
ui.horizontal_centered(|ui| {
|
ctx,
|
||||||
let label = ui.label("URI:");
|
|ui| {
|
||||||
ui.text_edit_singleline(&mut self.uri_edit_text)
|
ui.horizontal_centered(|ui| {
|
||||||
.labelled_by(label.id);
|
let label = ui.label("URI:");
|
||||||
if ui.small_button("✔").clicked() {
|
ui.text_edit_singleline(&mut self.uri_edit_text)
|
||||||
ctx.forget_image(&self.current_uri);
|
.labelled_by(label.id);
|
||||||
self.uri_edit_text = self.uri_edit_text.trim().to_owned();
|
if ui.small_button("✔").clicked() {
|
||||||
self.current_uri = self.uri_edit_text.clone();
|
ctx.forget_image(&self.current_uri);
|
||||||
};
|
self.uri_edit_text = self.uri_edit_text.trim().to_owned();
|
||||||
|
|
||||||
#[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();
|
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
|
// uv
|
||||||
ui.label("UV");
|
ui.label("UV");
|
||||||
ui.add(Slider::new(&mut self.image_options.uv.min.x, 0.0..=1.0).text("min x"));
|
ui.add(Slider::new(&mut self.image_options.uv.min.x, 0.0..=1.0).text("min x"));
|
||||||
|
|||||||
Reference in New Issue
Block a user