mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-21 16:02:20 +00:00
fix(settings): give the page back its scroll range, and hold the bar off the window corner
The centring added in #631 turned the settings content box into a flex column, and that cost the page most of its scroll range: the box is an item of the scroll pane, which is itself a flex column, so its height came out of a negotiation with the pane rather than from the rows it stacks. `content_size` is just that box's laid-out bounds, so the range ended a screen short of the last row — dragging to the bottom still left content cut off. `flex_shrink_0` does not help; the height is agreed, not squeezed. Centre with `mx_auto` on the column instead and leave the box a block, which reports the full height it stacks. While there, hold the content scrollbar 12px clear of the top and bottom. Every other list this bar serves sits in a bordered panel where running the full height is right; this pane is the window, and a bar drawn to the last pixel lands on the rounded corner. New `with_inset_vertical_scrollbar` takes the inset, and the existing `with_vertical_scrollbar` keeps its behaviour for the other twelve call sites.
This commit is contained in:
+18
-3
@@ -1,4 +1,4 @@
|
||||
use gpui::{AnyElement, ElementId, ScrollHandle, div, prelude::*};
|
||||
use gpui::{AnyElement, ElementId, Pixels, ScrollHandle, div, prelude::*, px};
|
||||
use gpui_component::scroll::Scrollbar;
|
||||
use gpui_component::v_flex;
|
||||
|
||||
@@ -13,6 +13,21 @@ pub(crate) fn with_vertical_scrollbar(
|
||||
id: impl Into<ElementId>,
|
||||
scroll_area: impl IntoElement,
|
||||
handle: &ScrollHandle,
|
||||
) -> AnyElement {
|
||||
with_inset_vertical_scrollbar(id, scroll_area, handle, px(0.))
|
||||
}
|
||||
|
||||
/// The same bar, held `inset_y` clear of the top and bottom of the area.
|
||||
///
|
||||
/// Every list inside a bordered panel wants the bar to run the full height —
|
||||
/// the border is already the edge. A scroll area that *is* the window has no
|
||||
/// such edge, and a bar that runs to the last pixel lands on the rounded
|
||||
/// corner and reads as if it had been clipped.
|
||||
pub(crate) fn with_inset_vertical_scrollbar(
|
||||
id: impl Into<ElementId>,
|
||||
scroll_area: impl IntoElement,
|
||||
handle: &ScrollHandle,
|
||||
inset_y: Pixels,
|
||||
) -> AnyElement {
|
||||
v_flex()
|
||||
.relative()
|
||||
@@ -28,10 +43,10 @@ pub(crate) fn with_vertical_scrollbar(
|
||||
.child(
|
||||
div()
|
||||
.absolute()
|
||||
.top_0()
|
||||
.top(inset_y)
|
||||
.left_0()
|
||||
.right_0()
|
||||
.bottom_0()
|
||||
.bottom(inset_y)
|
||||
// No `scrollbar_show` override: it falls back to
|
||||
// `cx.theme().scrollbar_show`, which `apply_theme` pins to
|
||||
// `Scrolling` for every list in the app. Overriding it here
|
||||
|
||||
+29
-11
@@ -78,6 +78,11 @@ const THEME_PANEL_W_MIN: f32 = 240.;
|
||||
/// a description stops being a paragraph and becomes a line to scan across.
|
||||
const READING_COLUMN: f32 = 640.;
|
||||
|
||||
/// How far the content scrollbar stays clear of the top and bottom of the
|
||||
/// window. The page has no chrome of its own to stop at, so a bar drawn to the
|
||||
/// last pixel runs into the window's rounded corner and looks cut off.
|
||||
const SCROLLBAR_WINDOW_INSET: f32 = 12.;
|
||||
|
||||
/// What the page gets before any list does, and the floor it may be pushed to
|
||||
/// when even that cannot be had — the numbers this file did not have.
|
||||
///
|
||||
@@ -1706,19 +1711,29 @@ impl Tty7App {
|
||||
// Chinese and Japanese pages while every other row stopped
|
||||
// at the column.
|
||||
//
|
||||
// `items_center` centres the column across the page's
|
||||
// cross axis. The cap keeps a description a paragraph
|
||||
// rather than a line to scan across, but left-aligning what
|
||||
// it caps put the whole page against the nav: on a window
|
||||
// as wide as the display it was made for, 640 points of
|
||||
// settings sat beside 1600 points of nothing. Centred, the
|
||||
// page is one column with air on both sides at every width,
|
||||
// and below the cap — where the column is the page — this
|
||||
// does nothing at all.
|
||||
v_flex().w_full().items_center().px_10().py_8().child(
|
||||
// `mx_auto` on the column centres it across the page. The
|
||||
// cap keeps a description a paragraph rather than a line to
|
||||
// scan across, but left-aligning what it caps put the whole
|
||||
// page against the nav: on a window as wide as the display
|
||||
// it was made for, 640 points of settings sat beside 1600
|
||||
// points of nothing. Centred, the page is one column with
|
||||
// air on both sides at every width, and below the cap —
|
||||
// where the column is the page — this does nothing at all.
|
||||
//
|
||||
// The centring has to come from the margin, not from an
|
||||
// `items_center` on a flex box here. The scroll pane is a
|
||||
// flex column and this box is its item: as a block it
|
||||
// reports the full height of the page it stacks, but as a
|
||||
// flex box it negotiates a height with the pane and lands
|
||||
// near the viewport, and `content_size` — which is just
|
||||
// this box's laid-out bounds — then leaves most of the page
|
||||
// outside the scroll range. `flex_shrink_0` does not buy
|
||||
// its way out of that; only staying a block does.
|
||||
div().w_full().px_10().py_8().child(
|
||||
div()
|
||||
.w_full()
|
||||
.max_w(px(READING_COLUMN * ui_scale))
|
||||
.mx_auto()
|
||||
.children(no_match_note)
|
||||
.child(content),
|
||||
),
|
||||
@@ -1731,10 +1746,13 @@ impl Tty7App {
|
||||
// the pane that covers most of the page would hide the theme
|
||||
// image behind it.
|
||||
.when_some(self.active_settings(), |pane, s| {
|
||||
pane.child(crate::ui::scrollbar::with_vertical_scrollbar(
|
||||
// Inset: this pane reaches both ends of the window, so a
|
||||
// full-height bar ends up on the rounded corner.
|
||||
pane.child(crate::ui::scrollbar::with_inset_vertical_scrollbar(
|
||||
"settings-content-scrollbar",
|
||||
body,
|
||||
&s.content_scroll,
|
||||
px(SCROLLBAR_WINDOW_INSET),
|
||||
))
|
||||
})
|
||||
.into_any_element()
|
||||
|
||||
Reference in New Issue
Block a user