Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure scroll bars are always visible #2371

Merged
merged 9 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG
* Improved text rendering ([#2071](https://github.com/emilk/egui/pull/2071)).
* Less jitter when calling `Context::set_pixels_per_point` ([#2239](https://github.com/emilk/egui/pull/2239)).
* Fixed popups and color edit going outside the screen.
* Fixed keyboard support in `DragValue`. ([#2342](https://github.com/emilk/egui/pull/2342)).
* Fixed keyboard support in `DragValue` ([#2342](https://github.com/emilk/egui/pull/2342)).
* If you nest `ScrollAreas` inside each other, the inner area will now move its scroll bar so it is always visible ([#2371](https://github.com/emilk/egui/pull/2371)).


## 0.19.0 - 2022-08-20
Expand Down
46 changes: 24 additions & 22 deletions crates/egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,23 +635,7 @@ impl Prepared {
};
}

let mut inner_rect = Rect::from_min_size(inner_rect.min, inner_size);

// The window that egui sits in can't be expanded by egui, so we need to respect it:
for d in 0..2 {
if !has_bar[d] {
// HACK for when we have a vertical-only scroll area in a top level panel,
// and that panel is not wide enough for the contents.
// This code ensures we still see the scroll bar!
let max = ui.input().screen_rect().max[d]
- current_bar_use[d]
- ui.spacing().item_spacing[d];
inner_rect.max[d] = inner_rect.max[d].at_most(max);
// TODO(emilk): maybe auto-enable horizontal/vertical scrolling if this limit is reached
}
}

inner_rect
Rect::from_min_size(inner_rect.min, inner_size)
};

let outer_rect = Rect::from_min_size(inner_rect.min, inner_rect.size() + current_bar_use);
Expand Down Expand Up @@ -703,13 +687,29 @@ impl Prepared {
continue;
}

// margin between contents and scroll bar
let margin = animation_t * ui.spacing().item_spacing.x;
let min_cross = inner_rect.max[1 - d] + margin; // left of vertical scroll (d == 1)
let max_cross = outer_rect.max[1 - d]; // right of vertical scroll (d == 1)
// margin on either side of the scroll bar
let inner_margin = animation_t * ui.spacing().scroll_bar_inner_margin;
let outer_margin = animation_t * ui.spacing().scroll_bar_outer_margin;
let mut min_cross = inner_rect.max[1 - d] + inner_margin; // left of vertical scroll (d == 1)
let mut max_cross = outer_rect.max[1 - d] - outer_margin; // right of vertical scroll (d == 1)
let min_main = inner_rect.min[d]; // top of vertical scroll (d == 1)
let max_main = inner_rect.max[d]; // bottom of vertical scroll (d == 1)

if ui.clip_rect().max[1 - d] < max_cross + outer_margin {
// Move the scrollbar so it is visible. This is needed in some cases.
// For instance:
// * When we have a vertical-only scroll area in a top level panel,
// and that panel is not wide enough for the contents.
// * When one ScrollArea is nested inside another, and the outer
// is scrolled so that the scroll-bars of the inner ScrollArea (us)
// is outside the clip rectangle.
// Really this should use the tighter clip_rect that ignores clip_rect_margin, but we don't store that.
// clip_rect_margin is quite a hack. It would be nice to get rid of it.
let width = max_cross - min_cross;
max_cross = ui.clip_rect().max[1 - d] - outer_margin;
min_cross = max_cross - width;
}

let outer_scroll_rect = if d == 0 {
Rect::from_min_max(
pos2(inner_rect.left(), min_cross),
Expand Down Expand Up @@ -865,5 +865,7 @@ impl Prepared {

/// Width of a vertical scrollbar, or height of a horizontal scroll bar
fn max_scroll_bar_width_with_margin(ui: &Ui) -> f32 {
ui.spacing().item_spacing.x + ui.spacing().scroll_bar_width
ui.spacing().scroll_bar_inner_margin
+ ui.spacing().scroll_bar_width
+ ui.spacing().scroll_bar_outer_margin
}
7 changes: 6 additions & 1 deletion crates/egui/src/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,12 @@ impl Painter {
impl Painter {
#[allow(clippy::needless_pass_by_value)]
pub fn debug_rect(&self, rect: Rect, color: Color32, text: impl ToString) {
self.rect_stroke(rect, 0.0, (1.0, color));
self.rect(
rect,
0.0,
color.additive().linear_multiply(0.015),
(1.0, color),
);
self.text(
rect.min,
Align2::LEFT_TOP,
Expand Down
19 changes: 18 additions & 1 deletion crates/egui/src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ pub struct Spacing {
pub combo_height: f32,

pub scroll_bar_width: f32,

/// Margin between contents and scroll bar.
pub scroll_bar_inner_margin: f32,
/// Margin between scroll bar and the outer container (e.g. right of a vertical scroll bar).
pub scroll_bar_outer_margin: f32,
}

impl Spacing {
Expand Down Expand Up @@ -658,6 +663,8 @@ impl Default for Spacing {
tooltip_width: 600.0,
combo_height: 200.0,
scroll_bar_width: 8.0,
scroll_bar_inner_margin: 4.0,
scroll_bar_outer_margin: 0.0,
indent_ends_with_horizontal_line: false,
}
}
Expand Down Expand Up @@ -941,6 +948,8 @@ impl Spacing {
indent_ends_with_horizontal_line,
combo_height,
scroll_bar_width,
scroll_bar_inner_margin,
scroll_bar_outer_margin,
} = self;

ui.add(slider_vec2(item_spacing, 0.0..=20.0, "Item spacing"));
Expand Down Expand Up @@ -1021,7 +1030,15 @@ impl Spacing {
});
ui.horizontal(|ui| {
ui.add(DragValue::new(scroll_bar_width).clamp_range(0.0..=32.0));
ui.label("Scroll-bar width width");
ui.label("Scroll-bar width");
});
ui.horizontal(|ui| {
ui.add(DragValue::new(scroll_bar_inner_margin).clamp_range(0.0..=32.0));
ui.label("Scroll-bar inner margin");
});
ui.horizontal(|ui| {
ui.add(DragValue::new(scroll_bar_outer_margin).clamp_range(0.0..=32.0));
ui.label("Scroll-bar outer margin");
});

ui.horizontal(|ui| {
Expand Down
10 changes: 10 additions & 0 deletions crates/egui_demo_lib/src/demo/scrolling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ enum ScrollDemo {
ManyLines,
LargeCanvas,
StickToEnd,
Bidirectional,
}

impl Default for ScrollDemo {
Expand Down Expand Up @@ -55,6 +56,7 @@ impl super::View for Scrolling {
"Scroll a large canvas",
);
ui.selectable_value(&mut self.demo, ScrollDemo::StickToEnd, "Stick to end");
ui.selectable_value(&mut self.demo, ScrollDemo::Bidirectional, "Bidirectional");
});
ui.separator();
match self.demo {
Expand All @@ -70,6 +72,14 @@ impl super::View for Scrolling {
ScrollDemo::StickToEnd => {
self.scroll_stick_to.ui(ui);
}
ScrollDemo::Bidirectional => {
egui::ScrollArea::both().show(ui, |ui| {
ui.style_mut().wrap = Some(false);
for _ in 0..100 {
ui.label(crate::LOREM_IPSUM);
}
});
}
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions crates/egui_demo_lib/src/demo/table_demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl super::Demo for TableDemo {
}
}

const NUM_MANUAL_ROWS: usize = 32;
const NUM_MANUAL_ROWS: usize = 20;

impl super::View for TableDemo {
fn ui(&mut self, ui: &mut egui::Ui) {
Expand Down Expand Up @@ -101,11 +101,13 @@ impl super::View for TableDemo {
// Leave room for the source code link after the table demo:
use egui_extras::{Size, StripBuilder};
StripBuilder::new(ui)
.size(Size::remainder()) // for the table
.size(Size::remainder().at_least(100.0)) // for the table
.size(Size::exact(10.0)) // for the source code link
.vertical(|mut strip| {
strip.cell(|ui| {
self.table_ui(ui);
egui::ScrollArea::horizontal().show(ui, |ui| {
self.table_ui(ui);
});
});
strip.cell(|ui| {
ui.vertical_centered(|ui| {
Expand Down Expand Up @@ -133,7 +135,8 @@ impl TableDemo {
.resizable(true)
.clip(true),
)
.column(Column::remainder());
.column(Column::remainder())
.min_scrolled_height(0.0);

if let Some(row_nr) = self.scroll_to_row.take() {
table = table.scroll_to_row(row_nr, None);
Expand Down
15 changes: 15 additions & 0 deletions crates/egui_extras/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ All notable changes to the `egui_extras` integration will be noted in this file.
## Unreleased
* Added `TableBuilder::vertical_scroll_offset`: method to set vertical scroll offset position for a table ([#1946](https://github.com/emilk/egui/pull/1946)).
* Added `RetainedImage::from_svg_bytes_with_size` to be able to specify a size for SVGs to be rasterized at.
* Big `Table` improvements ([#2369](https://github.com/emilk/egui/pull/2369)):
* Double-click column separators to auto-size the column.
* All `Table` now store state. You may see warnings about reused table ids. Use `ui.push_id` to fix this.
* `TableBuilder::column` takes a `Column` instead of a `Size`.
* `Column` controls default size, size range, resizing, and clipping of columns.
* `Column::auto` will pick a size automatically
* Added `Table::scroll_to_row`.
* Added `Table::min_scrolled_height` and `Table::max_scroll_height`.
* Added `TableBody::max_size`.
* `Table::scroll` renamed to `Table::vscroll`.
* `egui_extras::Strip` now has `clip: false` by default.
* Fix bugs when putting `Table` inside of a horizontal `ScrollArea`.
* Many other bug fixes.
* Add `Table::auto_shrink` - set to `false` to expand table to fit its containing `Ui` ([#2371](https://github.com/emilk/egui/pull/2371)).


## 0.19.0 - 2022-08-20
* MSRV (Minimum Supported Rust Version) is now `1.61.0` ([#1846](https://github.com/emilk/egui/pull/1846)).
Expand Down
Loading