Skip to content

Commit

Permalink
Add ScrollArea::scroll_bar_rect
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Sep 4, 2024
1 parent 0b92b93 commit de2f6c0
Showing 1 changed file with 32 additions and 9 deletions.
41 changes: 32 additions & 9 deletions crates/egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ pub struct ScrollArea {
max_size: Vec2,
min_scrolled_size: Vec2,
scroll_bar_visibility: ScrollBarVisibility,
scroll_bar_rect: Option<Rect>,
id_salt: Option<Id>,
offset_x: Option<f32>,
offset_y: Option<f32>,
Expand Down Expand Up @@ -223,6 +224,7 @@ impl ScrollArea {
max_size: Vec2::INFINITY,
min_scrolled_size: Vec2::splat(64.0),
scroll_bar_visibility: Default::default(),
scroll_bar_rect: None,
id_salt: None,
offset_x: None,
offset_y: None,
Expand Down Expand Up @@ -288,6 +290,16 @@ impl ScrollArea {
self
}

/// Specify within which screen-space rectangle to show the scroll bars.
///
/// This can be used to move the scroll bars to a smaller region of the `ScrollArea`,
/// for instance if you are painting a sticky header on top of it.
#[inline]
pub fn scroll_bar_rect(mut self, scroll_bar_rect: Rect) -> Self {
self.scroll_bar_rect = Some(scroll_bar_rect);
self
}

/// A source for the unique [`Id`], e.g. `.id_source("second_scroll_area")` or `.id_source(loop_index)`.
#[inline]
#[deprecated = "Renamed id_salt"]
Expand Down Expand Up @@ -474,6 +486,7 @@ struct Prepared {
current_bar_use: Vec2,

scroll_bar_visibility: ScrollBarVisibility,
scroll_bar_rect: Option<Rect>,

/// Where on the screen the content is (excludes scroll bars).
inner_rect: Rect,
Expand All @@ -497,6 +510,7 @@ impl ScrollArea {
max_size,
min_scrolled_size,
scroll_bar_visibility,
scroll_bar_rect,
id_salt,
offset_x,
offset_y,
Expand Down Expand Up @@ -679,6 +693,7 @@ impl ScrollArea {
show_bars_factor,
current_bar_use,
scroll_bar_visibility,
scroll_bar_rect,
inner_rect,
content_ui,
viewport,
Expand Down Expand Up @@ -792,6 +807,7 @@ impl Prepared {
mut show_bars_factor,
current_bar_use,
scroll_bar_visibility,
scroll_bar_rect,
content_ui,
viewport: _,
scrolling_enabled,
Expand Down Expand Up @@ -957,6 +973,7 @@ impl Prepared {
let scroll_style = ui.spacing().scroll;

// Paint the bars:
let scroll_bar_rect = scroll_bar_rect.unwrap_or(inner_rect);
for d in 0..2 {
// maybe force increase in offset to keep scroll stuck to end position
if stick_to_end[d] && state.scroll_stuck_to_end[d] {
Expand All @@ -971,7 +988,7 @@ impl Prepared {

// left/right of a horizontal scroll (d==1)
// top/bottom of vertical scroll (d == 1)
let main_range = Rangef::new(inner_rect.min[d], inner_rect.max[d]);
let main_range = Rangef::new(scroll_bar_rect.min[d], scroll_bar_rect.max[d]);

// Margin on either side of the scroll bar:
let inner_margin = show_factor * scroll_style.bar_inner_margin;
Expand Down Expand Up @@ -1028,13 +1045,13 @@ impl Prepared {

let outer_scroll_rect = if d == 0 {
Rect::from_min_max(
pos2(inner_rect.left(), cross.min),
pos2(inner_rect.right(), cross.max),
pos2(scroll_bar_rect.left(), cross.min),
pos2(scroll_bar_rect.right(), cross.max),
)
} else {
Rect::from_min_max(
pos2(cross.min, inner_rect.top()),
pos2(cross.max, inner_rect.bottom()),
pos2(cross.min, scroll_bar_rect.top()),
pos2(cross.max, scroll_bar_rect.bottom()),
)
};

Expand All @@ -1043,14 +1060,17 @@ impl Prepared {
let handle_rect = if d == 0 {
Rect::from_min_max(
pos2(from_content(state.offset.x), cross.min),
pos2(from_content(state.offset.x + inner_rect.width()), cross.max),
pos2(
from_content(state.offset.x + scroll_bar_rect.width()),
cross.max,
),
)
} else {
Rect::from_min_max(
pos2(cross.min, from_content(state.offset.y)),
pos2(
cross.max,
from_content(state.offset.y + inner_rect.height()),
from_content(state.offset.y + scroll_bar_rect.height()),
),
)
};
Expand Down Expand Up @@ -1102,14 +1122,17 @@ impl Prepared {
let mut handle_rect = if d == 0 {
Rect::from_min_max(
pos2(from_content(state.offset.x), cross.min),
pos2(from_content(state.offset.x + inner_rect.width()), cross.max),
pos2(
from_content(state.offset.x + scroll_bar_rect.width()),
cross.max,
),
)
} else {
Rect::from_min_max(
pos2(cross.min, from_content(state.offset.y)),
pos2(
cross.max,
from_content(state.offset.y + inner_rect.height()),
from_content(state.offset.y + scroll_bar_rect.height()),
),
)
};
Expand Down

0 comments on commit de2f6c0

Please sign in to comment.