mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 14:20:04 -04:00
Add ScrollArea::content_margin (#7722)
* Part of https://github.com/emilk/egui/issues/5605 * Part of https://github.com/emilk/egui/issues/3385
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
|
//! See [`ScrollArea`] for docs.
|
||||||
|
|
||||||
#![allow(clippy::needless_range_loop)]
|
#![allow(clippy::needless_range_loop)]
|
||||||
|
|
||||||
use std::ops::{Add, AddAssign, BitOr, BitOrAssign};
|
use std::ops::{Add, AddAssign, BitOr, BitOrAssign};
|
||||||
|
|
||||||
use emath::GuiRounding as _;
|
use emath::GuiRounding as _;
|
||||||
|
use epaint::Margin;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Context, CursorIcon, Id, NumExt as _, Pos2, Rangef, Rect, Response, Sense, Ui, UiBuilder,
|
Context, CursorIcon, Id, NumExt as _, Pos2, Rangef, Rect, Response, Sense, Ui, UiBuilder,
|
||||||
@@ -258,7 +261,7 @@ impl AddAssign for ScrollSource {
|
|||||||
/// ### Coordinate system
|
/// ### Coordinate system
|
||||||
/// * content: size of contents (generally large; that's why we want scroll bars)
|
/// * content: size of contents (generally large; that's why we want scroll bars)
|
||||||
/// * outer: size of scroll area including scroll bar(s)
|
/// * outer: size of scroll area including scroll bar(s)
|
||||||
/// * inner: excluding scroll bar(s). The area we clip the contents to.
|
/// * inner: excluding scroll bar(s). The area we clip the contents to. Includes `content_margin`.
|
||||||
///
|
///
|
||||||
/// If the floating scroll bars settings is turned on then `inner == outer`.
|
/// If the floating scroll bars settings is turned on then `inner == outer`.
|
||||||
///
|
///
|
||||||
@@ -294,6 +297,8 @@ pub struct ScrollArea {
|
|||||||
scroll_source: ScrollSource,
|
scroll_source: ScrollSource,
|
||||||
wheel_scroll_multiplier: Vec2,
|
wheel_scroll_multiplier: Vec2,
|
||||||
|
|
||||||
|
content_margin: Option<Margin>,
|
||||||
|
|
||||||
/// 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.
|
||||||
@@ -346,6 +351,7 @@ impl ScrollArea {
|
|||||||
on_drag_cursor: None,
|
on_drag_cursor: None,
|
||||||
scroll_source: ScrollSource::default(),
|
scroll_source: ScrollSource::default(),
|
||||||
wheel_scroll_multiplier: Vec2::splat(1.0),
|
wheel_scroll_multiplier: Vec2::splat(1.0),
|
||||||
|
content_margin: None,
|
||||||
stick_to_end: Vec2b::FALSE,
|
stick_to_end: Vec2b::FALSE,
|
||||||
animated: true,
|
animated: true,
|
||||||
}
|
}
|
||||||
@@ -593,6 +599,18 @@ impl ScrollArea {
|
|||||||
self.direction_enabled[0] || self.direction_enabled[1]
|
self.direction_enabled[0] || self.direction_enabled[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extra margin added around the contents.
|
||||||
|
///
|
||||||
|
/// The scroll bars will be either on top of this margin, or outside of it,
|
||||||
|
/// depending on the value of [`crate::style::ScrollStyle::floating`].
|
||||||
|
///
|
||||||
|
/// Default: [`crate::style::ScrollStyle::content_margin`].
|
||||||
|
#[inline]
|
||||||
|
pub fn content_margin(mut self, margin: impl Into<Margin>) -> Self {
|
||||||
|
self.content_margin = Some(margin.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// The scroll handle will stick to the rightmost position even while the content size
|
/// The scroll handle will stick to the rightmost position even while the content size
|
||||||
/// changes dynamically. This can be useful to simulate text scrollers coming in from right
|
/// changes dynamically. This can be useful to simulate text scrollers coming in from right
|
||||||
/// hand side. The scroll handle remains stuck until user manually changes position. Once "unstuck"
|
/// hand side. The scroll handle remains stuck until user manually changes position. Once "unstuck"
|
||||||
@@ -644,7 +662,7 @@ struct Prepared {
|
|||||||
scroll_bar_visibility: ScrollBarVisibility,
|
scroll_bar_visibility: ScrollBarVisibility,
|
||||||
scroll_bar_rect: Option<Rect>,
|
scroll_bar_rect: Option<Rect>,
|
||||||
|
|
||||||
/// Where on the screen the content is (excludes scroll bars).
|
/// Where on the screen the content is (excludes scroll bars; includes `content_margin`).
|
||||||
inner_rect: Rect,
|
inner_rect: Rect,
|
||||||
|
|
||||||
content_ui: Ui,
|
content_ui: Ui,
|
||||||
@@ -683,6 +701,7 @@ impl ScrollArea {
|
|||||||
on_drag_cursor,
|
on_drag_cursor,
|
||||||
scroll_source,
|
scroll_source,
|
||||||
wheel_scroll_multiplier,
|
wheel_scroll_multiplier,
|
||||||
|
content_margin: _, // Used elsewhere
|
||||||
stick_to_end,
|
stick_to_end,
|
||||||
animated,
|
animated,
|
||||||
} = self;
|
} = self;
|
||||||
@@ -983,10 +1002,21 @@ impl ScrollArea {
|
|||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
add_contents: Box<dyn FnOnce(&mut Ui, Rect) -> R + 'c>,
|
add_contents: Box<dyn FnOnce(&mut Ui, Rect) -> R + 'c>,
|
||||||
) -> ScrollAreaOutput<R> {
|
) -> ScrollAreaOutput<R> {
|
||||||
|
let margin = self
|
||||||
|
.content_margin
|
||||||
|
.unwrap_or_else(|| ui.spacing().scroll.content_margin);
|
||||||
|
|
||||||
let mut prepared = self.begin(ui);
|
let mut prepared = self.begin(ui);
|
||||||
let id = prepared.id;
|
let id = prepared.id;
|
||||||
let inner_rect = prepared.inner_rect;
|
let inner_rect = prepared.inner_rect;
|
||||||
let inner = add_contents(&mut prepared.content_ui, prepared.viewport);
|
|
||||||
|
let inner = crate::Frame::NONE
|
||||||
|
.inner_margin(margin)
|
||||||
|
.show(&mut prepared.content_ui, |ui| {
|
||||||
|
add_contents(ui, prepared.viewport)
|
||||||
|
})
|
||||||
|
.inner;
|
||||||
|
|
||||||
let (content_size, state) = prepared.end(ui);
|
let (content_size, state) = prepared.end(ui);
|
||||||
ScrollAreaOutput {
|
ScrollAreaOutput {
|
||||||
inner,
|
inner,
|
||||||
|
|||||||
@@ -508,6 +508,12 @@ pub struct ScrollStyle {
|
|||||||
/// it more promiment.
|
/// it more promiment.
|
||||||
pub floating: bool,
|
pub floating: bool,
|
||||||
|
|
||||||
|
/// Extra margin added around the contents of a [`crate::ScrollArea`].
|
||||||
|
///
|
||||||
|
/// The scroll bars will be either on top of this margin, or outside of it,
|
||||||
|
/// depending on the value of [`Self::floating`].
|
||||||
|
pub content_margin: Margin,
|
||||||
|
|
||||||
/// The width of the scroll bars at it largest.
|
/// The width of the scroll bars at it largest.
|
||||||
pub bar_width: f32,
|
pub bar_width: f32,
|
||||||
|
|
||||||
@@ -591,6 +597,7 @@ impl ScrollStyle {
|
|||||||
pub fn solid() -> Self {
|
pub fn solid() -> Self {
|
||||||
Self {
|
Self {
|
||||||
floating: false,
|
floating: false,
|
||||||
|
content_margin: Margin::ZERO,
|
||||||
bar_width: 6.0,
|
bar_width: 6.0,
|
||||||
handle_min_length: 12.0,
|
handle_min_length: 12.0,
|
||||||
bar_inner_margin: 4.0,
|
bar_inner_margin: 4.0,
|
||||||
@@ -672,6 +679,9 @@ impl ScrollStyle {
|
|||||||
pub fn details_ui(&mut self, ui: &mut Ui) {
|
pub fn details_ui(&mut self, ui: &mut Ui) {
|
||||||
let Self {
|
let Self {
|
||||||
floating,
|
floating,
|
||||||
|
|
||||||
|
content_margin,
|
||||||
|
|
||||||
bar_width,
|
bar_width,
|
||||||
handle_min_length,
|
handle_min_length,
|
||||||
bar_inner_margin,
|
bar_inner_margin,
|
||||||
@@ -695,6 +705,11 @@ impl ScrollStyle {
|
|||||||
ui.selectable_value(floating, true, "Floating");
|
ui.selectable_value(floating, true, "Floating");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Content margin:");
|
||||||
|
content_margin.ui(ui);
|
||||||
|
});
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(DragValue::new(bar_width).range(0.0..=32.0));
|
ui.add(DragValue::new(bar_width).range(0.0..=32.0));
|
||||||
ui.label("Full bar width");
|
ui.label("Full bar width");
|
||||||
@@ -1824,6 +1839,10 @@ impl Spacing {
|
|||||||
ui.add(window_margin);
|
ui.add(window_margin);
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
|
ui.label("ScrollArea margin");
|
||||||
|
scroll.content_margin.ui(ui);
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Menu margin");
|
ui.label("Menu margin");
|
||||||
ui.add(menu_margin);
|
ui.add(menu_margin);
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|||||||
Reference in New Issue
Block a user