Skip to content

Commit

Permalink
Per-side margins with new struct Margin (#1219)
Browse files Browse the repository at this point in the history
  • Loading branch information
lampsitter authored Feb 7, 2022
1 parent 603ec82 commit 2802e03
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
* `TextStyle` is no longer `Copy` ([#1154](https://github.com/emilk/egui/pull/1154)).
* Replaced `TextEdit::text_style` with `TextEdit::font` ([#1154](https://github.com/emilk/egui/pull/1154)).
* Replaced `corner_radius: f32` with `rounding: Rounding`, allowing per-corner rounding settings ([#1206](https://github.com/emilk/egui/pull/1206)).
* Replaced Frame's `margin: Vec2` with `margin: Margin`, allowing for different margins on opposing sides ([#1219](https://github.com/emilk/egui/pull/1219)).
* `Plot::highlight` now takes a `bool` argument ([#1159](https://github.com/emilk/egui/pull/1159)).
* `ScrollArea::show` now returns a `ScrollAreaOutput`, so you might need to add `.inner` after the call to it ([#1166](https://github.com/emilk/egui/pull/1166)).

Expand Down
71 changes: 60 additions & 11 deletions egui/src/containers/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,55 @@
use crate::{layers::ShapeIdx, *};
use epaint::*;

#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Margin {
pub left: f32,
pub right: f32,
pub top: f32,
pub bottom: f32,
}

impl Margin {
#[inline]
pub fn same(margin: f32) -> Self {
Self {
left: margin,
right: margin,
top: margin,
bottom: margin,
}
}

/// Margins with the same size on opposing sides
#[inline]
pub fn symmetric(x: f32, y: f32) -> Self {
Self {
left: x,
right: x,
top: y,
bottom: y,
}
}

/// Total margins on both sides
pub fn sum(&self) -> Vec2 {
Vec2::new(self.left + self.right, self.top + self.bottom)
}
}

impl From<Vec2> for Margin {
fn from(v: Vec2) -> Self {
Self::symmetric(v.x, v.y)
}
}

/// Color and margin of a rectangular background of a [`Ui`].
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[must_use = "You should call .show()"]
pub struct Frame {
/// On each side
pub margin: Vec2,
pub margin: Margin,
pub rounding: Rounding,
pub shadow: Shadow,
pub fill: Color32,
Expand All @@ -23,7 +66,7 @@ impl Frame {
/// For when you want to group a few widgets together within a frame.
pub fn group(style: &Style) -> Self {
Self {
margin: Vec2::splat(6.0), // symmetric looks best in corners when nesting
margin: Margin::same(6.0), // symmetric looks best in corners when nesting
rounding: style.visuals.widgets.noninteractive.rounding,
stroke: style.visuals.widgets.noninteractive.bg_stroke,
..Default::default()
Expand All @@ -32,7 +75,7 @@ impl Frame {

pub(crate) fn side_top_panel(style: &Style) -> Self {
Self {
margin: Vec2::new(8.0, 2.0),
margin: Margin::symmetric(8.0, 2.0),
rounding: Rounding::none(),
fill: style.visuals.window_fill(),
stroke: style.visuals.window_stroke(),
Expand All @@ -42,7 +85,7 @@ impl Frame {

pub(crate) fn central_panel(style: &Style) -> Self {
Self {
margin: Vec2::new(8.0, 8.0),
margin: Margin::symmetric(8.0, 8.0),
rounding: Rounding::none(),
fill: style.visuals.window_fill(),
stroke: Default::default(),
Expand All @@ -52,7 +95,7 @@ impl Frame {

pub fn window(style: &Style) -> Self {
Self {
margin: style.spacing.window_padding,
margin: style.spacing.window_margin,
rounding: style.visuals.window_rounding,
shadow: style.visuals.window_shadow,
fill: style.visuals.window_fill(),
Expand All @@ -62,7 +105,7 @@ impl Frame {

pub fn menu(style: &Style) -> Self {
Self {
margin: Vec2::splat(1.0),
margin: Margin::same(1.0),
rounding: style.visuals.widgets.noninteractive.rounding,
shadow: style.visuals.popup_shadow,
fill: style.visuals.window_fill(),
Expand All @@ -72,7 +115,7 @@ impl Frame {

pub fn popup(style: &Style) -> Self {
Self {
margin: style.spacing.window_padding,
margin: style.spacing.window_margin,
rounding: style.visuals.widgets.noninteractive.rounding,
shadow: style.visuals.popup_shadow,
fill: style.visuals.window_fill(),
Expand All @@ -83,7 +126,7 @@ impl Frame {
/// dark canvas to draw on
pub fn dark_canvas(style: &Style) -> Self {
Self {
margin: Vec2::new(10.0, 10.0),
margin: Margin::symmetric(10.0, 10.0),
rounding: style.visuals.widgets.noninteractive.rounding,
fill: Color32::from_black_alpha(250),
stroke: style.visuals.window_stroke(),
Expand All @@ -109,7 +152,7 @@ impl Frame {
}

/// Margin on each side of the frame.
pub fn margin(mut self, margin: impl Into<Vec2>) -> Self {
pub fn margin(mut self, margin: impl Into<Margin>) -> Self {
self.margin = margin.into();
self
}
Expand Down Expand Up @@ -137,7 +180,10 @@ impl Frame {
pub fn begin(self, ui: &mut Ui) -> Prepared {
let where_to_put_background = ui.painter().add(Shape::Noop);
let outer_rect_bounds = ui.available_rect_before_wrap();
let mut inner_rect = outer_rect_bounds.shrink2(self.margin);

let mut inner_rect = outer_rect_bounds;
inner_rect.min += Vec2::new(self.margin.left, self.margin.top);
inner_rect.max -= Vec2::new(self.margin.right, self.margin.bottom);

// Make sure we don't shrink to the negative:
inner_rect.max.x = inner_rect.max.x.max(inner_rect.min.x);
Expand Down Expand Up @@ -197,7 +243,10 @@ impl Frame {

impl Prepared {
pub fn outer_rect(&self) -> Rect {
self.content_ui.min_rect().expand2(self.frame.margin)
let mut rect = self.content_ui.min_rect();
rect.min -= Vec2::new(self.frame.margin.left, self.frame.margin.top);
rect.max += Vec2::new(self.frame.margin.right, self.frame.margin.bottom);
rect
}

pub fn end(self, ui: &mut Ui) -> Response {
Expand Down
2 changes: 1 addition & 1 deletion egui/src/containers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub use {
area::Area,
collapsing_header::{CollapsingHeader, CollapsingResponse},
combo_box::*,
frame::Frame,
frame::{Frame, Margin},
panel::{CentralPanel, SidePanel, TopBottomPanel},
popup::*,
resize::Resize,
Expand Down
2 changes: 1 addition & 1 deletion egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ pub fn popup_below_widget<R>(
frame
.show(ui, |ui| {
ui.with_layout(Layout::top_down_justified(Align::LEFT), |ui| {
ui.set_width(widget_response.rect.width() - 2.0 * frame_margin.x);
ui.set_width(widget_response.rect.width() - frame_margin.sum().x);
add_contents(ui)
})
.inner
Expand Down
2 changes: 1 addition & 1 deletion egui/src/containers/resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl Resize {
.at_least(self.min_size)
.at_most(self.max_size)
.at_most(
ui.input().screen_rect().size() - 2.0 * ui.spacing().window_padding, // hack for windows
ui.input().screen_rect().size() - ui.spacing().window_margin.sum(), // hack for windows
);

State {
Expand Down
2 changes: 1 addition & 1 deletion egui/src/containers/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ impl<'open> Window<'open> {
} else {
0.0
};
let margins = 2.0 * frame.margin + vec2(0.0, title_bar_height);
let margins = frame.margin.sum() + vec2(0.0, title_bar_height);

interact(
window_interaction,
Expand Down
42 changes: 36 additions & 6 deletions egui/src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#![allow(clippy::if_same_then_else)]

use crate::{color::*, emath::*, FontFamily, FontId, Response, RichText, WidgetText};
use crate::{color::*, emath::*, FontFamily, FontId, Margin, Response, RichText, WidgetText};
use epaint::{mutex::Arc, Rounding, Shadow, Stroke};
use std::collections::BTreeMap;

Expand Down Expand Up @@ -220,8 +220,8 @@ pub struct Spacing {
/// widgets `A` and `B` you need to change `item_spacing` before adding `A`.
pub item_spacing: Vec2,

/// Horizontal and vertical padding within a window frame.
pub window_padding: Vec2,
/// Horizontal and vertical margins within a window frame.
pub window_margin: Margin,

/// Button size is text size plus this on each side
pub button_padding: Vec2,
Expand Down Expand Up @@ -528,7 +528,7 @@ impl Default for Spacing {
fn default() -> Self {
Self {
item_spacing: vec2(8.0, 3.0),
window_padding: Vec2::splat(6.0),
window_margin: Margin::same(6.0),
button_padding: vec2(4.0, 1.0),
indent: 18.0, // match checkbox/radio-button with `button_padding.x + icon_width + icon_spacing`
interact_size: vec2(40.0, 18.0),
Expand Down Expand Up @@ -803,7 +803,7 @@ impl Spacing {
pub fn ui(&mut self, ui: &mut crate::Ui) {
let Self {
item_spacing,
window_padding,
window_margin,
button_padding,
indent,
interact_size,
Expand All @@ -818,7 +818,37 @@ impl Spacing {
} = self;

ui.add(slider_vec2(item_spacing, 0.0..=20.0, "Item spacing"));
ui.add(slider_vec2(window_padding, 0.0..=20.0, "Window padding"));

let margin_range = 0.0..=20.0;
ui.horizontal(|ui| {
ui.add(
DragValue::new(&mut window_margin.left)
.clamp_range(margin_range.clone())
.prefix("left: "),
);
ui.add(
DragValue::new(&mut window_margin.right)
.clamp_range(margin_range.clone())
.prefix("right: "),
);

ui.label("Window margins x");
});

ui.horizontal(|ui| {
ui.add(
DragValue::new(&mut window_margin.top)
.clamp_range(margin_range.clone())
.prefix("top: "),
);
ui.add(
DragValue::new(&mut window_margin.bottom)
.clamp_range(margin_range)
.prefix("bottom: "),
);
ui.label("Window margins y");
});

ui.add(slider_vec2(button_padding, 0.0..=20.0, "Button padding"));
ui.add(slider_vec2(interact_size, 4.0..=60.0, "Interact size"))
.on_hover_text("Minimum size of an interactive widget");
Expand Down
2 changes: 1 addition & 1 deletion egui/src/widgets/plot/legend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl Widget for &mut LegendWidget {
legend_ui
.scope(|ui| {
let background_frame = Frame {
margin: vec2(8.0, 4.0),
margin: vec2(8.0, 4.0).into(),
rounding: ui.style().visuals.window_rounding,
shadow: epaint::Shadow::default(),
fill: ui.style().visuals.extreme_bg_color,
Expand Down

0 comments on commit 2802e03

Please sign in to comment.