From 18cc67c6041c4b427a4158773017bc62f7a186b9 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Sat, 23 Nov 2024 18:13:43 -0600 Subject: [PATCH] vxfw: remove handles_mouse from Surface Don't require that surfaces explicitly declare mouse handling. We either pass an event to the eventHandler or we don't. Along with this, we remove all native widget passthrough events (IE we never pass an event to a child). Native widgets which don't handle events also set eventHandler to null, which prevents any null pointer issues also --- src/vxfw/Button.zig | 1 - src/vxfw/Center.zig | 6 ------ src/vxfw/ListView.zig | 15 --------------- src/vxfw/Padding.zig | 6 ------ src/vxfw/SizedBox.zig | 6 ------ src/vxfw/SplitView.zig | 1 - src/vxfw/TextField.zig | 1 - src/vxfw/vxfw.zig | 6 +----- 8 files changed, 1 insertion(+), 41 deletions(-) diff --git a/src/vxfw/Button.zig b/src/vxfw/Button.zig index 55000e0..70c3c8d 100644 --- a/src/vxfw/Button.zig +++ b/src/vxfw/Button.zig @@ -110,7 +110,6 @@ pub fn draw(self: *Button, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { var button_surf = try vxfw.Surface.initWithChildren(ctx.arena, self.widget(), surf.size, surf.children); @memset(button_surf.buffer, .{ .style = style }); - button_surf.handles_mouse = true; button_surf.focusable = true; return button_surf; } diff --git a/src/vxfw/Center.zig b/src/vxfw/Center.zig index 958c70d..ab682de 100644 --- a/src/vxfw/Center.zig +++ b/src/vxfw/Center.zig @@ -12,16 +12,10 @@ child: vxfw.Widget, pub fn widget(self: *const Center) vxfw.Widget { return .{ .userdata = @constCast(self), - .eventHandler = typeErasedEventHandler, .drawFn = typeErasedDrawFn, }; } -fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void { - const self: *const Center = @ptrCast(@alignCast(ptr)); - return self.child.handleEvent(ctx, event); -} - fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { const self: *const Center = @ptrCast(@alignCast(ptr)); return self.draw(ctx); diff --git a/src/vxfw/ListView.zig b/src/vxfw/ListView.zig index 4cc3f3b..683791b 100644 --- a/src/vxfw/ListView.zig +++ b/src/vxfw/ListView.zig @@ -109,20 +109,6 @@ pub fn handleEvent(self: *ListView, ctx: *vxfw.EventContext, event: vxfw.Event) self.ensureScroll(); return ctx.consumeAndRedraw(); } - - // All other keypresses go to our focused child - switch (self.children) { - .slice => |slice| { - if (slice.len == 0) return; - const child = slice[self.cursor]; - return child.handleEvent(ctx, event); - }, - .builder => |builder| { - if (builder.itemAtIdx(self.cursor, self.cursor)) |child| { - return child.handleEvent(ctx, event); - } - }, - } }, else => {}, } @@ -307,7 +293,6 @@ fn drawBuilder(self: *ListView, ctx: vxfw.DrawContext, builder: Builder) Allocat // Set state { surface.focusable = true; - surface.handles_mouse = true; // Assume we have more. We only know we don't after drawing self.scroll.has_more = true; } diff --git a/src/vxfw/Padding.zig b/src/vxfw/Padding.zig index 070a1b4..3c61f8a 100644 --- a/src/vxfw/Padding.zig +++ b/src/vxfw/Padding.zig @@ -43,16 +43,10 @@ pub fn vertical(padding: u16) PadValues { pub fn widget(self: *const Padding) vxfw.Widget { return .{ .userdata = @constCast(self), - .eventHandler = typeErasedEventHandler, .drawFn = typeErasedDrawFn, }; } -fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void { - const self: *const Padding = @ptrCast(@alignCast(ptr)); - return self.child.handleEvent(ctx, event); -} - fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { const self: *const Padding = @ptrCast(@alignCast(ptr)); return self.draw(ctx); diff --git a/src/vxfw/SizedBox.zig b/src/vxfw/SizedBox.zig index 90d2cad..b65e4ca 100644 --- a/src/vxfw/SizedBox.zig +++ b/src/vxfw/SizedBox.zig @@ -13,16 +13,10 @@ size: vxfw.Size, pub fn widget(self: *const SizedBox) vxfw.Widget { return .{ .userdata = @constCast(self), - .eventHandler = typeErasedEventHandler, .drawFn = typeErasedDrawFn, }; } -fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void { - const self: *const SizedBox = @ptrCast(@alignCast(ptr)); - return self.child.handleEvent(ctx, event); -} - fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { const self: *const SizedBox = @ptrCast(@alignCast(ptr)); const max: vxfw.MaxSize = .{ diff --git a/src/vxfw/SplitView.zig b/src/vxfw/SplitView.zig index 8c19a9a..026d040 100644 --- a/src/vxfw/SplitView.zig +++ b/src/vxfw/SplitView.zig @@ -129,7 +129,6 @@ fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw } var surface = try vxfw.Surface.initWithChildren(ctx.arena, self.widget(), max, &self.children); - surface.handles_mouse = true; for (0..max.height) |row| { surface.writeCell(self.width + 1, @intCast(row), .{ .char = .{ .grapheme = "│", .width = 1 }, diff --git a/src/vxfw/TextField.zig b/src/vxfw/TextField.zig index 313ab8e..5db4811 100644 --- a/src/vxfw/TextField.zig +++ b/src/vxfw/TextField.zig @@ -207,7 +207,6 @@ pub fn draw(self: *TextField, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surfac .{ .width = max_width, .height = @max(ctx.min.height, 1) }, ); surface.focusable = true; - surface.handles_mouse = true; const base: vaxis.Cell = .{ .style = .{} }; @memset(surface.buffer, base); diff --git a/src/vxfw/vxfw.zig b/src/vxfw/vxfw.zig index ab50792..bb98731 100644 --- a/src/vxfw/vxfw.zig +++ b/src/vxfw/vxfw.zig @@ -267,8 +267,6 @@ pub const Surface = struct { /// If this widget / Surface is focusable focusable: bool = false, - /// If this widget can handle mouse events - handles_mouse: bool = false, /// Cursor state cursor: ?CursorState = null, @@ -332,7 +330,6 @@ pub const Surface = struct { .buffer = self.buffer[0 .. self.size.width * height], .children = self.children, .focusable = self.focusable, - .handles_mouse = self.handles_mouse, }; } @@ -340,8 +337,7 @@ pub const Surface = struct { /// always be translated to local Surface coordinates. Asserts that this Surface does contain Point pub fn hitTest(self: Surface, list: *std.ArrayList(HitResult), point: Point) Allocator.Error!void { assert(point.col < self.size.width and point.row < self.size.height); - if (self.handles_mouse) - try list.append(.{ .local = point, .widget = self.widget }); + try list.append(.{ .local = point, .widget = self.widget }); for (self.children) |child| { if (!child.containsPoint(point)) continue; const child_point: Point = .{