summaryrefslogtreecommitdiff
path: root/src/tag_layer.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/tag_layer.zig')
-rw-r--r--src/tag_layer.zig25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/tag_layer.zig b/src/tag_layer.zig
index ac7c4ac2..7cfe5bbf 100644
--- a/src/tag_layer.zig
+++ b/src/tag_layer.zig
@@ -78,3 +78,28 @@ test "tag text capacity uses its own pitch and excludes the physical grip" {
try std.testing.expect(layer.hitAt(120, 85, std.math.nan(f32), 20, 6, 12) == null);
try std.testing.expect(layer.hitAt(120, 85, 10, 20, 0, 12) == null);
}
+
+/// Whether two pointer hits name the same cell of the same tag line.
+pub fn sameCell(a: ?Hit, b: ?Hit) bool {
+ const first = a orelse return b == null;
+ const second = b orelse return false;
+ return first.kind == second.kind and first.id == second.id and first.serial == second.serial and first.line == second.line and first.col == second.col;
+}
+
+/// The tag column a host's pointer is at. Clamped, a point off the tag is
+/// brought back onto line `line` of it, for a drag that leaves it.
+pub fn columnAt(p: *const pardes.Pardes, kind: Kind, id: usize, supplied: ?Hit, clamp: bool, line: u16) ?u16 {
+ var point = supplied orelse return null;
+ if (point.kind != kind or point.id != id) return null;
+ if (clamp) for (p.surface.tagLayers()) |*layer| {
+ if (layer.cols == 0 or layer.kind != kind or layer.id != id or layer.serial != point.serial or layer.line != line) continue;
+ const bw: f32 = @floatFromInt(point.metrics.body_w);
+ const bh: f32 = @floatFromInt(point.metrics.body_h);
+ const left = @as(f32, @floatFromInt(layer.viewport.x)) * bw;
+ const right = @as(f32, @floatFromInt(layer.viewport.x + layer.viewport.w)) * bw;
+ point.pixel_x = std.math.clamp(point.pixel_x, left, @max(left, right - 0.001));
+ point.pixel_y = (@as(f32, @floatFromInt(layer.viewport.y)) + 0.5) * bh;
+ break;
+ };
+ return if (p.reprojectTagHit(point)) |mapped| mapped.col else null;
+}