Skip to content

Commit

Permalink
Update scroll_area.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
rustbasic authored Jun 20, 2024
1 parent 52a8e11 commit 02f6fb5
Showing 1 changed file with 29 additions and 32 deletions.
61 changes: 29 additions & 32 deletions crates/egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,21 +793,21 @@ impl Prepared {

let content_size = content_ui.min_size();

let scroll_delta = content_ui
.ctx()
.frame_state_mut(|state| std::mem::take(&mut state.scroll_delta));

for d in 0..2 {
// FrameState::scroll_delta is inverted from the way we apply the delta, so we need to negate it.
let mut delta = -scroll_delta[d];

// We always take both scroll targets regardless of which scroll axes are enabled. This
// is to avoid them leaking to other scroll areas.
let scroll_target = content_ui
.ctx()
.frame_state_mut(|state| state.scroll_target[d].take());

if scroll_enabled[d] {
let scroll_delta = content_ui
.ctx()
.frame_state_mut(|state| std::mem::take(&mut state.scroll_delta[d]));

// FrameState::scroll_delta is inverted from the way we apply the delta, so we need to negate it.
let mut delta = -scroll_delta;

delta += if let Some((target_range, align)) = scroll_target {
let min = content_ui.min_rect().min[d];
let clip_rect = content_ui.clip_rect();
Expand Down Expand Up @@ -963,16 +963,30 @@ impl Prepared {
let inner_margin = show_factor * scroll_style.bar_inner_margin;
let outer_margin = show_factor * scroll_style.bar_outer_margin;

let mut max_cross = outer_rect.max[1 - d] - outer_margin;
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.
max_cross = ui.clip_rect().max[1 - d] - outer_margin;
}

// top/bottom of a horizontal scroll (d==0).
// left/rigth of a vertical scroll (d==1).
let mut cross = if scroll_style.floating {
let cross = if scroll_style.floating {
let max_bar_rect = if d == 0 {
outer_rect.with_min_y(outer_rect.max.y - scroll_style.allocated_width())
outer_rect.with_min_y(max_cross - scroll_style.bar_width)
} else {
outer_rect.with_min_x(outer_rect.max.x - scroll_style.allocated_width())
outer_rect.with_min_x(max_cross - scroll_style.bar_width)
};
let is_hovering_bar_area = is_hovering_outer_rect
&& ui.rect_contains_pointer(max_bar_rect)
let is_hovering_bar_area = (is_hovering_outer_rect
&& ui.rect_contains_pointer(max_bar_rect))
|| state.scroll_bar_interaction[d];
let is_hovering_bar_area_t = ui
.ctx()
Expand All @@ -983,38 +997,21 @@ impl Prepared {
is_hovering_bar_area_t,
);

let max_cross = outer_rect.max[1 - d] - outer_margin;
let min_cross = max_cross - width;
Rangef::new(min_cross, max_cross)
} else {
let min_cross = inner_rect.max[1 - d] + inner_margin;
let max_cross = outer_rect.max[1 - d] - outer_margin;
let min_cross = max_cross - scroll_style.bar_width;
Rangef::new(min_cross, max_cross)
};

if ui.clip_rect().max[1 - d] < cross.max + 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 = cross.max - cross.min;
cross.max = ui.clip_rect().max[1 - d] - outer_margin;
cross.min = cross.max - width;
}

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

0 comments on commit 02f6fb5

Please sign in to comment.