~mil/fbp

d2fbe646704c7fe43caa9f28af18d6727565477a — Miles Alan 2 months ago 6db125a
Implement touch drag gestures for LR/RL/UD/DU

When outside of keyboard space touch events are now interpreted as drag
gestures and can be bound for LR/RL/UD/DU. By default dragging left/right
will switch between VTs and dragging up and down will increase/decrease
brightness
3 files changed, 55 insertions(+), 10 deletions(-)

M src/Runtime.zig
M src/config.zig
M src/types.zig
M src/Runtime.zig => src/Runtime.zig +39 -10
@@ 174,18 174,47 @@ fn event_touch_handle(runtime: *@This(), evt_data: linput.input_event) !void {
    };

    if (run == .FingerDrag or run == .FingerDown or run == .FingerUp) {
        // Invalidate out of bound events
        if (runtime.touch_pending.?.y < framebuffer.fb_vinfo.yres - h or runtime.touch_pending.?.y > framebuffer.fb_vinfo.yres) return;
        defer {
            if (run == .FingerUp) runtime.touch_pending = null;
        }

        // Select item on grid
        try utilgrid.grid_calculate(runtime.grid(), runtime.dims_cols(), runtime.dims_rows(), 0, config.status_height, w, h, grid_calculate_callback_register_click, runtime);
        if (runtime.touch_pending.?.y < framebuffer.fb_vinfo.yres - h or runtime.touch_pending.?.y > framebuffer.fb_vinfo.yres) {
            // OOB touches - process swipes
            if (run == .FingerDown) {
                runtime.touch_start = .{
                    .coordinates = runtime.touch_pending.?,
                    .start_time = utiltime.now(),
                };
            } else if (run == .FingerUp and runtime.touch_start != null) {
                defer runtime.touch_start = null;
                if (utiltime.timeval_delta_ms(utiltime.now(), runtime.touch_start.?.start_time) > 2000) return;
                const drag_threshold = 300;

                const swipe : ?types.DragSwipe = swipe: {
                    if (runtime.touch_pending.?.y > runtime.touch_start.?.coordinates.y + drag_threshold) break :swipe .UD;
                    if (runtime.touch_pending.?.y < runtime.touch_start.?.coordinates.y - drag_threshold) break :swipe .DU;
                    if (runtime.touch_pending.?.x > runtime.touch_start.?.coordinates.x + drag_threshold) break :swipe .LR;
                    if (runtime.touch_pending.?.x < runtime.touch_start.?.coordinates.x - drag_threshold) break :swipe .RL;
                    break :swipe null;
                };

                for (config.drag_actions) |config_action| {
                    if (config_action.swipe == swipe) {
                        config_action.handler(runtime, config_action.arg);
                        runtime.redraw = true;
                    }
                }
            }

        // Select item, deslect in grid and invalid pending touch
        if (run == .FingerUp) {
            runtime.grid_select();
            if (runtime.grid_current_index()) |current_index| runtime.grid()[current_index].touched = false;
            runtime.touch_pending = null;
            runtime.redraw = true;
        } else {
            // Select item on grid
            runtime.touch_start = null;
            try utilgrid.grid_calculate(runtime.grid(), runtime.dims_cols(), runtime.dims_rows(), 0, config.status_height, w, h, grid_calculate_callback_register_click, runtime);
            if (run == .FingerUp) {
                runtime.grid_select();
                if (runtime.grid_current_index()) |current_index| runtime.grid()[current_index].touched = false;
                runtime.redraw = true;
            }
        }
    }
}

M src/config.zig => src/config.zig +8 -0
@@ 230,3 230,11 @@ pub const keybinding_actions = [_]types.KeybindingAction{
    .{ .mode = .Lock, .submode = .{ .Lock = .ScreenOff }, .keybinding = .{ .key = .Down, .MultiTap = 1, .HoldStart = true }, .handler = handlers.handler_lock_submode_screen_toggle },
    .{ .mode = .Lock, .submode = .{ .Lock = .ScreenOff }, .keybinding = .{ .key = .Select, .MultiTap = 1, .HoldStart = true }, .handler = handlers.handler_mode_lock_toggle },
};

// Drag actions
pub const drag_actions = [_]types.DragAction{
    .{ .swipe = .LR, .handler = handlers.handler_vt_delta, .arg = .{ .Number = -1 } },
    .{ .swipe = .RL, .handler = handlers.handler_vt_delta, .arg = .{ .Number = 1 } },
    .{ .swipe = .DU, .handler = handlers.handler_backlight_delta, .arg = .{ .Number = 1 } },
    .{ .swipe = .UD, .handler = handlers.handler_backlight_delta, .arg = .{ .Number = -1 } },
};

M src/types.zig => src/types.zig +8 -0
@@ 47,6 47,14 @@ pub const KeybindingAction = struct {
    arg: ?HandlerArg = null,
};

pub const DragSwipe = enum{ LR, RL, UD, DU };

pub const DragAction = struct {
    swipe: DragSwipe,
    handler: fn (runtime: *@import("./Runtime.zig"), arg: ?HandlerArg) void,
    arg: ?HandlerArg = null,
};

pub const GridItem = struct {
    t: []const u8, // E.g. string to display (and type if v not provided)
    v: ?c_ushort = null, // E.g. v is actual key vaue which overrides t[] if provided