parent
f925e5736c
commit
c4ae23938d
|
@ -6,9 +6,11 @@ const statspatch = @import("statspatch");
|
|||
|
||||
test {
|
||||
_ = ButtonActivated;
|
||||
_ = Relayout;
|
||||
}
|
||||
|
||||
pub const ButtonActivated = @import("backevents/ButtonActivated.zig");
|
||||
pub const Relayout = @import("backevents/Relayout.zig");
|
||||
|
||||
const zenolith = @import("main.zig");
|
||||
|
||||
|
@ -29,13 +31,28 @@ fn Prototype(comptime Self: type) type {
|
|||
) orelse {});
|
||||
}
|
||||
|
||||
/// A callback that is automatically invoked before the backevent is propageted up the tree.
|
||||
/// Here, the backevent may make changes to itself before being passed to the parent widget.
|
||||
/// It is not invoked if there is no parent widget, that causes `unhandled` to be called immediately.
|
||||
pub fn prePropagate(self: *Self, next_widget: *Widget) !void {
|
||||
try (statspatch.implcallOptional(
|
||||
self,
|
||||
.ptr,
|
||||
"prePropagate",
|
||||
anyerror!void,
|
||||
.{ self, next_widget },
|
||||
) orelse {});
|
||||
}
|
||||
|
||||
/// Propagates this backevent up the widget tree. If the current (given) Widget has a parent,
|
||||
/// the event is propagated to it. Otherwise, the backevent's unhandled handler is called.
|
||||
/// Widgets should call this in their backevent handler if they do not wish to modify or
|
||||
/// intercept the backevent.
|
||||
pub fn dispatch(self: Self, widget: *Widget) anyerror!void {
|
||||
if (widget.data.parent) |p| {
|
||||
try p.backevent(self);
|
||||
var selfv = self;
|
||||
try selfv.prePropagate(p);
|
||||
try p.backevent(selfv);
|
||||
} else {
|
||||
try self.unhandled(widget);
|
||||
}
|
||||
|
|
29
src/backevents/Relayout.zig
Normal file
29
src/backevents/Relayout.zig
Normal file
|
@ -0,0 +1,29 @@
|
|||
//! This backevent is fired on a widget to signal that this widget needs another layout pass done on it.
|
||||
//! A widget should handle this if it can do another layout pass on its child while guaranteeing
|
||||
//! that its own size won't change in the process.
|
||||
//! If no widget is able to handle this backevent, the platform will be asked to do another layout pass.
|
||||
const std = @import("std");
|
||||
|
||||
const Backevent = @import("../backevent.zig").Backevent;
|
||||
const Widget = @import("../widget.zig").Widget;
|
||||
|
||||
/// Not necessarily the widget this backevent originated from, but an immediate child of the
|
||||
/// widget it is currently being dispatched on. This is the child that should be laid out again.
|
||||
child: *Widget,
|
||||
|
||||
const Relayout = @This();
|
||||
|
||||
pub fn prePropagate(self: *Relayout, selfb: *Backevent, next_widget: *Widget) !void {
|
||||
_ = selfb;
|
||||
self.child = next_widget;
|
||||
}
|
||||
|
||||
pub fn unhandled(self: Relayout, selfb: Backevent, root: *Widget) !void {
|
||||
_ = selfb;
|
||||
|
||||
std.debug.assert(self.child == root);
|
||||
|
||||
if (root.data.platform) |plat| {
|
||||
try plat.relayoutRoot(root);
|
||||
}
|
||||
}
|
|
@ -58,6 +58,7 @@ pub const default_platform_impls = [_]type{};
|
|||
/// The default backevents in Zenolith. Remember that these may be required by widgets.
|
||||
pub const default_backevents = [_]type{
|
||||
backevent.ButtonActivated,
|
||||
backevent.Relayout,
|
||||
};
|
||||
|
||||
const root_options = if (@hasDecl(root, "zenolith_options")) root.zenolith_options else struct {};
|
||||
|
|
|
@ -29,6 +29,18 @@ fn Prototype(comptime Self: type) type {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Do a layout pass on a given widget. The passed widget is asserted to be a root widget of
|
||||
/// this platform.
|
||||
pub fn relayoutRoot(self: *Self, root: *Widget) !void {
|
||||
try statspatch.implcall(
|
||||
self,
|
||||
.ptr,
|
||||
"relayoutRoot",
|
||||
anyerror!void,
|
||||
.{ root },
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue