summaryrefslogtreecommitdiff
path: root/src/panes.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/panes.zig')
-rw-r--r--src/panes.zig46
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");