~mil/mepo

98af3ea2442d9fa39d58250c1128f8db1c2a3d9c — Miles Alan 1 year, 10 months ago 9dd193a highdpi-touch-bug
Attempt to fix highdpi touch bug
1 files changed, 33 insertions(+), 24 deletions(-)

M src/Mepo.zig
M src/Mepo.zig => src/Mepo.zig +33 -24
@@ 619,10 619,7 @@ fn event_multigesture(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_mousebuttondown(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    if (mepo.fingers.items.len > 1) return .None;

    if (!mepo.within_touch_bounds(e.button.x, e.button.y)) {
        mepo.drag = null;
        return .None;
    } else if (e.button.button == sdl.SDL_BUTTON_LEFT) {
    if (e.button.button == sdl.SDL_BUTTON_LEFT) {
        mepo.drag = .{
            .begin_ticks = sdl.SDL_GetTicks(),
            .point = .{ .x = e.button.x, .y = e.button.y },


@@ 696,9 693,9 @@ fn event_mousebuttonup(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
fn event_mousemotion(mepo: *@This(), e: sdl.SDL_Event) types.Pending {
    if (mepo.fingers.items.len > 1) return .None;

    if (mepo.drag != null and mepo.within_touch_bounds(e.motion.x, e.motion.y)) {
        mepo.drag.?.point.x = e.motion.x;
        mepo.drag.?.point.y = e.motion.y;
    if (mepo.drag != null) {
        mepo.drag.?.point.x = mepo.highdpi_scale_coordinate(.X, e.motion.x);
        mepo.drag.?.point.y = mepo.highdpi_scale_coordinate(.Y, e.motion.y);
        mepo.drag.?.delta_x += std.math.absInt(e.motion.xrel) catch unreachable;
        mepo.drag.?.delta_y += std.math.absInt(e.motion.yrel) catch unreachable;
        mepo.set_x(mepo.get_x() - (e.motion.xrel * p.get(p.pref.drag_scale).u));


@@ 896,18 893,21 @@ fn dispatch_check_click_hold(mepo: *@This()) void {
        return;
    }

    const threshold_hit_hold_ms = sdl.SDL_GetTicks() >= mepo.drag.?.begin_ticks + config.DragThresholdTicks;
    const threshold_hit_distance = mepo.drag.?.delta_x + mepo.drag.?.delta_y <= config.DragThresholdDelta;
    const threshold_not_dragging_ms = sdl.SDL_GetTicks() >= mepo.drag.?.begin_ticks + config.DragThresholdTicks;
    const threshold_not_dragging_delta = mepo.drag.?.delta_x + mepo.drag.?.delta_y <= config.DragThresholdDelta;

    if (threshold_hit_hold_ms and threshold_hit_distance) {
        // E.g ignore hold on ui buttons
    // UI Button clicking functionality
    if (threshold_not_dragging_delta) {
        if (mepo.blit_uibuttons(b: {
            var b: sdl.SDL_MouseButtonEvent = undefined;
            b.x = mepo.drag.?.point.x;
            b.y = mepo.drag.?.point.y;
            break :b b;
        }) catch null) |_| return;
    }

    // Hold click functionality (e.g. for menu in default config)
    if (threshold_not_dragging_ms and threshold_not_dragging_delta) {
        mepo.drag = null;
        // TODO: hold support for right click as well?
        if (mepo.table_clicks.get(.{ .button = sdl.SDL_BUTTON_LEFT, .clicks = -1 })) |run_expression| {


@@ 1200,26 1200,35 @@ pub fn update_debug_message(mepo: *@This(), new_msg_opt: ?[]const u8) !void {
    utilsdl.sdl_push_event_resize();
}

pub fn cursor_latlon(mepo: *@This()) struct { Lat: f64, Lon: f64 } {
    var cursor_x: c_int = undefined;
    var cursor_y: c_int = undefined;
fn highdpi_scale_coordinate(mepo: *@This(), x_or_y: enum{X, Y}, coordinate: i32) i32 {
    var gl_w: c_int = undefined;
    var gl_h: c_int = undefined;
    var win_w: c_int = undefined;
    var win_h: c_int = undefined;

    _ = sdl.SDL_GetMouseState(&cursor_x, &cursor_y);
    sdl.SDL_GL_GetDrawableSize(mepo.window, &gl_w, &gl_h);
    sdl.SDL_GetWindowSize(mepo.window, &win_w, &win_h);
    const scale_x = @divTrunc(gl_w, win_w);
    const scale_y = @divTrunc(gl_h, win_h);

    // GetMouseState does not respect scaled logical size set for high-DPI
    // displays in resizing logic (e.g. we store mepo.win_w/mepo.win_h
    // as the actual GL resolution).. thus we calculate scaling factor
    // here and scale up cursor position based on *= (gl_{w,h} / win_{w,h}
    cursor_x *= scale_x;
    cursor_y *= scale_y;
    switch (x_or_y) {
        .X => {
            const scale_x = @divTrunc(gl_w, win_w);
            return coordinate * scale_x;
        },
        .Y => {
            const scale_y = @divTrunc(gl_h, win_h);
            return coordinate * scale_y;
        }
    }
}

pub fn cursor_latlon(mepo: *@This()) struct { Lat: f64, Lon: f64 } {
    var cursor_raw_x: c_int = undefined;
    var cursor_raw_y: c_int = undefined;
    var cursor_x: i32 = undefined;
    var cursor_y: i32 = undefined;

    _ = sdl.SDL_GetMouseState(&cursor_raw_x, &cursor_raw_y);
    cursor_x = mepo.highdpi_scale_coordinate(.X, @intCast(i32, cursor_raw_x));
    cursor_y = mepo.highdpi_scale_coordinate(.Y, @intCast(i32, cursor_raw_y));

    const cursor_lat = utilconversion.px_y_to_lat(
        mepo.get_y() - @divTrunc(@intCast(i32, mepo.win_h), 2) + cursor_y,