summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-22 09:31:11 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:14 -0300
commita1d5ee19a648abc65b557dffa14a3b2f70577286 (patch)
treeef36c11168bcc2f7bbb9b7a6a29519c7e0882fab /src/gui
parent43b9d696f9e25ad7589527b91a74666e71ff0472 (diff)
downloadpardes-a1d5ee19a648abc65b557dffa14a3b2f70577286.tar.gz
pardes-a1d5ee19a648abc65b557dffa14a3b2f70577286.zip
Notices become chips that float over the body, not rows taken from it
A notice is an overlay now, which is the one place it is NOT like the tree-sitter context: it takes no row from the body and moves no text. Each one is a chip as wide as its own message plus a blank cell either side, anchored to the pane right edge on the body top rows. The rest of each of those rows is ordinary body text that still reads and still answers a click -- Notices.left records where each chip starts, and the hit test refuses only the cells it covers rather than the whole row. The width is counted in GRID columns rather than scaled into the tagline face the chip is drawn in, because the canonical grid is what a terminal client draws and a chip narrower than its own text there would clip it; the narrower tagline face simply leaves a little more room inside the chip. The tag layer takes the geometry the grid pass already chose, so the two cannot disagree and the GUI skipping the cells a tag layer covers leaves no stub behind. Pane.body_offset is gone with the reservation it existed for, and bodyTop takes only a rect. The body layer keeps every row it had, the scrollbar runs the full body again, and the GUI smooth-scroll extents go back to the pane. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui.zig25
1 files changed, 8 insertions, 17 deletions
diff --git a/src/gui/gui.zig b/src/gui/gui.zig
index c26629ab..3c2fd693 100644
--- a/src/gui/gui.zig
+++ b/src/gui/gui.zig
@@ -1788,7 +1788,6 @@ const Gui = struct {
scroll_pane: ?usize = null,
scroll_rect: pardes.Rect = .{ .x = 0, .y = 0, .w = 0, .h = 0 },
scroll_body_y: u16 = 0, // that rect's first BODY row (Tagbottom moves it)
- scroll_body_h: u16 = 0, // and how many rows it has, notice bands taken off
scroll_col: u16 = 0, // where the wheel turned: crossed rows are delivered
scroll_row: u16 = 0, // THERE, not wherever the pointer has drifted to since
scroll_delta: f32 = 0, // finite raw distance waiting for the render batch
@@ -4293,15 +4292,14 @@ fn stepScroll(g: *Gui, core: *pardes.Pardes, gpa: std.mem.Allocator) void {
}
g.scroll_lag = st.lag;
g.scroll_rect = r;
- const body_y = core.bodyTop(pane, r);
+ const body_y = core.bodyTop(r);
g.scroll_body_y = body_y;
- g.scroll_body_h = (r.h -| pardes.BOX_H) -| pane.body_offset;
if (st.rows != 0) {
const s = &core.surface;
g.scroll_edge_len = 0;
- if (r.w > config.GUTTER and r.h > pardes.BOX_H + pane.body_offset and r.x + r.w <= s.cols) {
+ if (r.w > config.GUTTER and r.h > pardes.BOX_H and r.x + r.w <= s.cols) {
const bw = r.w - config.GUTTER;
- const bh = (r.h - pardes.BOX_H) - pane.body_offset;
+ const bh = r.h - pardes.BOX_H;
const k: u16 = @intCast(@min(@abs(st.rows), @as(i32, bh)));
const srow = body_y + (if (st.rows > 0) k - 1 else bh - k);
if (srow < s.rows) {
@@ -4329,11 +4327,7 @@ fn emitScrollRows(g: *Gui, instances: [*]CellInstance, base: u32, surface: *pard
const x0 = r.x + config.GUTTER;
const y0 = g.scroll_body_y;
const bw = r.w - config.GUTTER;
- // The body the editor actually painted: measuring it from the rect while
- // the origin comes from bodyTop reads past the pane by the band rows, and
- // for the bottom-most pane past the surface, which drops the animation.
- const bh = g.scroll_body_h;
- if (bh == 0) return 0;
+ const bh = r.h - pardes.BOX_H;
if (x0 + bw > surface.cols or y0 + bh > surface.rows) return 0; // resized under us
var shifted = layout;
shifted.y_off -= g.scroll_lag * layout.h;
@@ -4365,7 +4359,7 @@ fn scrollScissor(g: *const Gui, layout: CellLayout, sw: u32, sh: u32) c.SDL_Rect
const px = layout.x_off + @as(f32, @floatFromInt(r.x + config.GUTTER)) * layout.w;
const py = layout.y_off + @as(f32, @floatFromInt(g.scroll_body_y)) * layout.h;
const pw = @as(f32, @floatFromInt(r.w - config.GUTTER)) * layout.w;
- const ph = @as(f32, @floatFromInt(g.scroll_body_h)) * layout.h;
+ const ph = @as(f32, @floatFromInt(r.h - pardes.BOX_H)) * layout.h;
const x0 = std.math.clamp(@as(i32, @intFromFloat(@floor(px))), 0, @as(i32, @intCast(sw)));
const y0 = std.math.clamp(@as(i32, @intFromFloat(@floor(py))), 0, @as(i32, @intCast(sh)));
const x1 = std.math.clamp(@as(i32, @intFromFloat(@ceil(px + pw))), x0, @as(i32, @intCast(sw)));
@@ -6691,14 +6685,11 @@ fn appendPaneChrome(
const chrome = core.chromeTheme();
const page = overlayRgb(core.theme().bg orelse bg_default);
for (core.panes, core.rects) |slot, r| {
- const pane = slot orelse continue;
- if (r.w <= config.GUTTER or r.h <= pardes.BOX_H) continue;
+ if (slot == null or r.w <= config.GUTTER or r.h <= pardes.BOX_H) continue;
if (@as(u32, r.x) + r.w > surface.cols or @as(u32, r.y) + r.h > surface.rows) continue;
const tag_y = if (core.settings.tag_bottom) r.y + r.h - pardes.BOX_H else r.y;
- // The rail the editor painted, notice bands included -- overlaying the
- // rows above it would tint the bands instead of the scrollbar.
- const body_y = core.bodyTop(pane, r);
- const body_end = body_y + ((r.h -| pardes.BOX_H) -| pane.body_offset);
+ const body_y = core.bodyTop(r);
+ const body_end = body_y + (r.h -| pardes.BOX_H);
const x0 = @as(f32, @floatFromInt(r.x)) * layout.w;
const x1 = x0 + @as(f32, @floatFromInt(r.w)) * layout.w;
const tag_cells = surface.cells[@as(usize, tag_y) * surface.cols + r.x + pardes.TAG_TEXT_INSET ..][0 .. r.w - pardes.TAG_TEXT_INSET];