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 == .press 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 }; } } } 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(); }