Fix hooks.
This commit is contained in:
@@ -81,12 +81,20 @@ closing: bool = false,
|
||||
on_empty: *const fn (ctx: ?*anyopaque) void,
|
||||
on_title: *const fn (ctx: ?*anyopaque) void,
|
||||
on_status: *const fn (ctx: ?*anyopaque) void,
|
||||
|
||||
/// A pane in here just finished work. Separate from `on_status` because the
|
||||
/// tab needs the *edge*, not the state: "something finished since you were
|
||||
/// last here" cannot be recovered by looking at the panes afterwards, since
|
||||
/// one that finished before your last visit looks identical to one that
|
||||
/// finished after it.
|
||||
on_finished: *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,
|
||||
on_finished: *const fn (ctx: ?*anyopaque) void,
|
||||
ctx: ?*anyopaque,
|
||||
};
|
||||
|
||||
@@ -101,6 +109,7 @@ pub fn create(alloc: std.mem.Allocator, cbs: Callbacks) !*View {
|
||||
.on_empty = cbs.on_empty,
|
||||
.on_title = cbs.on_title,
|
||||
.on_status = cbs.on_status,
|
||||
.on_finished = cbs.on_finished,
|
||||
.ctx = cbs.ctx,
|
||||
};
|
||||
|
||||
@@ -313,6 +322,19 @@ pub fn setFocused(self: *View, pane: *Pane) void {
|
||||
self.focused = pane;
|
||||
pane.setActive(true);
|
||||
self.on_title(self.ctx);
|
||||
|
||||
// Deliberately moving into a pane answers it, the same as typing would.
|
||||
// The identity check above is what keeps this honest: work finishing in
|
||||
// the pane you are already sitting in leaves the focus unchanged, so it
|
||||
// stays flagged — which is the case the whole indicator exists for.
|
||||
pane.markAnswered();
|
||||
self.on_status(self.ctx);
|
||||
}
|
||||
|
||||
pub fn paneFinished(self: *View, pane: *Pane) void {
|
||||
_ = pane;
|
||||
if (self.closing) return;
|
||||
self.on_finished(self.ctx);
|
||||
}
|
||||
|
||||
pub fn paneTitleChanged(self: *View, pane: *Pane) void {
|
||||
@@ -347,6 +369,26 @@ pub fn status(self: *View) Status {
|
||||
return worst;
|
||||
}
|
||||
|
||||
/// Whether any pane here has finished work that hasn't been answered.
|
||||
///
|
||||
/// Any one pane is enough, and deliberately so: the view's own status can't
|
||||
/// answer this, because a tab holding three agents never goes idle as a whole
|
||||
/// until the last of them stops, and "one of them is ready for you" is worth
|
||||
/// hearing before then.
|
||||
pub fn anyDoneUnanswered(self: *View) bool {
|
||||
for (self.panes.items) |pane| if (pane.done_unanswered) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Answer the pane the user has landed in, without touching its siblings.
|
||||
///
|
||||
/// Called when a tab is opened: the pane you arrive in is the one you are
|
||||
/// looking at, while the others in a split are still holding news you have not
|
||||
/// gone to yet, and their dots are the only thing that says which.
|
||||
pub fn answerFocused(self: *View) void {
|
||||
if (self.focusedPane()) |pane| pane.markAnswered();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Layouts
|
||||
|
||||
|
||||
Reference in New Issue
Block a user