1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 14:20:04 -04:00

Only paint scroll fade on enabled axes

`paint_fade_areas` previously checked overflow on both axes regardless
of which directions were scroll-enabled. A horizontal-only ScrollArea
with non-zero overflow.y (which can happen when the inner ui's content
height differs from `inner_rect.size().y` for any reason) would draw
permanent top/bottom fades — visible as a stripe through the content
that never goes away because there's no way to scroll it off.

Gate the top/bottom fades behind `direction_enabled.y` and the
left/right fades behind `direction_enabled.x`. The ScrollArea already
owns this state; pass it through `show_viewport_dyn`.
This commit is contained in:
lucasmerlin
2026-05-10 01:50:37 +02:00
parent 90b83c780e
commit fca54dec2c

View File

@@ -1006,6 +1006,7 @@ impl ScrollArea {
let margin = self let margin = self
.content_margin .content_margin
.unwrap_or_else(|| ui.spacing().scroll.content_margin); .unwrap_or_else(|| ui.spacing().scroll.content_margin);
let direction_enabled = self.direction_enabled;
let mut prepared = self.begin(ui); let mut prepared = self.begin(ui);
let id = prepared.id; let id = prepared.id;
@@ -1027,7 +1028,7 @@ impl ScrollArea {
inner_rect, inner_rect,
}; };
paint_fade_areas(ui, &output); paint_fade_areas(ui, &output, direction_enabled);
output output
} }
@@ -1509,9 +1510,13 @@ impl Prepared {
} }
} }
/// Paint fade-out gradients at the top and/or bottom of a scroll area to /// Paint fade-out gradients at the edges of a scroll area to
/// indicate that more content is available beyond the visible region. /// indicate that more content is available beyond the visible region.
fn paint_fade_areas<R>(ui: &Ui, scroll_output: &ScrollAreaOutput<R>) { ///
/// Only fades for axes where scrolling is enabled — otherwise stray overflow
/// in a non-scrollable axis would draw a permanent fade with nothing to scroll
/// away to.
fn paint_fade_areas<R>(ui: &Ui, scroll_output: &ScrollAreaOutput<R>, direction_enabled: Vec2b) {
let crate::style::ScrollFadeStyle { let crate::style::ScrollFadeStyle {
strength, strength,
size: fade_size, size: fade_size,
@@ -1531,6 +1536,7 @@ fn paint_fade_areas<R>(ui: &Ui, scroll_output: &ScrollAreaOutput<R>) {
.intersect(ui.min_rect()) .intersect(ui.min_rect())
.expand(ui.visuals().clip_rect_margin); .expand(ui.visuals().clip_rect_margin);
if direction_enabled.y {
// Top fade: animate opacity based on how far we've scrolled down. // Top fade: animate opacity based on how far we've scrolled down.
if 0.0 < offset.y { if 0.0 < offset.y {
let t = (offset.y / fade_size).clamp(0.0, 1.0) * strength; let t = (offset.y / fade_size).clamp(0.0, 1.0) * strength;
@@ -1561,7 +1567,9 @@ fn paint_fade_areas<R>(ui: &Ui, scroll_output: &ScrollAreaOutput<R>) {
[bg_faded, Color32::TRANSPARENT], [bg_faded, Color32::TRANSPARENT],
)); ));
} }
}
if direction_enabled.x {
// Left fade: animate opacity based on how far we've scrolled right. // Left fade: animate opacity based on how far we've scrolled right.
if 0.0 < offset.x { if 0.0 < offset.x {
let t = (offset.x / fade_size).clamp(0.0, 1.0) * strength; let t = (offset.x / fade_size).clamp(0.0, 1.0) * strength;
@@ -1593,3 +1601,4 @@ fn paint_fade_areas<R>(ui: &Ui, scroll_output: &ScrollAreaOutput<R>) {
)); ));
} }
} }
}