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
This commit is contained in:
parent
62854672ef
commit
18cc67c604
8 changed files with 1 additions and 41 deletions
|
@ -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);
|
var button_surf = try vxfw.Surface.initWithChildren(ctx.arena, self.widget(), surf.size, surf.children);
|
||||||
@memset(button_surf.buffer, .{ .style = style });
|
@memset(button_surf.buffer, .{ .style = style });
|
||||||
button_surf.handles_mouse = true;
|
|
||||||
button_surf.focusable = true;
|
button_surf.focusable = true;
|
||||||
return button_surf;
|
return button_surf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,10 @@ child: vxfw.Widget,
|
||||||
pub fn widget(self: *const Center) vxfw.Widget {
|
pub fn widget(self: *const Center) vxfw.Widget {
|
||||||
return .{
|
return .{
|
||||||
.userdata = @constCast(self),
|
.userdata = @constCast(self),
|
||||||
.eventHandler = typeErasedEventHandler,
|
|
||||||
.drawFn = typeErasedDrawFn,
|
.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 {
|
fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
|
||||||
const self: *const Center = @ptrCast(@alignCast(ptr));
|
const self: *const Center = @ptrCast(@alignCast(ptr));
|
||||||
return self.draw(ctx);
|
return self.draw(ctx);
|
||||||
|
|
|
@ -109,20 +109,6 @@ pub fn handleEvent(self: *ListView, ctx: *vxfw.EventContext, event: vxfw.Event)
|
||||||
self.ensureScroll();
|
self.ensureScroll();
|
||||||
return ctx.consumeAndRedraw();
|
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 => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
@ -307,7 +293,6 @@ fn drawBuilder(self: *ListView, ctx: vxfw.DrawContext, builder: Builder) Allocat
|
||||||
// Set state
|
// Set state
|
||||||
{
|
{
|
||||||
surface.focusable = true;
|
surface.focusable = true;
|
||||||
surface.handles_mouse = true;
|
|
||||||
// Assume we have more. We only know we don't after drawing
|
// Assume we have more. We only know we don't after drawing
|
||||||
self.scroll.has_more = true;
|
self.scroll.has_more = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,16 +43,10 @@ pub fn vertical(padding: u16) PadValues {
|
||||||
pub fn widget(self: *const Padding) vxfw.Widget {
|
pub fn widget(self: *const Padding) vxfw.Widget {
|
||||||
return .{
|
return .{
|
||||||
.userdata = @constCast(self),
|
.userdata = @constCast(self),
|
||||||
.eventHandler = typeErasedEventHandler,
|
|
||||||
.drawFn = typeErasedDrawFn,
|
.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 {
|
fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
|
||||||
const self: *const Padding = @ptrCast(@alignCast(ptr));
|
const self: *const Padding = @ptrCast(@alignCast(ptr));
|
||||||
return self.draw(ctx);
|
return self.draw(ctx);
|
||||||
|
|
|
@ -13,16 +13,10 @@ size: vxfw.Size,
|
||||||
pub fn widget(self: *const SizedBox) vxfw.Widget {
|
pub fn widget(self: *const SizedBox) vxfw.Widget {
|
||||||
return .{
|
return .{
|
||||||
.userdata = @constCast(self),
|
.userdata = @constCast(self),
|
||||||
.eventHandler = typeErasedEventHandler,
|
|
||||||
.drawFn = typeErasedDrawFn,
|
.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 {
|
fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
|
||||||
const self: *const SizedBox = @ptrCast(@alignCast(ptr));
|
const self: *const SizedBox = @ptrCast(@alignCast(ptr));
|
||||||
const max: vxfw.MaxSize = .{
|
const max: vxfw.MaxSize = .{
|
||||||
|
|
|
@ -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);
|
var surface = try vxfw.Surface.initWithChildren(ctx.arena, self.widget(), max, &self.children);
|
||||||
surface.handles_mouse = true;
|
|
||||||
for (0..max.height) |row| {
|
for (0..max.height) |row| {
|
||||||
surface.writeCell(self.width + 1, @intCast(row), .{
|
surface.writeCell(self.width + 1, @intCast(row), .{
|
||||||
.char = .{ .grapheme = "│", .width = 1 },
|
.char = .{ .grapheme = "│", .width = 1 },
|
||||||
|
|
|
@ -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) },
|
.{ .width = max_width, .height = @max(ctx.min.height, 1) },
|
||||||
);
|
);
|
||||||
surface.focusable = true;
|
surface.focusable = true;
|
||||||
surface.handles_mouse = true;
|
|
||||||
|
|
||||||
const base: vaxis.Cell = .{ .style = .{} };
|
const base: vaxis.Cell = .{ .style = .{} };
|
||||||
@memset(surface.buffer, base);
|
@memset(surface.buffer, base);
|
||||||
|
|
|
@ -267,8 +267,6 @@ pub const Surface = struct {
|
||||||
|
|
||||||
/// If this widget / Surface is focusable
|
/// If this widget / Surface is focusable
|
||||||
focusable: bool = false,
|
focusable: bool = false,
|
||||||
/// If this widget can handle mouse events
|
|
||||||
handles_mouse: bool = false,
|
|
||||||
|
|
||||||
/// Cursor state
|
/// Cursor state
|
||||||
cursor: ?CursorState = null,
|
cursor: ?CursorState = null,
|
||||||
|
@ -332,7 +330,6 @@ pub const Surface = struct {
|
||||||
.buffer = self.buffer[0 .. self.size.width * height],
|
.buffer = self.buffer[0 .. self.size.width * height],
|
||||||
.children = self.children,
|
.children = self.children,
|
||||||
.focusable = self.focusable,
|
.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
|
/// 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 {
|
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);
|
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| {
|
for (self.children) |child| {
|
||||||
if (!child.containsPoint(point)) continue;
|
if (!child.containsPoint(point)) continue;
|
||||||
const child_point: Point = .{
|
const child_point: Point = .{
|
||||||
|
|
Loading…
Add table
Reference in a new issue