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

Fix scroll handle extending outside of ScrollArea #5286

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
69 changes: 29 additions & 40 deletions crates/egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,21 +1067,34 @@ 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),
)
} else {
Rect::from_min_max(
pos2(cross.min, from_content(state.offset.y)),
pos2(
cross.max,
from_content(state.offset.y + inner_rect.height()),
),
)
let calculate_handle_rect = |d, offset: &Vec2| {
let handle_size = if d == 0 {
from_content(offset.x + inner_rect.width()) - from_content(offset.x)
} else {
from_content(offset.y + inner_rect.height()) - from_content(offset.y)
}.max(scroll_style.handle_min_length);

let handle_start_point = remap_clamp(
offset[d],
0.0..=max_offset[d],
scroll_bar_rect.min[d]..=(scroll_bar_rect.max[d] - handle_size),
);

if d == 0 {
Rect::from_min_max(
pos2(handle_start_point, cross.min),
pos2(handle_start_point + handle_size, cross.max),
)
} else {
Rect::from_min_max(
pos2(cross.min, handle_start_point),
pos2(cross.max, handle_start_point + handle_size),
)
}
};

let handle_rect = calculate_handle_rect(d, &state.offset);

let interact_id = id.with(d);
let sense = if self.scrolling_enabled {
Sense::click_and_drag()
Expand Down Expand Up @@ -1110,8 +1123,8 @@ impl Prepared {
let new_handle_top = pointer_pos[d] - *scroll_start_offset_from_top_left;
state.offset[d] = remap(
new_handle_top,
scroll_bar_rect.min[d]..=scroll_bar_rect.max[d],
0.0..=content_size[d],
scroll_bar_rect.min[d]..=(scroll_bar_rect.max[d] - handle_rect.size()[d]),
0.0..=max_offset[d],
);

// some manual action taken, scroll not stuck
Expand All @@ -1131,31 +1144,7 @@ impl Prepared {

if ui.is_rect_visible(outer_scroll_bar_rect) {
// Avoid frame-delay by calculating a new handle rect:
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),
)
} else {
Rect::from_min_max(
pos2(cross.min, from_content(state.offset.y)),
pos2(
cross.max,
from_content(state.offset.y + inner_rect.height()),
),
)
};
let min_handle_size = scroll_style.handle_min_length;
if handle_rect.size()[d] < min_handle_size {
handle_rect = Rect::from_center_size(
handle_rect.center(),
if d == 0 {
vec2(min_handle_size, handle_rect.size().y)
} else {
vec2(handle_rect.size().x, min_handle_size)
},
);
}
let handle_rect = calculate_handle_rect(d, &state.offset);

let visuals = if scrolling_enabled {
// Pick visuals based on interaction with the handle.
Expand Down
Loading