diff options
Diffstat (limited to 'src/panes.zig')
| -rw-r--r-- | src/panes.zig | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/src/panes.zig b/src/panes.zig index 4b5c6721..f995986b 100644 --- a/src/panes.zig +++ b/src/panes.zig @@ -191,11 +191,6 @@ pub const Pane = struct { /// body layer reserves exactly `len` rows for them, the way it already /// reserves rows for sticky context headers. notices: Notices = .{}, - /// Rows the notice bands take off the TOP of the body, the way tree-sitter - /// context rows do: the body starts below them rather than being painted - /// under them. Zero while the body LAYER renders, which paints into a - /// surface of its own that carries no bands. - body_offset: u16 = 0, pub const Notices = struct { /// Painted bottom-up in this order, so a prompt keeps the row nearest @@ -204,14 +199,25 @@ pub const Pane = struct { pub const max = @typeInfo(Kind).@"enum".fields.len; kinds: [max]Kind = undefined, + /// Where each band's chip starts, as an absolute grid column. A chip + /// is only as wide as its own text, so the rest of the row underneath + /// is ordinary body text and a click there has to reach it. + left: [max]u16 = @splat(std.math.maxInt(u16)), len: u8 = 0, pub fn push(n: *Notices, kind: Kind) void { if (n.len >= max) return; n.kinds[n.len] = kind; + n.left[n.len] = std.math.maxInt(u16); n.len += 1; } + /// Is this cell inside the chip drawn for band `i`? Nothing else on + /// that row belongs to the notice. + pub fn covers(n: *const Notices, i: usize, col: u16) bool { + return i < n.len and col >= n.left[i]; + } + pub fn slice(n: *const Notices) []const Kind { return n.kinds[0..n.len]; } @@ -2041,7 +2047,7 @@ pub const File = struct { const gcrow = if (pane.cur_pinned) pane.cur_row else @as(i32, gcur.y) + goff; const cur_line: i32 = if (active and !pane.tag_edit) gcrow else std.math.minInt(i32); // the body's first row, the way renderPane derives it (Tagbottom) - const body_y = p.bodyTop(pane, r); + const body_y = p.bodyTop(r); const context_bg = p.theme().tag_bg; for (0..@min(pane.context_rows, body_h)) |context_row| { for (0..tw) |col| { @@ -2095,7 +2101,7 @@ pub const File = struct { // indexed start, same as bodyText — an empty tail simply paints nothing var flines = std.mem.splitScalar(u8, f.content[lineStart(p.gpa, f, f.scroll)..], '\n'); const total = nlines(p.gpa, f); - const body_y = p.bodyTop(pane, r); + const body_y = p.bodyTop(r); var vr: u16 = 0; while (vr < body_h) : (vr += 1) { var base: usize = undefined; @@ -2171,7 +2177,7 @@ pub const File = struct { pane_bg: pardes.Color, ) void { if (tw <= gutterWidth(pane) + 1) return; - const body_y = p.bodyTop(pane, r); + const body_y = p.bodyTop(r); const marker_fg = p.chromeTheme().lineno; var row: u16 = 0; while (row + 1 < pane.wrap_n and row + 1 < body_h) : (row += 1) { @@ -2195,9 +2201,9 @@ pub const File = struct { const tx = r.x + config.GUTTER; const tw = r.w - config.GUTTER; const prefix_width = gutterWidth(pane); - const body_y = p.bodyTop(pane, r); + const body_y = p.bodyTop(r); var vr: i32 = 0; - while (vr + @as(i32, pardes.BOX_H) < @as(i32, r.h -| pane.body_offset)) : (vr += 1) { + while (vr + @as(i32, pardes.BOX_H) < @as(i32, r.h)) : (vr += 1) { const here = pane.wrapAt(vr); if (here.line != row) continue; var hi = word_hi; @@ -5482,7 +5488,7 @@ pub const Pdf = struct { if (slot == pane) break core.rects[id]; } else return null; const cols = rect.w -| config.GUTTER; - const rows = (rect.h -| pardes.BOX_H) -| pane.body_offset; + const rows = rect.h -| pardes.BOX_H; if (cols == 0 or rows == 0) return null; return .{ .pixel_w = @as(u32, cols) * @as(u32, core.cell_pixels.w), @@ -5520,8 +5526,8 @@ pub const Pdf = struct { const rect = for (core.panes, 0..) |slot, id| { if (slot == pane) break core.rects[id]; } else return null; - const body_y = core.bodyTop(pane, rect); - if (row < body_y or row >= body_y + ((rect.h -| pardes.BOX_H) -| pane.body_offset)) return null; + const body_y = core.bodyTop(rect); + if (row < body_y or row >= body_y + (rect.h -| pardes.BOX_H)) return null; const local_y = @as(f64, @floatFromInt( @as(u32, row - body_y) * core.cell_pixels.h + core.cell_pixels.h / 2, )); @@ -5577,7 +5583,7 @@ pub const Pdf = struct { if (slot == pane) break core.rects[id]; } else return null; const body_x = @as(i64, rect.x + config.GUTTER); - const body_y = @as(i64, core.bodyTop(pane, rect)); + const body_y = @as(i64, core.bodyTop(rect)); const px = (@as(i64, col) - body_x) * core.cell_pixels.w + core.cell_pixels.w / 2; const py = (@as(i64, row) - body_y) * core.cell_pixels.h + core.cell_pixels.h / 2; return pointAtPage(state, view, page, px, py, clamp_to_page); @@ -5860,7 +5866,7 @@ pub const Pdf = struct { text_width: u16, ) bool { if (comptime !enabled) return false; - if (!core.native_images or rect.h <= pardes.BOX_H + pane.body_offset) return false; + if (!core.native_images or rect.h <= pardes.BOX_H) return false; const state = &(pane.pdf orelse return false); const view = paneViewport(core, pane) orelse return false; const key = TintKey{ .mode = state.tint, .colors = tintColors(core) }; @@ -5897,9 +5903,9 @@ pub const Pdf = struct { null, }, .x = text_x, - .y = core.bodyTop(pane, rect), + .y = core.bodyTop(rect), .w = text_width, - .h = (rect.h -| pardes.BOX_H) -| pane.body_offset, + .h = rect.h -| pardes.BOX_H, .rgba = placed.rgba, .iw = placed.width, // The texture contains the retained band, not the full page. @@ -5911,8 +5917,8 @@ pub const Pdf = struct { // This frame has spent the motion used to choose its raster band. state.scroll_travel = 0; - const body_y = core.bodyTop(pane, rect); - const body_h = (rect.h -| pardes.BOX_H) -| pane.body_offset; + const body_y = core.bodyTop(rect); + const body_h = rect.h -| pardes.BOX_H; const chrome = core.chromeTheme(); const theme = core.theme(); const pane_bg: pardes.Color = if (theme.bg) |color| .{ .rgb = color } else .default; @@ -7579,7 +7585,7 @@ pub const Terminal = struct { if (comptime !enabled) return; const s = &p.surface; if (pane.terminal == null) return; - const body_y = p.bodyTop(pane, r); + const body_y = p.bodyTop(r); var filtered_storage: FilteredColors = undefined; const filtered: ?*FilteredColors = if (pane.tty_filter) blk: { const tz_filter = tracy.zone(@src(), "filterInit"); |
