Prevent ScrollArea:s from becoming tiny (#1255)
Closes https://github.com/emilk/egui/issues/1097
This commit is contained in:
parent
b5c8f034e7
commit
3d754e3a16
3 changed files with 47 additions and 9 deletions
|
@ -55,11 +55,11 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
|
||||||
* Renamed `Plot::custom_label_func` to `Plot::label_formatter` ([#1235](https://github.com/emilk/egui/pull/1235)).
|
* Renamed `Plot::custom_label_func` to `Plot::label_formatter` ([#1235](https://github.com/emilk/egui/pull/1235)).
|
||||||
* Tooltips that don't fit the window don't flicker anymore ([#1240](https://github.com/emilk/egui/pull/1240)).
|
* Tooltips that don't fit the window don't flicker anymore ([#1240](https://github.com/emilk/egui/pull/1240)).
|
||||||
* `Areas::layer_id_at` ignores non interatable layers (i.e. Tooltips) ([#1240](https://github.com/emilk/egui/pull/1240)).
|
* `Areas::layer_id_at` ignores non interatable layers (i.e. Tooltips) ([#1240](https://github.com/emilk/egui/pull/1240)).
|
||||||
|
* `ScrollArea`:s will not shrink below a certain minimum size, set by `min_scrolled_width/min_scrolled_height` ([1255](https://github.com/emilk/egui/pull/1255)).
|
||||||
|
|
||||||
### Fixed 🐛
|
### Fixed 🐛
|
||||||
* Context menus now respects the theme ([#1043](https://github.com/emilk/egui/pull/1043)).
|
* Context menus now respects the theme ([#1043](https://github.com/emilk/egui/pull/1043)).
|
||||||
* Plot `Orientation` was not public, although fields using this type were ([#1130](https://github.com/emilk/egui/pull/1130)).
|
* Plot `Orientation` was not public, although fields using this type were ([#1130](https://github.com/emilk/egui/pull/1130)).
|
||||||
* Fixed `enable_drag` for Windows ([#1108](https://github.com/emilk/egui/pull/1108)).
|
|
||||||
* Calling `Context::set_pixels_per_point` before the first frame will now work.
|
* Calling `Context::set_pixels_per_point` before the first frame will now work.
|
||||||
* Tooltips that don't fit the window don't flicker anymore ([#1240](https://github.com/emilk/egui/pull/1240)).
|
* Tooltips that don't fit the window don't flicker anymore ([#1240](https://github.com/emilk/egui/pull/1240)).
|
||||||
* Scroll areas now follow text cursor ([1252](https://github.com/emilk/egui/pull/1252)).
|
* Scroll areas now follow text cursor ([1252](https://github.com/emilk/egui/pull/1252)).
|
||||||
|
|
|
@ -12,6 +12,7 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG
|
||||||
* Fix horizontal scrolling direction on Linux.
|
* Fix horizontal scrolling direction on Linux.
|
||||||
* Added `App::on_exit_event` ([#1038](https://github.com/emilk/egui/pull/1038))
|
* Added `App::on_exit_event` ([#1038](https://github.com/emilk/egui/pull/1038))
|
||||||
* Added `NativeOptions::initial_window_pos`.
|
* Added `NativeOptions::initial_window_pos`.
|
||||||
|
* Fixed `enable_drag` for Windows ([#1108](https://github.com/emilk/egui/pull/1108)).
|
||||||
* Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)).
|
* Shift-scroll will now result in horizontal scrolling on all platforms ([#1136](https://github.com/emilk/egui/pull/1136)).
|
||||||
* Log using the `tracing` crate. Log to stdout by adding `tracing_subscriber::fmt::init();` to your `main` ([#1192](https://github.com/emilk/egui/pull/1192)).
|
* Log using the `tracing` crate. Log to stdout by adding `tracing_subscriber::fmt::init();` to your `main` ([#1192](https://github.com/emilk/egui/pull/1192)).
|
||||||
* Expose all parts of the location/url in `frame.info().web_info` ([#1258](https://github.com/emilk/egui/pull/1258)).
|
* Expose all parts of the location/url in `frame.info().web_info` ([#1258](https://github.com/emilk/egui/pull/1258)).
|
||||||
|
|
|
@ -81,6 +81,7 @@ pub struct ScrollArea {
|
||||||
has_bar: [bool; 2],
|
has_bar: [bool; 2],
|
||||||
auto_shrink: [bool; 2],
|
auto_shrink: [bool; 2],
|
||||||
max_size: Vec2,
|
max_size: Vec2,
|
||||||
|
min_scrolled_size: Vec2,
|
||||||
always_show_scroll: bool,
|
always_show_scroll: bool,
|
||||||
id_source: Option<Id>,
|
id_source: Option<Id>,
|
||||||
offset_x: Option<f32>,
|
offset_x: Option<f32>,
|
||||||
|
@ -123,6 +124,7 @@ impl ScrollArea {
|
||||||
has_bar,
|
has_bar,
|
||||||
auto_shrink: [true; 2],
|
auto_shrink: [true; 2],
|
||||||
max_size: Vec2::INFINITY,
|
max_size: Vec2::INFINITY,
|
||||||
|
min_scrolled_size: Vec2::splat(64.0),
|
||||||
always_show_scroll: false,
|
always_show_scroll: false,
|
||||||
id_source: None,
|
id_source: None,
|
||||||
offset_x: None,
|
offset_x: None,
|
||||||
|
@ -152,6 +154,28 @@ impl ScrollArea {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The minimum width of a horizontal scroll area which requires scroll bars.
|
||||||
|
///
|
||||||
|
/// The `ScrollArea` will only become smaller than this if the content is smaller than this
|
||||||
|
/// (and so we don't require scroll bars).
|
||||||
|
///
|
||||||
|
/// Default: `64.0`.
|
||||||
|
pub fn min_scrolled_width(mut self, min_scrolled_width: f32) -> Self {
|
||||||
|
self.min_scrolled_size.x = min_scrolled_width;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The minimum height of a vertical scroll area which requires scroll bars.
|
||||||
|
///
|
||||||
|
/// The `ScrollArea` will only become smaller than this if the content is smaller than this
|
||||||
|
/// (and so we don't require scroll bars).
|
||||||
|
///
|
||||||
|
/// Default: `64.0`.
|
||||||
|
pub fn min_scrolled_height(mut self, min_scrolled_height: f32) -> Self {
|
||||||
|
self.min_scrolled_size.y = min_scrolled_height;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// If `false` (default), the scroll bar will be hidden when not needed/
|
/// If `false` (default), the scroll bar will be hidden when not needed/
|
||||||
/// If `true`, the scroll bar will always be displayed even if not needed.
|
/// If `true`, the scroll bar will always be displayed even if not needed.
|
||||||
pub fn always_show_scroll(mut self, always_show_scroll: bool) -> Self {
|
pub fn always_show_scroll(mut self, always_show_scroll: bool) -> Self {
|
||||||
|
@ -288,6 +312,7 @@ impl ScrollArea {
|
||||||
has_bar,
|
has_bar,
|
||||||
auto_shrink,
|
auto_shrink,
|
||||||
max_size,
|
max_size,
|
||||||
|
min_scrolled_size,
|
||||||
always_show_scroll,
|
always_show_scroll,
|
||||||
id_source,
|
id_source,
|
||||||
offset_x,
|
offset_x,
|
||||||
|
@ -329,27 +354,39 @@ impl ScrollArea {
|
||||||
|
|
||||||
let outer_size = available_outer.size().at_most(max_size);
|
let outer_size = available_outer.size().at_most(max_size);
|
||||||
|
|
||||||
let inner_size = outer_size - current_bar_use;
|
let inner_size = {
|
||||||
|
let mut inner_size = outer_size - current_bar_use;
|
||||||
|
|
||||||
|
// Don't go so far that we shrink to zero.
|
||||||
|
// In particular, if we put a `ScrollArea` inside of a `ScrollArea`, the inner
|
||||||
|
// one shouldn't collapse into nothingness.
|
||||||
|
// See https://github.com/emilk/egui/issues/1097
|
||||||
|
for d in 0..2 {
|
||||||
|
if has_bar[d] {
|
||||||
|
inner_size[d] = inner_size[d].max(min_scrolled_size[d]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inner_size
|
||||||
|
};
|
||||||
|
|
||||||
let inner_rect = Rect::from_min_size(available_outer.min, inner_size);
|
let inner_rect = Rect::from_min_size(available_outer.min, inner_size);
|
||||||
|
|
||||||
let mut inner_child_max_size = inner_size;
|
let mut content_max_size = inner_size;
|
||||||
|
|
||||||
if true {
|
if true {
|
||||||
// Tell the inner Ui to *try* to fit the content without needing to scroll,
|
// Tell the inner Ui to *try* to fit the content without needing to scroll,
|
||||||
// i.e. better to wrap text than showing a horizontal scrollbar!
|
// i.e. better to wrap text and shrink images than showing a horizontal scrollbar!
|
||||||
} else {
|
} else {
|
||||||
// Tell the inner Ui to use as much space as possible, we can scroll to see it!
|
// Tell the inner Ui to use as much space as possible, we can scroll to see it!
|
||||||
for d in 0..2 {
|
for d in 0..2 {
|
||||||
if has_bar[d] {
|
if has_bar[d] {
|
||||||
inner_child_max_size[d] = f32::INFINITY;
|
content_max_size[d] = f32::INFINITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut content_ui = ui.child_ui(
|
let content_max_rect = Rect::from_min_size(inner_rect.min - state.offset, content_max_size);
|
||||||
Rect::from_min_size(inner_rect.min - state.offset, inner_child_max_size),
|
let mut content_ui = ui.child_ui(content_max_rect, *ui.layout());
|
||||||
*ui.layout(),
|
|
||||||
);
|
|
||||||
let mut content_clip_rect = inner_rect.expand(ui.visuals().clip_rect_margin);
|
let mut content_clip_rect = inner_rect.expand(ui.visuals().clip_rect_margin);
|
||||||
content_clip_rect = content_clip_rect.intersect(ui.clip_rect());
|
content_clip_rect = content_clip_rect.intersect(ui.clip_rect());
|
||||||
// Nice handling of forced resizing beyond the possible:
|
// Nice handling of forced resizing beyond the possible:
|
||||||
|
|
Loading…
Reference in a new issue