summaryrefslogtreecommitdiff
path: root/src/mouse.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/mouse.zig')
-rw-r--r--src/mouse.zig59
1 files changed, 51 insertions, 8 deletions
diff --git a/src/mouse.zig b/src/mouse.zig
index 36786612..1ca53017 100644
--- a/src/mouse.zig
+++ b/src/mouse.zig
@@ -97,13 +97,50 @@ fn cornerFixture(gpa: std.mem.Allocator) !*Pardes {
return p;
}
+test "a pane's last row of text is no resize handle; the rule over the next pane is" {
+ if (platform == .web) return;
+ const p = try cornerFixture(std.testing.allocator);
+ defer p.deinit();
+ const seam = seamRowOf(p, 1, 0);
+ const inside = p.col_x[1] + p.col_w[1] / 2;
+ p.update(.{ .mouse = .{ .button = .left, .kind = .press, .col = inside, .row = seam } });
+ try std.testing.expect(p.drag != .border_h);
+ p.update(.{ .mouse = .{ .button = .left, .kind = .release, .col = inside, .row = seam } });
+ try std.testing.expect(nudgeRightSeam(p, 2) == seam + 2);
+}
+
+test "a pane's grip dragged up or down its own column moves its top, down to a tag alone above" {
+ if (platform == .web) return;
+ const p = try cornerFixture(std.testing.allocator);
+ defer p.deinit();
+ const upper = p.col_panes[1][0];
+ const lower = p.col_panes[1][1];
+ const grip_x = p.rects[lower].x;
+ // Up, past the pane above's first row: it keeps one row, its tag.
+ const top = p.rects[upper].y;
+ p.update(.{ .mouse = .{ .button = .left, .kind = .press, .col = grip_x, .row = p.rects[lower].y } });
+ p.update(.{ .mouse = .{ .button = .left, .kind = .drag, .col = grip_x, .row = top } });
+ p.update(.{ .mouse = .{ .button = .left, .kind = .release, .col = grip_x, .row = top } });
+ p.sync();
+ try std.testing.expectEqual(@as(u16, 1), p.rects[upper].h);
+ try std.testing.expectEqual(lower, p.col_panes[1][1]);
+ // Down, inside itself: its top follows, the pane above taking the rows.
+ const to = p.rects[lower].y + 6;
+ p.update(.{ .mouse = .{ .button = .left, .kind = .press, .col = grip_x, .row = p.rects[lower].y } });
+ p.update(.{ .mouse = .{ .button = .left, .kind = .drag, .col = grip_x, .row = to } });
+ p.update(.{ .mouse = .{ .button = .left, .kind = .release, .col = grip_x, .row = to } });
+ p.sync();
+ try std.testing.expectEqual(to, p.rects[lower].y);
+}
+
fn nudgeRightSeam(p: *Pardes, delta: i32) u16 {
const from = seamRowOf(p, 1, 0);
const inside = p.col_x[1] + p.col_w[1] / 2;
const to: u16 = @intCast(@as(i32, from) + delta);
- p.update(.{ .mouse = .{ .button = .left, .kind = .press, .col = inside, .row = from } });
- p.update(.{ .mouse = .{ .button = .left, .kind = .drag, .col = inside, .row = to } });
- p.update(.{ .mouse = .{ .button = .left, .kind = .release, .col = inside, .row = to } });
+ // On the rule a pixel frontend draws over the lower pane's first row.
+ p.update(.{ .mouse = .{ .button = .left, .kind = .press, .col = inside, .row = from + 1, .rule_above = true } });
+ p.update(.{ .mouse = .{ .button = .left, .kind = .drag, .col = inside, .row = to + 1 } });
+ p.update(.{ .mouse = .{ .button = .left, .kind = .release, .col = inside, .row = to + 1 } });
p.sync();
return seamRowOf(p, 1, 0);
}
@@ -437,13 +474,17 @@ pub fn handleMouse(p: *Pardes, m: Mouse) void {
return;
}
}
- for (0..p.ncol) |cc| {
+ // Two panes are resized on the rule between them, never on a
+ // row of text; with no rule, by the grip, as acme moves a
+ // window by its button.
+ if (m.rule_above and mrow > 0) for (0..p.ncol) |cc| {
if (mcol < p.col_x[cc] or mcol >= p.col_x[cc] + p.col_w[cc]) continue;
- if (seamIdxAt(p, cc, mrow)) |k| {
- p.drag = .{ .border_h = .{ .col = cc, .top_idx = k, .cur_y = mrow } };
+ const seam = if (p.settings.tag_bottom) mrow else mrow - 1;
+ if (seamIdxAt(p, cc, seam)) |k| {
+ p.drag = .{ .border_h = .{ .col = cc, .top_idx = k, .cur_y = seam } };
return;
}
- }
+ };
const id = hovered orelse return;
const r = p.rects[id];
const pane = p.panes[id] orelse return;
@@ -597,7 +638,9 @@ pub fn dragUpdate(p: *Pardes, mcol: u16, mrow: u16, body_hit: ?Mouse.BodyHit) vo
if (k + 1 < p.col_n[cc]) {
const a = p.rects[p.col_panes[cc][k]];
const b = p.rects[p.col_panes[cc][k + 1]];
- d.cur_y = clampBorderRow(a.y, a.h, b.h, mrow, p.settings.tag_bottom);
+ // Held by the rule over the lower pane: the seam is the row above.
+ const seam = if (p.settings.tag_bottom) mrow else mrow -| 1;
+ d.cur_y = clampBorderRow(a.y, a.h, b.h, seam, p.settings.tag_bottom);
} else d.cur_y = mrow;
},
.column_move => |*d| d.cur_x = mcol,