vxfw: improve .mouse_leave delivery
This commit is contained in:
parent
90eb6489a2
commit
37aeabc647
2 changed files with 84 additions and 6 deletions
73
examples/split_view.zig
Normal file
73
examples/split_view.zig
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const vaxis = @import("vaxis");
|
||||||
|
const vxfw = vaxis.vxfw;
|
||||||
|
|
||||||
|
const Model = struct {
|
||||||
|
split: vxfw.SplitView,
|
||||||
|
lhs: vxfw.Text,
|
||||||
|
rhs: vxfw.Text,
|
||||||
|
children: [1]vxfw.SubSurface = undefined,
|
||||||
|
|
||||||
|
pub fn widget(self: *Model) vxfw.Widget {
|
||||||
|
return .{
|
||||||
|
.userdata = self,
|
||||||
|
.eventHandler = Model.typeErasedEventHandler,
|
||||||
|
.drawFn = Model.typeErasedDrawFn,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void {
|
||||||
|
const self: *Model = @ptrCast(@alignCast(ptr));
|
||||||
|
switch (event) {
|
||||||
|
.init => {
|
||||||
|
self.split.lhs = self.lhs.widget();
|
||||||
|
self.split.rhs = self.rhs.widget();
|
||||||
|
},
|
||||||
|
.key_press => |key| {
|
||||||
|
if (key.matches('c', .{ .ctrl = true })) {
|
||||||
|
ctx.quit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) std.mem.Allocator.Error!vxfw.Surface {
|
||||||
|
const self: *Model = @ptrCast(@alignCast(ptr));
|
||||||
|
const surf = try self.split.widget().draw(ctx);
|
||||||
|
self.children[0] = .{
|
||||||
|
.surface = surf,
|
||||||
|
.origin = .{ .row = 0, .col = 0 },
|
||||||
|
};
|
||||||
|
return .{
|
||||||
|
.size = ctx.max.size(),
|
||||||
|
.widget = self.widget(),
|
||||||
|
.buffer = &.{},
|
||||||
|
.children = &self.children,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
|
var app = try vxfw.App.init(allocator);
|
||||||
|
defer app.deinit();
|
||||||
|
|
||||||
|
const model = try allocator.create(Model);
|
||||||
|
defer allocator.destroy(model);
|
||||||
|
model.* = .{
|
||||||
|
.lhs = .{ .text = "Left hand side" },
|
||||||
|
.rhs = .{ .text = "right hand side" },
|
||||||
|
.split = .{ .lhs = undefined, .rhs = undefined, .width = 10 },
|
||||||
|
};
|
||||||
|
|
||||||
|
model.split.lhs = model.lhs.widget();
|
||||||
|
model.split.rhs = model.rhs.widget();
|
||||||
|
|
||||||
|
try app.run(model.widget(), .{});
|
||||||
|
}
|
|
@ -240,6 +240,17 @@ const MouseHandler = struct {
|
||||||
if (sub.containsPoint(mouse_point)) {
|
if (sub.containsPoint(mouse_point)) {
|
||||||
try last_frame.hitTest(&hits, mouse_point);
|
try last_frame.hitTest(&hits, mouse_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See if our new hit test contains our last handler. If it doesn't we'll send a mouse_leave
|
||||||
|
// event
|
||||||
|
if (self.maybe_last_handler) |last_handler| {
|
||||||
|
for (hits.items) |item| {
|
||||||
|
if (item.widget.eql(last_handler)) break;
|
||||||
|
} else {
|
||||||
|
try last_handler.handleEvent(ctx, .mouse_leave);
|
||||||
|
try app.handleCommand(&ctx.cmds);
|
||||||
|
}
|
||||||
|
}
|
||||||
while (hits.popOrNull()) |item| {
|
while (hits.popOrNull()) |item| {
|
||||||
var m_local = mouse;
|
var m_local = mouse;
|
||||||
m_local.col = item.local.col;
|
m_local.col = item.local.col;
|
||||||
|
@ -250,12 +261,6 @@ const MouseHandler = struct {
|
||||||
// If the event wasn't consumed, we keep passing it on
|
// If the event wasn't consumed, we keep passing it on
|
||||||
if (!ctx.consume_event) continue;
|
if (!ctx.consume_event) continue;
|
||||||
|
|
||||||
if (self.maybe_last_handler) |last_mouse_handler| {
|
|
||||||
if (!last_mouse_handler.eql(item.widget)) {
|
|
||||||
try last_mouse_handler.handleEvent(ctx, .mouse_leave);
|
|
||||||
try app.handleCommand(&ctx.cmds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.maybe_last_handler = item.widget;
|
self.maybe_last_handler = item.widget;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue