Add hook system.
This commit is contained in:
@@ -20,6 +20,7 @@ const View = @This();
|
||||
|
||||
pub const Side = Layout.Side;
|
||||
pub const Kind = Pane.Kind;
|
||||
pub const Status = Pane.Status;
|
||||
|
||||
/// Where a dragged pane would land.
|
||||
pub const Target = struct {
|
||||
@@ -72,11 +73,13 @@ closing: bool = false,
|
||||
|
||||
on_empty: *const fn (ctx: ?*anyopaque) void,
|
||||
on_title: *const fn (ctx: ?*anyopaque) void,
|
||||
on_status: *const fn (ctx: ?*anyopaque) void,
|
||||
ctx: ?*anyopaque = null,
|
||||
|
||||
pub const Callbacks = struct {
|
||||
on_empty: *const fn (ctx: ?*anyopaque) void,
|
||||
on_title: *const fn (ctx: ?*anyopaque) void,
|
||||
on_status: *const fn (ctx: ?*anyopaque) void,
|
||||
ctx: ?*anyopaque,
|
||||
};
|
||||
|
||||
@@ -90,6 +93,7 @@ pub fn create(alloc: std.mem.Allocator, cbs: Callbacks) !*View {
|
||||
.layout = .{ .alloc = alloc },
|
||||
.on_empty = cbs.on_empty,
|
||||
.on_title = cbs.on_title,
|
||||
.on_status = cbs.on_status,
|
||||
.ctx = cbs.ctx,
|
||||
};
|
||||
|
||||
@@ -215,6 +219,10 @@ pub fn closePane(self: *View, pane: *Pane) void {
|
||||
self.setFocused(self.panes.items[next]);
|
||||
self.panes.items[next].grabFocus();
|
||||
self.on_title(self.ctx);
|
||||
|
||||
// Closing a busy pane changes what the tab as a whole is reporting, so
|
||||
// the row has to be recomputed even though no pane changed its own state.
|
||||
self.on_status(self.ctx);
|
||||
}
|
||||
|
||||
pub fn setFocused(self: *View, pane: *Pane) void {
|
||||
@@ -229,6 +237,34 @@ pub fn paneTitleChanged(self: *View, pane: *Pane) void {
|
||||
if (self.focused == pane or self.panes.items.len == 1) self.on_title(self.ctx);
|
||||
}
|
||||
|
||||
pub fn paneStatusChanged(self: *View, pane: *Pane) void {
|
||||
_ = pane;
|
||||
if (self.closing) return;
|
||||
self.on_status(self.ctx);
|
||||
}
|
||||
|
||||
/// The view's status: the most urgent thing any of its panes is reporting.
|
||||
///
|
||||
/// A tab is one row however many panes it holds, so the row has to say
|
||||
/// something about all of them at once. Urgency wins rather than, say, the
|
||||
/// focused pane's status, because the whole point of the indicator is to be
|
||||
/// read from another tab — a pane blocked on a permission prompt matters
|
||||
/// even if it isn't the one you left focused.
|
||||
pub fn status(self: *View) Status {
|
||||
var worst: Status = .idle;
|
||||
for (self.panes.items) |pane| {
|
||||
worst = switch (pane.status) {
|
||||
// Nothing outranks a pane waiting on the user, so this can
|
||||
// return the moment one is found.
|
||||
.needs_input => return .needs_input,
|
||||
.failed => .failed,
|
||||
.busy => if (worst == .failed) worst else .busy,
|
||||
.idle => worst,
|
||||
};
|
||||
}
|
||||
return worst;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Layouts
|
||||
|
||||
|
||||
Reference in New Issue
Block a user