118 lines
3.7 KiB
Zig
118 lines
3.7 KiB
Zig
const std = @import("std");
|
|
const dvui = @import("dvui");
|
|
const icons = @import("../icons.zig");
|
|
const WindowContext = @import("../WindowContext.zig");
|
|
|
|
const DocCallback = union(enum) {
|
|
select: usize,
|
|
close: usize,
|
|
};
|
|
|
|
fn documentTab(ctx: *WindowContext, index: usize, callback: *?DocCallback) void {
|
|
const row_id: usize = index;
|
|
const is_selected = if (ctx.active_document_index) |active| active == index else false;
|
|
const focus_color = dvui.themeGet().focus;
|
|
|
|
var row = dvui.box(
|
|
@src(),
|
|
.{ .dir = .horizontal },
|
|
.{
|
|
.id_extra = row_id,
|
|
.expand = .none,
|
|
.gravity_y = 0.5,
|
|
},
|
|
);
|
|
{
|
|
var hovered: bool = false;
|
|
var select_row: bool = false;
|
|
const row_data = row.data();
|
|
|
|
// Ручная обработка hover/click по строке без пометки события как handled,
|
|
// чтобы кнопка закрытия могла нормально получать свои события.
|
|
for (dvui.events()) |*e| {
|
|
switch (e.evt) {
|
|
.mouse => |*mouse| {
|
|
if (!dvui.eventMatchSimple(e, row_data)) continue;
|
|
hovered = true;
|
|
if (mouse.action == .release and mouse.button == .left) {
|
|
select_row = true;
|
|
}
|
|
},
|
|
else => {},
|
|
}
|
|
}
|
|
|
|
var overlay = dvui.overlay(@src(), .{
|
|
.margin = dvui.Rect{ .x = 4, .w = 4 },
|
|
.padding = dvui.Rect{ .x = 12, .y = 0, .w = 0, .h = 0 },
|
|
.background = is_selected or hovered,
|
|
.color_fill = if (is_selected) focus_color.opacity(0.35) else if (hovered) focus_color.opacity(0.18) else null,
|
|
.corner_radius = dvui.Rect.all(4),
|
|
});
|
|
{
|
|
var buf: [32]u8 = undefined;
|
|
const label = std.fmt.bufPrint(&buf, "Doc {d}", .{index + 1}) catch "Doc";
|
|
dvui.labelNoFmt(@src(), label, .{}, .{
|
|
.gravity_x = 0.5,
|
|
.gravity_y = 0.5,
|
|
.margin = .{ .w = 24 },
|
|
});
|
|
|
|
if (hovered) {
|
|
if (dvui.buttonIcon(@src(), "Close", icons.cross, .{}, .{}, .{
|
|
.id_extra = row_id +% 1,
|
|
.margin = dvui.Rect{ .x = 8, .w = 6 },
|
|
.padding = dvui.Rect.all(2),
|
|
.gravity_x = 1,
|
|
.gravity_y = 0.5,
|
|
})) {
|
|
callback.* = .{ .close = index };
|
|
select_row = false;
|
|
}
|
|
}
|
|
}
|
|
overlay.deinit();
|
|
|
|
if (select_row) {
|
|
callback.* = .{ .select = index };
|
|
}
|
|
}
|
|
row.deinit();
|
|
}
|
|
|
|
pub fn tabBar(ctx: *WindowContext) void {
|
|
var bar = dvui.box(
|
|
@src(),
|
|
.{ .dir = .horizontal },
|
|
.{
|
|
.expand = .horizontal,
|
|
.background = true,
|
|
.padding = .{
|
|
.x = 12,
|
|
.w = 12,
|
|
},
|
|
},
|
|
);
|
|
{
|
|
var callback: ?DocCallback = null;
|
|
for (ctx.documents.items, 0..) |_, i| {
|
|
documentTab(ctx, i, &callback);
|
|
}
|
|
if (callback) |action| {
|
|
switch (action) {
|
|
.select => |index| ctx.setActiveDocument(index),
|
|
.close => |index| ctx.closeDocument(index),
|
|
}
|
|
}
|
|
|
|
if (dvui.buttonIcon(@src(), "Create", icons.plus, .{}, .{}, .{
|
|
.gravity_y = 0,
|
|
})) {
|
|
ctx.addNewDocument() catch |err| {
|
|
std.debug.print("addNewDocument error: {}\n", .{err});
|
|
};
|
|
}
|
|
}
|
|
bar.deinit();
|
|
}
|