1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
//! Pointer hits on tag bands (Layer.TagHit): comparing two, and bringing one
//! that left its band back onto it.
const std = @import("std");
const pardes = @import("pardes.zig");
const Layer = @import("Layer.zig");
const Hit = Layer.TagHit;
const Kind = Layer.Kind;
/// 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.rows == 0 or layer.kind != kind or layer.id != id or layer.serial != point.serial or line >= layer.rows) 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 + line)) + 0.5) * bh;
break;
};
return if (p.reprojectTagHit(point)) |mapped| mapped.col else null;
}
|