Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions app/layout/Rail.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
const std = @import("std");
const dvui = @import("dvui");
const core = @import("core");
const PluginStore = @import("../store/PluginStore.zig");
const Layout = @import("Layout.zig");
const Chooser = Layout.Chooser;

Expand All @@ -20,8 +19,8 @@ pub const Host = struct {
drawFooterItems: *const fn (ctx: ?*anyopaque, size: f32) void,
/// Whether the side pane is on screen, as opposed to closed or folded away.
sidePaneShown: *const fn (ctx: ?*anyopaque) bool,
/// How many installed plugins wait for the person to say whether to load them.
undecidedPluginCount: *const fn (ctx: ?*anyopaque) usize,
/// How many plugins wait for a load decision in this view; zero for other views.
undecidedPluginCount: *const fn (ctx: ?*anyopaque, view_id: []const u8) usize,
/// An icon's rect in physical pixels, to register with a custom title bar it overlaps.
iconRect: *const fn (ctx: ?*anyopaque, r: dvui.Rect.Physical) void,
};
Expand Down Expand Up @@ -174,14 +173,10 @@ fn pickAction(host: Host, c: *const Chooser, so_far: Action) Action {
return if (host.vtable.sidePaneShown(host.ctx)) .close else .open;
}

/// One rail icon: the chooser's item, drawn as the view's glyph with the store's attention badge.
/// One rail icon: the chooser's item, drawn as the view's glyph with the host's attention badge for that view.
/// Returns the bottom of the item's cell, in physical pixels.
fn drawIcon(host: Host, c: *Chooser, view: *Layout.Surface, index: usize) f32 {
// Only the store view can carry one; nothing else in the rail has a pending-decision notion.
const undecided_count: usize = if (std.mem.eql(u8, view.id, PluginStore.view_id))
host.vtable.undecidedPluginCount(host.ctx)
else
0;
const undecided_count = host.vtable.undecidedPluginCount(host.ctx, view.id);
// Say what the dot means — a bare badge on a 20px rail icon is otherwise a riddle.
const detail: ?[]const u8 = if (undecided_count > 0)
dvui.currentWindow().arena().print("{d} plugin{s} ready to load", .{
Expand Down
6 changes: 4 additions & 2 deletions src/editor/layout.zig
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ fn explorerPane(ctx: ?*anyopaque, f: *Layout, keywords: []const []const u8) Layo
return editor.explorer.draw(editor, f, keywords);
}

fn railHost(editor: *fizzy.Editor) Rail.Host {
pub fn railHost(editor: *fizzy.Editor) Rail.Host {
return .{ .ctx = editor, .vtable = &.{
.drawFooterItems = railFooterItems,
.sidePaneShown = railSidePaneShown,
Expand All @@ -217,7 +217,9 @@ fn railSidePaneShown(ctx: ?*anyopaque) bool {
return if (editor.regionFor(sidebar)) |r| !r.isClosed() and !r.isFolded() else !editor.explorer.closed;
}

fn railUndecidedCount(ctx: ?*anyopaque) usize {
fn railUndecidedCount(ctx: ?*anyopaque, view_id: []const u8) usize {
// The rail knows no view by name; only the store's view holds the card that offers a build.
if (!std.mem.eql(u8, view_id, app.store.Store.view_id)) return 0;
const editor: *fizzy.Editor = @ptrCast(@alignCast(ctx.?));
return editor.app.undecidedPluginCount();
}
Expand Down
17 changes: 17 additions & 0 deletions tests/integration.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3067,6 +3067,23 @@ fn expectNoPanel(editor: *fizzy.Editor) !void {
try std.testing.expect(editor.regionFor(fizzy.sdk.keywords.ide.panel) == null);
}

test "rail: the undecided-plugin badge counts for the store view and no other" {
var ctx = try shim.init(std.testing.allocator);
defer ctx.deinit(std.testing.allocator);
const editor = ctx.editor;
editor.app.gpa = std.testing.allocator;
defer {
for (editor.app.undecided_plugin_ids.items) |id| editor.app.gpa.free(id);
editor.app.undecided_plugin_ids.clearAndFree(editor.app.gpa);
}
try editor.app.trackUndecidedPlugin("one");
try editor.app.trackUndecidedPlugin("two");

const host = fizzy.layout.railHost(editor);
try std.testing.expectEqual(@as(usize, 2), host.vtable.undecidedPluginCount(host.ctx, @import("app").store.Store.view_id));
try std.testing.expectEqual(@as(usize, 0), host.vtable.undecidedPluginCount(host.ctx, "test.files"));
}

test "chrome: the defaults are fizzy's own frame, Sidebar left of Main with a Panel" {
try std.testing.expectEqual(fizzy.Editor.Chrome{}, fizzy.Editor.Chrome.configured);
try withChrome(.{}, expectSidebarLeft);
Expand Down
Loading