diff options
| -rw-r--r-- | src/draw.zig | 42 | ||||
| -rw-r--r-- | test/gui-goldens.txt | 14 |
2 files changed, 47 insertions, 9 deletions
diff --git a/src/draw.zig b/src/draw.zig index d1d4c11b..2e608132 100644 --- a/src/draw.zig +++ b/src/draw.zig @@ -675,7 +675,14 @@ fn renderPane(p: *Pardes, s: *Surface, arena: std.mem.Allocator, pane: *Pane, r: // Grips keep physical grid dimensions, independently of tag text. .font_role = .tagline, }; - s.fill(r.x, tag_y, config.GUTTER, pane.tag_rows, box_style); + // The grip is the first row's alone, as acme's button is; the rows + // under it are the tag band's, and still grab the pane (the region + // spans them all, as acme's button column does). + s.fill(r.x, tag_y, config.GUTTER, @min(1, pane.tag_rows), box_style); + s.fill(r.x, tag_y + 1, config.GUTTER, pane.tag_rows -| 1, .{ + .bg = .{ .rgb = if (active and p.settings.focus_tint) chrome.tag_active_bg else chrome.tag_bg }, + .font_role = .tagline, + }); s.set(r.x, tag_y, switch (pane.body.mode) { .normal => config.tag_normal, .insert => config.tag_insert, @@ -739,7 +746,8 @@ pub fn paintHeaders(p: *Pardes, s: *Surface, arena: std.mem.Allocator) !void { const grip_bg = if (grabbed) chrome.column_box else chrome.column_box_dim; const lum = (@as(u16, grip_bg[0]) * 3 + @as(u16, grip_bg[1]) * 6 + @as(u16, grip_bg[2])) / 10; const ink: [3]u8 = if (lum > 140) .{ 0, 0, 0 } else .{ 255, 255, 255 }; - s.fill(p.col_x[c], region.rect.y, grip, column_rows, .{ .bg = .{ .rgb = grip_bg }, .fg = .{ .rgb = ink }, .font_role = .tagline }); + s.fill(p.col_x[c], region.rect.y, grip, @min(1, column_rows), .{ .bg = .{ .rgb = grip_bg }, .fg = .{ .rgb = ink }, .font_role = .tagline }); + s.fill(p.col_x[c], region.rect.y + 1, grip, column_rows -| 1, .{ .bg = .{ .rgb = bg }, .font_role = .tagline }); s.fill(p.col_x[c] + grip, region.rect.y, inset - grip, column_rows, .{ .bg = .{ .rgb = bg }, .font_role = .tagline }); } const top = if (p.header_focus and p.header_column == c) p.header_top else 0; @@ -1159,6 +1167,36 @@ pub fn paintPaneTag(p: *Pardes, s: *Surface, arena: std.mem.Allocator, pane: *Pa } } +test "a tag of three rows has its grip on the first, and band under it that still grabs the pane" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 30 }); + defer p.deinit(); + const pane = try p.setTestFile("text\n"); + pane.tag.own = try std.testing.allocator.dupe(u8, "Second\nthird\nfourth"); + var arena: std.heap.ArenaAllocator = .init(std.testing.allocator); + defer arena.deinit(); + for ([_]bool{ false, true }) |bottom| { + p.settings.tag_bottom = bottom; + p.sync(); + _ = arena.reset(.retain_capacity); + const s = try p.render(arena.allocator()); + const r = p.rects[0]; + const top = p.tagTop(pane, r); + try std.testing.expect(pane.tag_rows >= 3); + const chrome = p.chromeTheme(); + const band = if (p.settings.focus_tint) chrome.tag_active_bg else chrome.tag_bg; + for (0..config.GUTTER) |dx| { + const x = r.x + @as(u16, @intCast(dx)); + try std.testing.expectEqual(Color{ .rgb = chrome.box }, s.at(x, top).style.bg); + for (1..pane.tag_rows) |line| { + const cell = s.at(x, top + @as(u16, @intCast(line))); + try std.testing.expectEqual(Color{ .rgb = band }, cell.style.bg); + try std.testing.expectEqualStrings(" ", cell.grapheme()); + } + } + try std.testing.expectEqual(pane.tag_rows, s.region(.grip, 0).?.rect.h); + } +} + test "place puts every part where the painters and layers put it, in every layout" { const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 30 }); defer p.deinit(); diff --git a/test/gui-goldens.txt b/test/gui-goldens.txt index 38ca89e5..87134609 100644 --- a/test/gui-goldens.txt +++ b/test/gui-goldens.txt @@ -9,10 +9,10 @@ 09-collapsed-focus-tint ae66076fdfb0cab9a906b052df257deee5ba91a6274712d52a76d8a7adc5b415 10-tagbottom dd8ba0d3ecabf3420d000b0c9591a57278179cbd2a9060f849d283f3881d1847 11-column-tags 6b1731d1611404597c96ad77f34c2d5cd5a81c1085ec68c6779388e07ce28614 -12-multiline-tag 1b9ccd331814dc76111470f18448b1ca192e1edc3d79ea6eee19a6a78a4b1831 -13-image a52e2cf9f238447d885692cba01e68ef7fdc6ae3fc7c8fe1e95c8463c85f519c -14-theme-ink cc2ea256ddda24e1c97871f75b71ddf62fa825bd02f5d1432592d05e478c707a -15-theme-acme-light 2bde8a2bdfada7f061217f52cb2272913fc0657dbfa1d7448e1852f321f8e3bf -16-debug 129ad6f5f85b0e60e81bc6e8e78434629ee751f49731cf2eb28fd0553efd914a -17-terminal 45a3d9f823ccf28a336ef6687c9c210f9fb05cc426c0fdee98bb0ebb2a957d42 -18-mid-transition 79f90fb247f75ab284fca147028ee18ea78e77a02a57203699fb423f4bcc02fb +12-multiline-tag 0ea8f8a83fecef0e9a72d11f56bb7174739109d15074c56165274046bab48e17 +13-image 33986b288f6e2f4b3dc82113c7890980fc10362be471b3d6bf04eb1df7785e6b +14-theme-ink 3c435c76370d09c9856a7b481a52206f4ab0314729da79eef8b442d25fa210fa +15-theme-acme-light 3cf7ed81fc85ec91b5d448cab3d943f4724d754215944b4525e44885f73bccea +16-debug d2fcf18c15c1cbf771c0141b7e7f680185a099bec9102af147bf7951446afb16 +17-terminal 9b46bf9969382991243aafba88977db3bd276bb2d72dd06552b1683d3ee7d90e +18-mid-transition 11473788385e248cd7e1cc952629b3ad9a55c2068b51bf78d1494f631509e343 |
