feat: position cursor at closest glyph boundary on click when beam cursor is enabled

closes #99
This commit is contained in:
CJ van den Berg 2025-01-03 13:52:47 +01:00
parent 18b0c217fc
commit dd042e2fdd
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
3 changed files with 33 additions and 8 deletions

View file

@ -89,6 +89,17 @@ pub inline fn dim_x(self: Plane) c_uint {
return @intCast(self.window.width);
}
pub fn abs_yx_to_rel_nearest_x(self: Plane, y: c_int, x: c_int, xoffset: c_int) struct { c_int, c_int } {
if (self.window.screen.width == 0 or self.window.screen.height == 0) return self.abs_yx_to_rel(y, x);
const xextra = self.window.screen.width_pix % self.window.screen.width;
const xcell = (self.window.screen.width_pix - xextra) / self.window.screen.width;
if (xcell == 0)
return self.abs_yx_to_rel(y, x);
if (xoffset > xcell / 2)
return self.abs_yx_to_rel(y, x + 1);
return self.abs_yx_to_rel(y, x);
}
pub fn abs_yx_to_rel(self: Plane, y: c_int, x: c_int) struct { c_int, c_int } {
return .{ y - self.abs_y(), x - self.abs_x() };
}

View file

@ -4687,8 +4687,15 @@ pub const EditorWidget = struct {
})(self, y, x, ypx, xpx);
}
fn mouse_click_button1(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result {
const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x);
fn mouse_pos_abs(self: *Self, y: c_int, x: c_int, xoffset: c_int) struct { c_int, c_int } {
return if (tui.current().is_cursor_beam())
self.editor.plane.abs_yx_to_rel_nearest_x(y, x, xoffset)
else
self.editor.plane.abs_yx_to_rel(y, x);
}
fn mouse_click_button1(self: *Self, y: c_int, x: c_int, _: c_int, xoffset: c_int) Result {
const y_, const x_ = self.mouse_pos_abs(y, x, xoffset);
if (self.last_btn == input.mouse.BUTTON1) {
const click_time_ms = time.milliTimestamp() - self.last_btn_time_ms;
if (click_time_ms <= double_click_time_ms) {
@ -4707,8 +4714,8 @@ pub const EditorWidget = struct {
return;
}
fn mouse_drag_button1(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result {
const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x);
fn mouse_drag_button1(self: *Self, y: c_int, x: c_int, _: c_int, xoffset: c_int) Result {
const y_, const x_ = self.mouse_pos_abs(y, x, xoffset);
self.editor.primary_drag(y_, x_);
}
@ -4716,13 +4723,13 @@ pub const EditorWidget = struct {
fn mouse_drag_button2(_: *Self, _: c_int, _: c_int, _: c_int, _: c_int) Result {}
fn mouse_click_button3(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result {
const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x);
fn mouse_click_button3(self: *Self, y: c_int, x: c_int, _: c_int, xoffset: c_int) Result {
const y_, const x_ = self.mouse_pos_abs(y, x, xoffset);
try self.editor.secondary_click(y_, x_);
}
fn mouse_drag_button3(self: *Self, y: c_int, x: c_int, _: c_int, _: c_int) Result {
const y_, const x_ = self.editor.plane.abs_yx_to_rel(y, x);
fn mouse_drag_button3(self: *Self, y: c_int, x: c_int, _: c_int, xoffset: c_int) Result {
const y_, const x_ = self.mouse_pos_abs(y, x, xoffset);
try self.editor.secondary_drag(y_, x_);
}

View file

@ -1119,3 +1119,10 @@ pub fn get_cursor_shape(self: *Self) renderer.CursorShape {
.beam => .beam,
};
}
pub fn is_cursor_beam(self: *Self) bool {
return switch (self.get_cursor_shape()) {
.beam, .beam_blink => true,
else => false,
};
}