summaryrefslogtreecommitdiff
path: root/test/column_drag.zig
diff options
context:
space:
mode:
Diffstat (limited to 'test/column_drag.zig')
-rw-r--r--test/column_drag.zig89
1 files changed, 87 insertions, 2 deletions
diff --git a/test/column_drag.zig b/test/column_drag.zig
index 85dca66b..b2b8f35d 100644
--- a/test/column_drag.zig
+++ b/test/column_drag.zig
@@ -176,7 +176,7 @@ test "column grip is separate from compact text and the resize seam" {
p.update(.{ .mouse = .{ .button = .left, .kind = .release, .col = seam, .row = body_row } });
}
-test "column grips stay blank and muted across focus hover and drag" {
+test "column grips stay blank, and muted across focus and hover until grabbed" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 20 });
defer p.deinit();
_ = try p.setTestFile("left\n");
@@ -198,11 +198,12 @@ test "column grips stay blank and muted across focus hover and drag" {
_ = frame.reset(.retain_capacity);
const surface = try p.render(frame.allocator());
const muted: pardes.Color = .{ .rgb = p.chromeTheme().column_box_dim };
+ const lit: pardes.Color = .{ .rgb = p.chromeTheme().column_box };
for (0..p.ncol) |column| {
for (0..config.GUTTER) |offset| {
const cell = surface.at(p.col_x[column] + @as(u16, @intCast(offset)), pardes.TOPBAR_H);
try std.testing.expectEqualStrings(" ", cell.grapheme());
- try std.testing.expectEqual(muted, cell.style.bg);
+ try std.testing.expectEqual(if (dragging and column == active_column) lit else muted, cell.style.bg);
try std.testing.expectEqual(pardes.FontRole.tagline, cell.style.font_role);
}
try std.testing.expectEqual(p.col_x[column] + pardes.TAG_TEXT_INSET, (try tagLayer(p, column)).viewport.x);
@@ -252,3 +253,87 @@ test "column grip dropped in its own place moves the column's left edge" {
try std.testing.expectEqual(serials[1], p.col_serial[0]);
try std.testing.expectEqual(serials[0], p.col_serial[1]);
}
+
+/// The column of the drag preview's rail, checked to run the full height
+/// below the workspace tag in the grabbed grip's color, except through the
+/// grip and pane boxes at the window's left edge.
+fn previewRail(p: *Pardes, frame: *std.heap.ArenaAllocator) !?u16 {
+ _ = frame.reset(.retain_capacity);
+ const surface = try p.render(frame.allocator());
+ const lit: pardes.Color = .{ .rgb = p.chromeTheme().column_box };
+ var found: ?u16 = null;
+ for (0..surface.cols) |x| {
+ if (!std.mem.eql(u8, surface.at(@intCast(x), surface.rows - 1).grapheme(), "╎")) continue;
+ try std.testing.expect(found == null);
+ found = @intCast(x);
+ for (p.topBarHeight()..surface.rows) |row| {
+ const cell = surface.at(@intCast(x), @intCast(row));
+ if (x < config.GUTTER and cell.style.font_role == .tagline) {
+ try std.testing.expect(!std.mem.eql(u8, cell.grapheme(), "╎"));
+ continue;
+ }
+ try std.testing.expectEqualStrings("╎", cell.grapheme());
+ try std.testing.expectEqual(lit, cell.style.fg);
+ }
+ }
+ return found;
+}
+
+test "column grip drag previews where the column lands, in the seam beside its rule" {
+ const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 120, .rows = 24 });
+ defer p.deinit();
+ _ = try p.setTestFile("body\n");
+ p.presentation.enabled = false;
+ p.settings.column_tags = true;
+ for (0..2) |_| {
+ try std.testing.expect(p.executeBuiltinLine(p.active, "New"));
+ try std.testing.expect(layout.splitColumn(p, p.active, p.active, false));
+ }
+ try std.testing.expectEqual(@as(usize, 3), p.ncol);
+ p.update(.tick);
+ var frame = std.heap.ArenaAllocator.init(p.gpa);
+ defer frame.deinit();
+ _ = try p.render(frame.allocator());
+ const serials = .{ p.col_serial[0], p.col_serial[1], p.col_serial[2] };
+
+ // Held on its own grip it lands nowhere new: no rail.
+ mouse(p, .press, p.col_x[1]);
+ mouse(p, .drag, p.col_x[1] + 1);
+ try std.testing.expectEqual(@as(?u16, null), try previewRail(p, &frame));
+ // Over the first column's left half it goes first. The window edge has
+ // no seam, and the gutter there is the GUI's scroll rail, so the rail
+ // runs in the gutter's last cell.
+ mouse(p, .drag, 3);
+ try std.testing.expectEqual(@as(?u16, config.GUTTER - 1), try previewRail(p, &frame));
+ // The pointer is over the first column's "New", but a carried column
+ // aims at a place: no word lights under it.
+ for (0..p.screen_w) |x| try std.testing.expect(!std.meta.eql(p.surface.at(@intCast(x), pardes.TOPBAR_H).style.bg, pardes.Color{ .rgb = p.theme().sel_bg }));
+ mouse(p, .release, 3);
+ try std.testing.expectEqual(serials[1], p.col_serial[0]);
+ try std.testing.expectEqual(serials[0], p.col_serial[1]);
+
+ // Past the middle column's middle it lands after it: the rail is in the
+ // seam cell left of the last column's rule, where a border drag's is.
+ mouse(p, .press, p.col_x[0]);
+ const past = p.col_x[1] + p.col_w[1] - 2;
+ mouse(p, .drag, past);
+ try std.testing.expectEqual(@as(?u16, p.col_x[2] - 1), try previewRail(p, &frame));
+ // Past the last column's middle: the window's last cell.
+ mouse(p, .drag, p.col_x[2] + p.col_w[2] - 1);
+ try std.testing.expectEqual(@as(?u16, p.screen_w - 1), try previewRail(p, &frame));
+ mouse(p, .release, p.col_x[2] + p.col_w[2] - 1);
+ try std.testing.expectEqual(serials[0], p.col_serial[0]);
+ try std.testing.expectEqual(serials[2], p.col_serial[1]);
+ try std.testing.expectEqual(serials[1], p.col_serial[2]);
+
+ // Short of a neighbour's middle the left edge moves, and the preview
+ // is the seam that edge will have: exactly where the release puts it.
+ const edge = p.col_x[2];
+ mouse(p, .press, edge + 1);
+ mouse(p, .drag, edge + 1 - 6);
+ try std.testing.expectEqual(@as(?u16, edge - 6 - 1), try previewRail(p, &frame));
+ mouse(p, .release, edge + 1 - 6);
+ _ = try p.render(frame.allocator());
+ try std.testing.expectEqual(edge - 6, p.col_x[2]);
+ try std.testing.expectEqual(@as(?u16, null), try previewRail(p, &frame));
+}