Return more info from ScrollArea::show (#1166)
This commit is contained in:
parent
1134258441
commit
3333d63b91
6 changed files with 72 additions and 34 deletions
|
@ -33,7 +33,8 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w
|
||||||
* Replaced `Style::body_text_style` with more generic `Style::text_styles` ([#1154](https://github.com/emilk/egui/pull/1154)).
|
* Replaced `Style::body_text_style` with more generic `Style::text_styles` ([#1154](https://github.com/emilk/egui/pull/1154)).
|
||||||
* `TextStyle` is no longer `Copy` ([#1154](https://github.com/emilk/egui/pull/1154)).
|
* `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 `TextEdit::text_style` with `TextEdit::font` ([#1154](https://github.com/emilk/egui/pull/1154)).
|
||||||
* `Plot::highlight` now takes a `bool` argument ([#1159](https://github.com/emilk/egui/pull/1159)),
|
* `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)).
|
||||||
|
|
||||||
### Fixed 🐛
|
### Fixed 🐛
|
||||||
* Context menu now respects the theme ([#1043](https://github.com/emilk/egui/pull/1043))
|
* Context menu now respects the theme ([#1043](https://github.com/emilk/egui/pull/1043))
|
||||||
|
|
|
@ -196,6 +196,7 @@ fn combo_box_dyn<'c, R>(
|
||||||
ScrollArea::vertical()
|
ScrollArea::vertical()
|
||||||
.max_height(ui.spacing().combo_height)
|
.max_height(ui.spacing().combo_height)
|
||||||
.show(ui, menu_contents)
|
.show(ui, menu_contents)
|
||||||
|
.inner
|
||||||
});
|
});
|
||||||
|
|
||||||
InnerResponse {
|
InnerResponse {
|
||||||
|
|
|
@ -10,9 +10,9 @@ use crate::*;
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "serde", serde(default))]
|
#[cfg_attr(feature = "serde", serde(default))]
|
||||||
pub(crate) struct State {
|
pub struct State {
|
||||||
/// Positive offset means scrolling down/right
|
/// Positive offset means scrolling down/right
|
||||||
offset: Vec2,
|
pub offset: Vec2,
|
||||||
|
|
||||||
show_scroll: [bool; 2],
|
show_scroll: [bool; 2],
|
||||||
|
|
||||||
|
@ -51,6 +51,20 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ScrollAreaOutput<R> {
|
||||||
|
/// What the user closure returned.
|
||||||
|
pub inner: R,
|
||||||
|
|
||||||
|
/// `Id` of the `ScrollArea`.
|
||||||
|
pub id: Id,
|
||||||
|
|
||||||
|
/// The current state of the scroll area.
|
||||||
|
pub state: State,
|
||||||
|
|
||||||
|
/// Where on the screen the content is (excludes scroll bars).
|
||||||
|
pub inner_rect: Rect,
|
||||||
|
}
|
||||||
|
|
||||||
/// Add vertical and/or horizontal scrolling to a contained [`Ui`].
|
/// Add vertical and/or horizontal scrolling to a contained [`Ui`].
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -258,6 +272,7 @@ struct Prepared {
|
||||||
/// width of the vertical bar, and the height of the horizontal bar?
|
/// width of the vertical bar, and the height of the horizontal bar?
|
||||||
current_bar_use: Vec2,
|
current_bar_use: Vec2,
|
||||||
always_show_scroll: bool,
|
always_show_scroll: bool,
|
||||||
|
/// Where on the screen the content is (excludes scroll bars).
|
||||||
inner_rect: Rect,
|
inner_rect: Rect,
|
||||||
content_ui: Ui,
|
content_ui: Ui,
|
||||||
/// Relative coordinates: the offset and size of the view of the inner UI.
|
/// Relative coordinates: the offset and size of the view of the inner UI.
|
||||||
|
@ -365,7 +380,11 @@ impl ScrollArea {
|
||||||
/// Show the `ScrollArea`, and add the contents to the viewport.
|
/// Show the `ScrollArea`, and add the contents to the viewport.
|
||||||
///
|
///
|
||||||
/// If the inner area can be very long, consider using [`Self::show_rows`] instead.
|
/// If the inner area can be very long, consider using [`Self::show_rows`] instead.
|
||||||
pub fn show<R>(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> R {
|
pub fn show<R>(
|
||||||
|
self,
|
||||||
|
ui: &mut Ui,
|
||||||
|
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||||
|
) -> ScrollAreaOutput<R> {
|
||||||
self.show_viewport_dyn(ui, Box::new(|ui, _viewport| add_contents(ui)))
|
self.show_viewport_dyn(ui, Box::new(|ui, _viewport| add_contents(ui)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +410,7 @@ impl ScrollArea {
|
||||||
row_height_sans_spacing: f32,
|
row_height_sans_spacing: f32,
|
||||||
total_rows: usize,
|
total_rows: usize,
|
||||||
add_contents: impl FnOnce(&mut Ui, std::ops::Range<usize>) -> R,
|
add_contents: impl FnOnce(&mut Ui, std::ops::Range<usize>) -> R,
|
||||||
) -> R {
|
) -> ScrollAreaOutput<R> {
|
||||||
let spacing = ui.spacing().item_spacing;
|
let spacing = ui.spacing().item_spacing;
|
||||||
let row_height_with_spacing = row_height_sans_spacing + spacing.y;
|
let row_height_with_spacing = row_height_sans_spacing + spacing.y;
|
||||||
self.show_viewport(ui, |ui, viewport| {
|
self.show_viewport(ui, |ui, viewport| {
|
||||||
|
@ -420,7 +439,11 @@ impl ScrollArea {
|
||||||
///
|
///
|
||||||
/// `add_contents` is past the viewport, which is the relative view of the content.
|
/// `add_contents` is past the viewport, which is the relative view of the content.
|
||||||
/// So if the passed rect has min = zero, then show the top left content (the user has not scrolled).
|
/// So if the passed rect has min = zero, then show the top left content (the user has not scrolled).
|
||||||
pub fn show_viewport<R>(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui, Rect) -> R) -> R {
|
pub fn show_viewport<R>(
|
||||||
|
self,
|
||||||
|
ui: &mut Ui,
|
||||||
|
add_contents: impl FnOnce(&mut Ui, Rect) -> R,
|
||||||
|
) -> ScrollAreaOutput<R> {
|
||||||
self.show_viewport_dyn(ui, Box::new(add_contents))
|
self.show_viewport_dyn(ui, Box::new(add_contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,16 +451,23 @@ impl ScrollArea {
|
||||||
self,
|
self,
|
||||||
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>,
|
||||||
) -> R {
|
) -> ScrollAreaOutput<R> {
|
||||||
let mut prepared = self.begin(ui);
|
let mut prepared = self.begin(ui);
|
||||||
let ret = add_contents(&mut prepared.content_ui, prepared.viewport);
|
let id = prepared.id;
|
||||||
prepared.end(ui);
|
let inner_rect = prepared.inner_rect;
|
||||||
ret
|
let inner = add_contents(&mut prepared.content_ui, prepared.viewport);
|
||||||
|
let state = prepared.end(ui);
|
||||||
|
ScrollAreaOutput {
|
||||||
|
inner,
|
||||||
|
id,
|
||||||
|
state,
|
||||||
|
inner_rect,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Prepared {
|
impl Prepared {
|
||||||
fn end(self, ui: &mut Ui) {
|
fn end(self, ui: &mut Ui) -> State {
|
||||||
let Prepared {
|
let Prepared {
|
||||||
id,
|
id,
|
||||||
mut state,
|
mut state,
|
||||||
|
@ -747,6 +777,8 @@ impl Prepared {
|
||||||
state.show_scroll = show_scroll_this_frame;
|
state.show_scroll = show_scroll_this_frame;
|
||||||
|
|
||||||
state.store(ui.ctx(), id);
|
state.store(ui.ctx(), id);
|
||||||
|
|
||||||
|
state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -354,7 +354,7 @@ impl<'open> Window<'open> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if scroll.has_any_bar() {
|
if scroll.has_any_bar() {
|
||||||
scroll.show(ui, add_contents)
|
scroll.show(ui, add_contents).inner
|
||||||
} else {
|
} else {
|
||||||
add_contents(ui)
|
add_contents(ui)
|
||||||
}
|
}
|
||||||
|
|
|
@ -586,7 +586,9 @@ impl std::ops::BitOrAssign for Response {
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InnerResponse<R> {
|
pub struct InnerResponse<R> {
|
||||||
|
/// What the user closure returned.
|
||||||
pub inner: R,
|
pub inner: R,
|
||||||
|
/// The response of the area.
|
||||||
pub response: Response,
|
pub response: Response,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,32 +210,34 @@ impl super::View for ScrollTo {
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
let (current_scroll, max_scroll) = scroll_area.show(ui, |ui| {
|
let (current_scroll, max_scroll) = scroll_area
|
||||||
if scroll_top {
|
.show(ui, |ui| {
|
||||||
ui.scroll_to_cursor(Align::TOP);
|
if scroll_top {
|
||||||
}
|
ui.scroll_to_cursor(Align::TOP);
|
||||||
ui.vertical(|ui| {
|
|
||||||
for item in 1..=50 {
|
|
||||||
if track_item && item == self.track_item {
|
|
||||||
let response =
|
|
||||||
ui.colored_label(Color32::YELLOW, format!("This is item {}", item));
|
|
||||||
response.scroll_to_me(self.tack_item_align);
|
|
||||||
} else {
|
|
||||||
ui.label(format!("This is item {}", item));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
ui.vertical(|ui| {
|
||||||
|
for item in 1..=50 {
|
||||||
|
if track_item && item == self.track_item {
|
||||||
|
let response =
|
||||||
|
ui.colored_label(Color32::YELLOW, format!("This is item {}", item));
|
||||||
|
response.scroll_to_me(self.tack_item_align);
|
||||||
|
} else {
|
||||||
|
ui.label(format!("This is item {}", item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if scroll_bottom {
|
if scroll_bottom {
|
||||||
ui.scroll_to_cursor(Align::BOTTOM);
|
ui.scroll_to_cursor(Align::BOTTOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
let margin = ui.visuals().clip_rect_margin;
|
let margin = ui.visuals().clip_rect_margin;
|
||||||
|
|
||||||
let current_scroll = ui.clip_rect().top() - ui.min_rect().top() + margin;
|
let current_scroll = ui.clip_rect().top() - ui.min_rect().top() + margin;
|
||||||
let max_scroll = ui.min_rect().height() - ui.clip_rect().height() + 2.0 * margin;
|
let max_scroll = ui.min_rect().height() - ui.clip_rect().height() + 2.0 * margin;
|
||||||
(current_scroll, max_scroll)
|
(current_scroll, max_scroll)
|
||||||
});
|
})
|
||||||
|
.inner;
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
ui.label(format!(
|
ui.label(format!(
|
||||||
|
|
Loading…
Reference in a new issue