Column shell: a drag sets off from the wider of the width drawn and the owner's, so a column a short shell squeezes moves with the pointer, where it jumped back against it, and a drag with no sideways move changes no width, where it wrote the squeezed one
This commit is contained in:
3 files changed
+46
-4
No files matched your search
@@ -221,7 +221,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark.
|
|||||||
- `typography::Ellipsis` shapes its line with the text style's own run, so a strike or an underline set on its box shows (`lists::ListItem::struck`, a closed task's title).
|
- `typography::Ellipsis` shapes its line with the text style's own run, so a strike or an underline set on its box shows (`lists::ListItem::struck`, a closed task's title).
|
||||||
- Focus that must follow an item to another parent is taken by the owner and keyed by the item: a handle gpui makes for an element dies with its path (`project::KanbanBoard`, whose cards keep focus across columns).
|
- Focus that must follow an item to another parent is taken by the owner and keyed by the item: a handle gpui makes for an element dies with its path (`project::KanbanBoard`, whose cards keep focus across columns).
|
||||||
- The theme's `platform`, the system's to start, decides the window buttons Ely draws, the title bar's layout and key caps, `secondary` included (`typography::keys::keystroke`). A title bar whose buttons the OS draws follows the OS.
|
- The theme's `platform`, the system's to start, decides the window buttons Ely draws, the title bar's layout and key caps, `secondary` included (`typography::keys::keystroke`). A title bar whose buttons the OS draws follows the OS.
|
||||||
- A window whose sidebar runs to its top is `shell::ColumnShell`: each column's header drags the window; the first leaves the traffic lights room, and drawn controls lead the first header in the macOS manner or end the last. A set width is a flex basis, not a width, so it holds its header's own parts, which a width let run past it, and yields when the shell runs short; the host's header items keep one control's width and scroll when short. A resizable column drags by its border toward the filling column, its right before it and its left after it; the handle draws that border and occludes the header under it, and a drag sets off from the width drawn, not the owner's.
|
- A window whose sidebar runs to its top is `shell::ColumnShell`: each column's header drags the window; the first leaves the traffic lights room, and drawn controls lead the first header in the macOS manner or end the last. A set width is a flex basis, not a width, so it holds its header's own parts, which a width let run past it, and yields when the shell runs short; the host's header items keep one control's width and scroll when short. A resizable column drags by its border toward the filling column, its right before it and its left after it; the handle draws that border and occludes the header under it, and a drag sets off from the wider of the width drawn and the owner's, since a header's parts may hold a column wider and a short shell squeeze it narrower; a drag that has not moved sideways changes nothing.
|
||||||
- Taffy counts a flex item's text in its least width whatever width the item sets. A box that must add none lays its content absolutely inside a filling box (`shell::ColumnShell`'s title and body).
|
- Taffy counts a flex item's text in its least width whatever width the item sets. A box that must add none lays its content absolutely inside a filling box (`shell::ColumnShell`'s title and body).
|
||||||
- A centered title sits between a start and an end that grow alike from a zero basis, their padding on a box inside them, since taffy counts padding in the flex base; their content is their least width, so the title gives way before either end (`shell::TitleBar`).
|
- A centered title sits between a start and an end that grow alike from a zero basis, their padding on a box inside them, since taffy counts padding in the flex base; their content is their least width, so the title gives way before either end (`shell::TitleBar`).
|
||||||
- A pane the window's blur shows through is `shell::Vibrancy`, filled with the palette's `glass`, in a window opened `WindowBackgroundAppearance::Blurred`: vibrancy on macOS, acrylic on Windows. gpui's `MicaBackdrop` and `MicaAltBackdrop` are DWM backdrops from Windows 11 build 22621; older builds get none, in silence, and macOS plain transparency.
|
- A pane the window's blur shows through is `shell::Vibrancy`, filled with the palette's `glass`, in a window opened `WindowBackgroundAppearance::Blurred`: vibrancy on macOS, acrylic on Windows. gpui's `MicaBackdrop` and `MicaAltBackdrop` are DWM backdrops from Windows 11 build 22621; older builds get none, in silence, and macOS plain transparency.
|
||||||
|
|||||||
@@ -323,10 +323,16 @@ fn resizing(
|
|||||||
log::error!("column shell: a drag on column {ix} with no press behind it");
|
log::error!("column shell: a drag on column {ix} with no press behind it");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// The drawn width, which a header's own parts may hold past the owner's.
|
// A header's parts may hold a column wider, a short shell squeeze it narrower.
|
||||||
let start = drag.start.get().unwrap_or(event.bounds.size.width);
|
let start = drag
|
||||||
|
.start
|
||||||
|
.get()
|
||||||
|
.unwrap_or(event.bounds.size.width.max(width));
|
||||||
drag.start.set(Some(start));
|
drag.start.set(Some(start));
|
||||||
let moved = event.event.position.x - anchor;
|
let moved = event.event.position.x - anchor;
|
||||||
|
if moved == Pixels::ZERO {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let next = match drag.side {
|
let next = match drag.side {
|
||||||
Side::Left => start - moved,
|
Side::Left => start - moved,
|
||||||
Side::Right => start + moved,
|
Side::Right => start + moved,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use crate::theme::{Platform, Theme};
|
|||||||
/// Two set columns round a filling one; this view keeps their widths.
|
/// Two set columns round a filling one; this view keeps their widths.
|
||||||
struct Sided {
|
struct Sided {
|
||||||
platform: Platform,
|
platform: Platform,
|
||||||
|
width: Pixels,
|
||||||
widths: [Pixels; 2],
|
widths: [Pixels; 2],
|
||||||
heard: Vec<Pixels>,
|
heard: Vec<Pixels>,
|
||||||
}
|
}
|
||||||
@@ -31,7 +32,7 @@ impl Render for Sided {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
div().w(px(1000.0)).h(px(400.0)).flex().flex_col().child(
|
div().w(self.width).h(px(400.0)).flex().flex_col().child(
|
||||||
ColumnShell::new("shell")
|
ColumnShell::new("shell")
|
||||||
.platform(self.platform)
|
.platform(self.platform)
|
||||||
.column(side("left", 0))
|
.column(side("left", 0))
|
||||||
@@ -48,6 +49,7 @@ fn sided(
|
|||||||
) -> (Entity<Sided>, &mut VisualTestContext) {
|
) -> (Entity<Sided>, &mut VisualTestContext) {
|
||||||
let (view, cx) = cx.add_window_view(|_, _| Sided {
|
let (view, cx) = cx.add_window_view(|_, _| Sided {
|
||||||
platform,
|
platform,
|
||||||
|
width: px(1000.0),
|
||||||
widths,
|
widths,
|
||||||
heard: Vec::new(),
|
heard: Vec::new(),
|
||||||
});
|
});
|
||||||
@@ -166,3 +168,37 @@ fn a_resizing_column_needs_a_border_toward_a_filling_one(cx: &mut TestAppContext
|
|||||||
let (_, cx) = cx.add_window_view(|_, _| Unfilled);
|
let (_, cx) = cx.add_window_view(|_, _| Unfilled);
|
||||||
cx.run_until_parked();
|
cx.run_until_parked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A short shell squeezes both columns; a drag moves a border with the pointer, from the owner's width.
|
||||||
|
#[gpui::test]
|
||||||
|
fn a_squeezed_column_drags_from_the_owner_s_width(cx: &mut TestAppContext) {
|
||||||
|
cx.update(Theme::init);
|
||||||
|
let (view, cx) = cx.add_window_view(|_, _| Sided {
|
||||||
|
platform: Platform::Linux,
|
||||||
|
width: px(700.0),
|
||||||
|
widths: [px(350.0), px(350.0)],
|
||||||
|
heard: Vec::new(),
|
||||||
|
});
|
||||||
|
cx.run_until_parked();
|
||||||
|
let left = column(0, cx);
|
||||||
|
assert!(left.size.width < px(350.0), "{left:?} is squeezed");
|
||||||
|
let border = |ix: usize, cx: &mut VisualTestContext| {
|
||||||
|
let name = ["column-shell-border-0", "", "column-shell-border-2"][ix];
|
||||||
|
cx.debug_bounds(name).expect("a border").center()
|
||||||
|
};
|
||||||
|
drag(border(0, cx), px(0.0), cx);
|
||||||
|
assert_eq!(heard(&view, cx), None, "a drag with no sideways move");
|
||||||
|
drag(border(0, cx), px(20.0), cx);
|
||||||
|
assert_eq!(heard(&view, cx), Some(px(370.0)));
|
||||||
|
assert!(
|
||||||
|
column(0, cx).right() > left.right(),
|
||||||
|
"the left border moves right"
|
||||||
|
);
|
||||||
|
let right = column(2, cx);
|
||||||
|
drag(border(2, cx), px(-20.0), cx);
|
||||||
|
assert_eq!(heard(&view, cx), Some(px(370.0)));
|
||||||
|
assert!(
|
||||||
|
column(2, cx).left() < right.left(),
|
||||||
|
"the right border moves left"
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user