Compare commits

..

No commits in common. "48c42737a6a159a93c3b2db497010212067f7ac5" and "ba86f3466931e46b1cb3d5b074f89c449e1ec23e" have entirely different histories.

14 changed files with 112 additions and 189 deletions

View file

@ -123,7 +123,7 @@ fn State(ctx_type: type) type {
input.mouse.BUTTON1 => { input.mouse.BUTTON1 => {
self.active = true; self.active = true;
self.drag_anchor = self.to_rel_cursor(x, y); self.drag_anchor = self.to_rel_cursor(x, y);
tui.need_render(@src()); tui.need_render();
}, },
input.mouse.BUTTON4, input.mouse.BUTTON5 => { input.mouse.BUTTON4, input.mouse.BUTTON5 => {
self.call_click_handler(btn_enum, self.to_rel_cursor(x, y)); self.call_click_handler(btn_enum, self.to_rel_cursor(x, y));
@ -136,7 +136,7 @@ fn State(ctx_type: type) type {
self.drag_anchor = null; self.drag_anchor = null;
self.drag_pos = null; self.drag_pos = null;
self.call_click_handler(@enumFromInt(btn), self.to_rel_cursor(x, y)); self.call_click_handler(@enumFromInt(btn), self.to_rel_cursor(x, y));
tui.need_render(@src()); tui.need_render();
return true; return true;
} else if (try m.match(.{ "D", input.event.press, tp.extract(&btn), tp.any, tp.extract(&x), tp.extract(&y), tp.any, tp.any })) { } else if (try m.match(.{ "D", input.event.press, tp.extract(&btn), tp.any, tp.extract(&x), tp.extract(&y), tp.any, tp.any })) {
self.drag_pos = .{ .x = x, .y = y }; self.drag_pos = .{ .x = x, .y = y };
@ -153,11 +153,11 @@ fn State(ctx_type: type) type {
self.drag_anchor = null; self.drag_anchor = null;
self.drag_pos = null; self.drag_pos = null;
self.call_click_handler(@enumFromInt(btn), self.to_rel_cursor(x, y)); self.call_click_handler(@enumFromInt(btn), self.to_rel_cursor(x, y));
tui.need_render(@src()); tui.need_render();
return true; return true;
} else if (try m.match(.{ "H", tp.extract(&self.hover) })) { } else if (try m.match(.{ "H", tp.extract(&self.hover) })) {
tui.rdr().request_mouse_cursor_pointer(self.hover); tui.rdr().request_mouse_cursor_pointer(self.hover);
tui.need_render(@src()); tui.need_render();
return true; return true;
} }
self.drag_anchor = null; self.drag_anchor = null;

View file

@ -132,21 +132,21 @@ pub fn State(ctx_type: type) type {
pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool {
if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) { if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) {
self.active = true; self.active = true;
tui.need_render(@src()); tui.need_render();
return true; return true;
} else if (try m.match(.{ "B", input.event.release, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) { } else if (try m.match(.{ "B", input.event.release, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) {
self.opts.on_click(self.opts.ctx, self); self.opts.on_click(self.opts.ctx, self);
self.active = false; self.active = false;
tui.need_render(@src()); tui.need_render();
return true; return true;
} else if (try m.match(.{ "D", input.event.release, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) { } else if (try m.match(.{ "D", input.event.release, @intFromEnum(input.mouse.BUTTON1), tp.any, tp.any, tp.any, tp.any, tp.any })) {
self.opts.on_click(self.opts.ctx, self); self.opts.on_click(self.opts.ctx, self);
self.active = false; self.active = false;
tui.need_render(@src()); tui.need_render();
return true; return true;
} else if (try m.match(.{ "H", tp.extract(&self.hover) })) { } else if (try m.match(.{ "H", tp.extract(&self.hover) })) {
tui.rdr().request_mouse_cursor_pointer(self.hover); tui.rdr().request_mouse_cursor_pointer(self.hover);
tui.need_render(@src()); tui.need_render();
return true; return true;
} }
return false; return false;

View file

@ -55,7 +55,7 @@ pub const VTable = struct {
walk: *const fn (ctx: *anyopaque, walk_ctx: *anyopaque, f: WalkFn, self_widget: *Self) bool, walk: *const fn (ctx: *anyopaque, walk_ctx: *anyopaque, f: WalkFn, self_widget: *Self) bool,
focus: *const fn (ctx: *anyopaque) void, focus: *const fn (ctx: *anyopaque) void,
unfocus: *const fn (ctx: *anyopaque) void, unfocus: *const fn (ctx: *anyopaque) void,
hover: *const fn (ctx: *const anyopaque) bool, hover: *const fn (ctx: *anyopaque) bool,
type_name: []const u8, type_name: []const u8,
}; };
@ -154,8 +154,8 @@ pub fn to(pimpl: anytype) Self {
} }
}.unfocus, }.unfocus,
.hover = struct { .hover = struct {
pub fn hover(ctx: *const anyopaque) bool { pub fn hover(ctx: *anyopaque) bool {
return if (comptime @hasField(child, "hover")) @as(*const child, @ptrCast(@alignCast(ctx))).hover else false; return if (comptime @hasField(child, "hover")) @as(*child, @ptrCast(@alignCast(ctx))).hover else false;
} }
}.hover, }.hover,
}, },
@ -170,7 +170,7 @@ pub fn dynamic_cast(self: Self, comptime T: type) ?*T {
} }
pub fn need_render() void { pub fn need_render() void {
tui.need_render(@src()); tui.need_render();
} }
pub fn need_reflow() void { pub fn need_reflow() void {
@ -203,10 +203,7 @@ pub fn update(self: Self) void {
} }
pub fn render(self: Self, theme: *const Theme) bool { pub fn render(self: Self, theme: *const Theme) bool {
const more = self.vtable.render(self.ptr, theme); return self.vtable.render(self.ptr, theme);
if (more)
tp.trace(tp.channel.widget, .{ "continue_by", self.vtable.type_name });
return more;
} }
pub fn resize(self: Self, pos: Box) void { pub fn resize(self: Self, pos: Box) void {
@ -245,7 +242,7 @@ pub fn unfocus(self: *Self) void {
self.vtable.unfocus(self.ptr); self.vtable.unfocus(self.ptr);
} }
pub fn hover(self: *const Self) bool { pub fn hover(self: *Self) bool {
return self.vtable.hover(self.ptr); return self.vtable.hover(self.ptr);
} }
@ -316,7 +313,7 @@ pub fn empty(allocator: Allocator, parent: Plane, layout_: Layout) !Self {
pub fn unfocus(_: *anyopaque) void {} pub fn unfocus(_: *anyopaque) void {}
}.unfocus, }.unfocus,
.hover = struct { .hover = struct {
pub fn hover(_: *const anyopaque) bool { pub fn hover(_: *anyopaque) bool {
return false; return false;
} }
}.hover, }.hover,

View file

@ -6934,7 +6934,7 @@ pub const EditorWidget = struct {
return; return;
} else { } else {
self.editor.cancel_all_matches(); self.editor.cancel_all_matches();
tui.need_render(@src()); tui.need_render();
} }
}, },
.none => {}, .none => {},

View file

@ -209,7 +209,7 @@ pub fn receive(_: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool {
var hover: bool = false; var hover: bool = false;
if (try m.match(.{ "H", tp.extract(&hover) })) { if (try m.match(.{ "H", tp.extract(&hover) })) {
tui.rdr().request_mouse_cursor_default(hover); tui.rdr().request_mouse_cursor_default(hover);
tui.need_render(@src()); tui.need_render();
return true; return true;
} }
if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.more }) or if (try m.match(.{ "B", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.more }) or
@ -453,7 +453,7 @@ const cmds = struct {
const padding = tui.get_widget_style(widget_type).padding; const padding = tui.get_widget_style(widget_type).padding;
self.menu_len = self.menu_count + padding.top + padding.bottom; self.menu_len = self.menu_count + padding.top + padding.bottom;
self.menu_w = self.menu_label_max + 2 + padding.left + padding.right; self.menu_w = self.menu_label_max + 2 + padding.left + padding.right;
tui.need_render(@src()); tui.need_render();
try tui.save_config(); try tui.save_config();
} }
pub const home_next_widget_style_meta: Meta = .{}; pub const home_next_widget_style_meta: Meta = .{};

View file

@ -605,7 +605,7 @@ const cmds = struct {
if (view == null) if (view == null)
try command.executeName("scroll_view_center", .{}); try command.executeName("scroll_view_center", .{});
} }
tui.need_render(@src()); tui.need_render();
self.location_update_from_editor(); self.location_update_from_editor();
} }
@ -613,7 +613,7 @@ const cmds = struct {
tui.reset_drag_context(); tui.reset_drag_context();
try self.create_editor(); try self.create_editor();
try command.executeName("open_scratch_buffer", command.fmt(.{ "help", @embedFile("help.md"), "markdown" })); try command.executeName("open_scratch_buffer", command.fmt(.{ "help", @embedFile("help.md"), "markdown" }));
tui.need_render(@src()); tui.need_render();
self.location_update_from_editor(); self.location_update_from_editor();
} }
pub const open_help_meta: Meta = .{ .description = "Open help" }; pub const open_help_meta: Meta = .{ .description = "Open help" };
@ -622,7 +622,7 @@ const cmds = struct {
tui.reset_drag_context(); tui.reset_drag_context();
try self.create_editor(); try self.create_editor();
try command.executeName("open_scratch_buffer", command.fmt(.{ "font test", @import("fonts.zig").font_test_text, "text" })); try command.executeName("open_scratch_buffer", command.fmt(.{ "font test", @import("fonts.zig").font_test_text, "text" }));
tui.need_render(@src()); tui.need_render();
self.location_update_from_editor(); self.location_update_from_editor();
} }
pub const open_font_test_text_meta: Meta = .{ .description = "Open font glyph test text" }; pub const open_font_test_text_meta: Meta = .{ .description = "Open font glyph test text" };
@ -631,7 +631,7 @@ const cmds = struct {
tui.reset_drag_context(); tui.reset_drag_context();
try self.create_editor(); try self.create_editor();
try command.executeName("open_scratch_buffer", command.fmt(.{ "version", root.version_info, "gitcommit" })); try command.executeName("open_scratch_buffer", command.fmt(.{ "version", root.version_info, "gitcommit" }));
tui.need_render(@src()); tui.need_render();
self.location_update_from_editor(); self.location_update_from_editor();
} }
pub const open_version_info_meta: Meta = .{ .description = "Version" }; pub const open_version_info_meta: Meta = .{ .description = "Version" };
@ -726,7 +726,7 @@ const cmds = struct {
tui.reset_drag_context(); tui.reset_drag_context();
try self.create_editor(); try self.create_editor();
try command.executeName("open_scratch_buffer", .{ .args = args }); try command.executeName("open_scratch_buffer", .{ .args = args });
tui.need_render(@src()); tui.need_render();
self.location_update_from_editor(); self.location_update_from_editor();
} }
pub const create_scratch_buffer_meta: Meta = .{ .arguments = &.{ .string, .string, .string } }; pub const create_scratch_buffer_meta: Meta = .{ .arguments = &.{ .string, .string, .string } };
@ -807,7 +807,7 @@ const cmds = struct {
new_buffer.mark_dirty(); new_buffer.mark_dirty();
new_editor.clamp(); new_editor.clamp();
new_editor.update_buf(new_buffer.root) catch {}; new_editor.update_buf(new_buffer.root) catch {};
tui.need_render(@src()); tui.need_render();
} }
try command.executeName("save_file", .{}); try command.executeName("save_file", .{});
try command.executeName("place_next_tab", command.fmt(.{ try command.executeName("place_next_tab", command.fmt(.{
@ -836,7 +836,7 @@ const cmds = struct {
const logger = log.logger("buffer"); const logger = log.logger("buffer");
defer logger.deinit(); defer logger.deinit();
logger.print("deleted buffer {s}", .{file_path}); logger.print("deleted buffer {s}", .{file_path});
tui.need_render(@src()); tui.need_render();
} }
pub const delete_buffer_meta: Meta = .{ .arguments = &.{.string} }; pub const delete_buffer_meta: Meta = .{ .arguments = &.{.string} };
@ -852,13 +852,13 @@ const cmds = struct {
return; return;
} }
_ = self.buffer_manager.close_buffer(buffer); _ = self.buffer_manager.close_buffer(buffer);
tui.need_render(@src()); tui.need_render();
} }
pub const close_buffer_meta: Meta = .{ .arguments = &.{.string} }; pub const close_buffer_meta: Meta = .{ .arguments = &.{.string} };
pub fn restore_session(self: *Self, _: Ctx) Result { pub fn restore_session(self: *Self, _: Ctx) Result {
try self.read_restore_info(); try self.read_restore_info();
tui.need_render(@src()); tui.need_render();
} }
pub const restore_session_meta: Meta = .{}; pub const restore_session_meta: Meta = .{};
@ -1117,7 +1117,7 @@ const cmds = struct {
if (self.get_active_editor()) |editor| if (std.mem.eql(u8, file_path, editor.file_path orelse "")) { if (self.get_active_editor()) |editor| if (std.mem.eql(u8, file_path, editor.file_path orelse "")) {
self.symbols_complete = true; self.symbols_complete = true;
try tui.open_overlay(@import("mode/overlay/symbol_palette.zig").Type); try tui.open_overlay(@import("mode/overlay/symbol_palette.zig").Type);
tui.need_render(@src()); tui.need_render();
}; };
} }
pub const add_document_symbol_done_meta: Meta = .{ pub const add_document_symbol_done_meta: Meta = .{
@ -1181,7 +1181,7 @@ const cmds = struct {
.palette => try tui.open_overlay(@import("mode/overlay/completion_palette.zig").Type), .palette => try tui.open_overlay(@import("mode/overlay/completion_palette.zig").Type),
.dropdown => try tui.open_overlay(@import("mode/overlay/completion_dropdown.zig").Type), .dropdown => try tui.open_overlay(@import("mode/overlay/completion_dropdown.zig").Type),
} }
tui.need_render(@src()); tui.need_render();
} }
}; };
} }
@ -1383,7 +1383,7 @@ const cmds = struct {
const buffer = self.buffer_manager.buffer_from_ref(buffer_ref) orelse return; const buffer = self.buffer_manager.buffer_from_ref(buffer_ref) orelse return;
if (self.get_editor_for_buffer(buffer)) |editor| if (editor.buffer) |eb| if (eb == buffer) { if (self.get_editor_for_buffer(buffer)) |editor| if (editor.buffer) |eb| if (eb == buffer) {
editor.smart_buffer_append(command.fmt(.{output})) catch {}; editor.smart_buffer_append(command.fmt(.{output})) catch {};
tui.need_render(@src()); tui.need_render();
return; return;
}; };
var cursor: Buffer.Cursor = .{}; var cursor: Buffer.Cursor = .{};
@ -1393,7 +1393,7 @@ const cmds = struct {
_, _, root_ = try root_.insert_chars(cursor.row, cursor.col, output, self.allocator, metrics); _, _, root_ = try root_.insert_chars(cursor.row, cursor.col, output, self.allocator, metrics);
buffer.store_undo(&[_]u8{}) catch {}; buffer.store_undo(&[_]u8{}) catch {};
buffer.update(root_); buffer.update(root_);
tui.need_render(@src()); tui.need_render();
} }
pub const shell_execute_stream_output_meta: Meta = .{ .arguments = &.{ .integer, .string } }; pub const shell_execute_stream_output_meta: Meta = .{ .arguments = &.{ .integer, .string } };
@ -1407,7 +1407,7 @@ const cmds = struct {
return; return;
} }
buffer.mark_clean(); buffer.mark_clean();
tui.need_render(@src()); tui.need_render();
} }
pub const shell_execute_stream_output_complete_meta: Meta = .{ .arguments = &.{ .integer, .string } }; pub const shell_execute_stream_output_complete_meta: Meta = .{ .arguments = &.{ .integer, .string } };
@ -2074,12 +2074,12 @@ pub fn set_info_content(self: *Self, content: []const u8, mode: enum { replace,
.replace => info.set_content(content) catch |e| return tp.exit_error(e, @errorReturnTrace()), .replace => info.set_content(content) catch |e| return tp.exit_error(e, @errorReturnTrace()),
.append => info.append_content(content) catch |e| return tp.exit_error(e, @errorReturnTrace()), .append => info.append_content(content) catch |e| return tp.exit_error(e, @errorReturnTrace()),
} }
tui.need_render(@src()); tui.need_render();
} }
pub fn cancel_info_content(self: *Self) tp.result { pub fn cancel_info_content(self: *Self) tp.result {
_ = self.toggle_panel_view(info_view, .disable) catch |e| return tp.exit_error(e, @errorReturnTrace()); _ = self.toggle_panel_view(info_view, .disable) catch |e| return tp.exit_error(e, @errorReturnTrace());
tui.need_render(@src()); tui.need_render();
} }
pub fn vcs_id_update(self: *Self, m: tp.message) void { pub fn vcs_id_update(self: *Self, m: tp.message) void {

View file

@ -179,7 +179,7 @@ pub fn Create(options: type) type {
} else { } else {
log.logger("file_browser").err("receive", tp.unexpected(m)); log.logger("file_browser").err("receive", tp.unexpected(m));
} }
tui.need_render(@src()); tui.need_render();
} }
fn add_entry(self: *Self, file_name: []const u8, entry_type: EntryType, file_type: []const u8, icon: []const u8, color: u24) !void { fn add_entry(self: *Self, file_name: []const u8, entry_type: EntryType, file_type: []const u8, icon: []const u8, color: u24) !void {

View file

@ -298,7 +298,7 @@ pub fn Create(options: type) type {
self.menu.select_down(); self.menu.select_down();
const padding = tui.get_widget_style(widget_type).padding; const padding = tui.get_widget_style(widget_type).padding;
self.do_resize(padding); self.do_resize(padding);
tui.refresh_hover(@src()); tui.refresh_hover();
self.selection_updated(); self.selection_updated();
} }
} }
@ -580,7 +580,7 @@ pub fn Create(options: type) type {
tui.set_next_style(widget_type); tui.set_next_style(widget_type);
const padding = tui.get_widget_style(widget_type).padding; const padding = tui.get_widget_style(widget_type).padding;
self.do_resize(padding); self.do_resize(padding);
tui.need_render(@src()); tui.need_render();
try tui.save_config(); try tui.save_config();
} }
pub const overlay_next_widget_style_meta: Meta = .{}; pub const overlay_next_widget_style_meta: Meta = .{};

View file

@ -273,7 +273,7 @@ fn process_project_manager(self: *Self, m: tp.message) MessageFilter.Error!void
self.menu.select_down(); self.menu.select_down();
self.need_select_first = false; self.need_select_first = false;
} }
tui.need_render(@src()); tui.need_render();
} else if (try cbor.match(m.buf, .{ } else if (try cbor.match(m.buf, .{
"PRJ", "PRJ",
"recent", "recent",
@ -291,7 +291,7 @@ fn process_project_manager(self: *Self, m: tp.message) MessageFilter.Error!void
self.menu.select_down(); self.menu.select_down();
self.need_select_first = false; self.need_select_first = false;
} }
tui.need_render(@src()); tui.need_render();
} else if (try cbor.match(m.buf, .{ "PRJ", "recent_done", tp.extract(&self.longest), tp.extract(&query), tp.extract(&self.total_files_in_project) })) { } else if (try cbor.match(m.buf, .{ "PRJ", "recent_done", tp.extract(&self.longest), tp.extract(&query), tp.extract(&self.total_files_in_project) })) {
self.update_count_hint(); self.update_count_hint();
self.query_pending = false; self.query_pending = false;
@ -492,7 +492,7 @@ const cmds = struct {
pub fn overlay_next_widget_style(self: *Self, _: Ctx) Result { pub fn overlay_next_widget_style(self: *Self, _: Ctx) Result {
tui.set_next_style(widget_type); tui.set_next_style(widget_type);
self.do_resize(); self.do_resize();
tui.need_render(@src()); tui.need_render();
try tui.save_config(); try tui.save_config();
} }
pub const overlay_next_widget_style_meta: Meta = .{}; pub const overlay_next_widget_style_meta: Meta = .{};

View file

@ -349,7 +349,7 @@ pub fn Create(options: type) type {
self.menu.select_down(); self.menu.select_down();
const padding = tui.get_widget_style(widget_type).padding; const padding = tui.get_widget_style(widget_type).padding;
self.do_resize(padding); self.do_resize(padding);
tui.refresh_hover(@src()); tui.refresh_hover();
self.selection_updated(); self.selection_updated();
} }
} }
@ -635,7 +635,7 @@ pub fn Create(options: type) type {
tui.set_next_style(widget_type); tui.set_next_style(widget_type);
const padding = tui.get_widget_style(widget_type).padding; const padding = tui.get_widget_style(widget_type).padding;
self.do_resize(padding); self.do_resize(padding);
tui.need_render(@src()); tui.need_render();
try tui.save_config(); try tui.save_config();
} }
pub const overlay_next_widget_style_meta: Meta = .{}; pub const overlay_next_widget_style_meta: Meta = .{};

View file

@ -188,7 +188,7 @@ fn process_project_manager(self: *Self, m: tp.message) MessageFilter.Error!void
self.menu.select_down(); self.menu.select_down();
self.need_select_first = false; self.need_select_first = false;
} }
tui.need_render(@src()); tui.need_render();
} else if (try cbor.match(m.buf, .{ } else if (try cbor.match(m.buf, .{
"PRJ", "PRJ",
"new_or_modified_files", "new_or_modified_files",
@ -207,7 +207,7 @@ fn process_project_manager(self: *Self, m: tp.message) MessageFilter.Error!void
self.menu.select_down(); self.menu.select_down();
self.need_select_first = false; self.need_select_first = false;
} }
tui.need_render(@src()); tui.need_render();
} else if (try cbor.match(m.buf, .{ "PRJ", "new_or_modified_files_done", tp.extract(&self.longest), tp.extract(&query) })) { } else if (try cbor.match(m.buf, .{ "PRJ", "new_or_modified_files_done", tp.extract(&self.longest), tp.extract(&query) })) {
self.query_pending = false; self.query_pending = false;
self.need_reset = true; self.need_reset = true;
@ -369,7 +369,7 @@ const cmds = struct {
pub fn overlay_next_widget_style(self: *Self, _: Ctx) Result { pub fn overlay_next_widget_style(self: *Self, _: Ctx) Result {
tui.set_next_style(widget_type); tui.set_next_style(widget_type);
self.do_resize(); self.do_resize();
tui.need_render(@src()); tui.need_render();
try tui.save_config(); try tui.save_config();
} }
pub const overlay_next_widget_style_meta: Meta = .{}; pub const overlay_next_widget_style_meta: Meta = .{};

View file

@ -95,7 +95,7 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool {
fn receive_tick(self: *Self, _: tp.pid_ref, m: tp.message) MessageFilter.Error!bool { fn receive_tick(self: *Self, _: tp.pid_ref, m: tp.message) MessageFilter.Error!bool {
if (try cbor.match(m.buf, .{"CLOCK"})) { if (try cbor.match(m.buf, .{"CLOCK"})) {
tui.need_render(@src()); tui.need_render();
self.update_tick_timer(.ticked); self.update_tick_timer(.ticked);
return true; return true;
} }

View file

@ -104,7 +104,6 @@ pub const TabBar = struct {
const TabBarTab = struct { const TabBarTab = struct {
buffer_ref: usize, buffer_ref: usize,
widget: Widget, widget: Widget,
view: ?usize,
}; };
fn init(allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler, min_tabs: ?usize) !Self { fn init(allocator: std.mem.Allocator, parent: Plane, event_handler: ?EventHandler, min_tabs: ?usize) !Self {
@ -139,14 +138,9 @@ pub const TabBar = struct {
} }
pub fn update(self: *Self) void { pub fn update(self: *Self) void {
const drag_source, const drag_btn = tui.get_drag_source(); self.update_tabs() catch {};
self.update_tabs(drag_source) catch {};
self.widget_list_widget.resize(Widget.Box.from(self.plane)); self.widget_list_widget.resize(Widget.Box.from(self.plane));
self.widget_list_widget.update(); self.widget_list_widget.update();
for (self.widget_list.widgets.items) |*split_widgetstate| if (split_widgetstate.widget.dynamic_cast(WidgetList)) |split|
for (split.widgets.items) |*widgetstate| if (widgetstate.widget.dynamic_cast(Tab.ButtonType)) |btn| if (btn.drag_pos) |_|
tui.update_drag_source(&widgetstate.widget, drag_btn);
tui.refresh_hover(@src());
} }
pub fn render(self: *Self, theme: *const Widget.Theme) bool { pub fn render(self: *Self, theme: *const Widget.Theme) bool {
@ -159,8 +153,7 @@ pub const TabBar = struct {
}); });
self.plane.fill(" "); self.plane.fill(" ");
self.plane.home(); self.plane.home();
for (self.tabs) |*tab| _ = tab.widget.render(theme); return self.widget_list_widget.render(theme);
return false;
} }
pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { pub fn receive(self: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool {
@ -207,9 +200,14 @@ pub const TabBar = struct {
if (btn.hover) break idx; if (btn.hover) break idx;
} else return; } else return;
if (dragging != hover_) { if (dragging != hover_) {
self.swap_tabs_by_index(dragging, hover_); const tmp = self.tabs[dragging];
self.tabs[dragging] = self.tabs[hover_];
self.tabs[hover_] = tmp;
if (self.tabs[dragging].widget.dynamic_cast(Tab.ButtonType)) |btn| btn.hover = false; if (self.tabs[dragging].widget.dynamic_cast(Tab.ButtonType)) |btn| btn.hover = false;
self.update(); self.update();
for (self.widget_list.widgets.items) |*widgetstate| if (widgetstate.widget.dynamic_cast(Tab.ButtonType)) |btn| if (btn.drag_pos) |_|
tui.update_drag_source(&widgetstate.widget);
tui.refresh_hover();
} }
} }
} }
@ -231,61 +229,30 @@ pub const TabBar = struct {
return self.widget_list_widget.hover(); return self.widget_list_widget.hover();
} }
fn update_tabs(self: *Self, drag_source: ?*Widget) !void { fn update_tabs(self: *Self) !void {
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager"); const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
const buffers_changed = try self.update_tab_buffers(); try self.update_tab_buffers();
const dragging = for (self.tabs) |*tab| { const prev_widget_count = self.widget_list.widgets.items.len;
if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn| while (self.widget_list.pop()) |widget| if (widget.dynamic_cast(Tab.ButtonType) == null)
if (btn.drag_pos) |_| break true;
} else false;
if (!dragging and !buffers_changed and self.widget_list.widgets.items.len > 0) return;
var prev_widget_count: usize = 0;
for (self.widget_list.widgets.items) |*split_widgetstate| if (split_widgetstate.widget.dynamic_cast(WidgetList)) |split| {
prev_widget_count += 1;
for (split.widgets.items) |_| prev_widget_count += 1;
};
for (self.widget_list.widgets.items) |*split_widget| if (split_widget.widget.dynamic_cast(WidgetList)) |split| {
for (split.widgets.items) |*widget|
if (&widget.widget == drag_source) tui.reset_drag_context();
};
while (self.widget_list.pop()) |split_widget| if (split_widget.dynamic_cast(WidgetList)) |split| {
while (split.pop()) |widget| if (widget.dynamic_cast(Tab.ButtonType) == null)
widget.deinit(self.widget_list.allocator); widget.deinit(self.widget_list.allocator);
split.deinit(self.widget_list.allocator);
};
var max_view: usize = 0;
for (self.tabs) |tab| max_view = @max(max_view, tab.view orelse 0);
var widget_count: usize = 0;
for (0..max_view + 1) |view| {
var first = true; var first = true;
var view_widget_list = try WidgetList.createH(self.allocator, self.widget_list.plane, "split", .dynamic);
try self.widget_list.add(view_widget_list.widget());
widget_count += 1;
for (self.tabs) |tab| { for (self.tabs) |tab| {
const tab_view = tab.view orelse 0;
if (tab_view != view) continue;
if (first) { if (first) {
first = false; first = false;
} else { } else {
try view_widget_list.add(try self.make_spacer(view_widget_list.plane)); try self.widget_list.add(try self.make_spacer());
widget_count += 1;
} }
try view_widget_list.add(tab.widget); try self.widget_list.add(tab.widget);
widget_count += 1;
if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn| { if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn| {
if (buffer_manager.buffer_from_ref(tab.buffer_ref)) |buffer| if (buffer_manager.buffer_from_ref(tab.buffer_ref)) |buffer|
try btn.update_label(Tab.name_from_buffer(buffer)); try btn.update_label(Tab.name_from_buffer(buffer));
} }
} }
} if (prev_widget_count != self.widget_list.widgets.items.len)
if (prev_widget_count != widget_count) tui.refresh_hover();
tui.refresh_hover(@src());
} }
fn update_tab_buffers(self: *Self) !bool { fn update_tab_buffers(self: *Self) !void {
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager"); const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
const buffers = try buffer_manager.list_unordered(self.allocator); const buffers = try buffer_manager.list_unordered(self.allocator);
defer self.allocator.free(buffers); defer self.allocator.free(buffers);
@ -311,16 +278,6 @@ pub const TabBar = struct {
} }
self.tabs = try result.toOwnedSlice(self.allocator); self.tabs = try result.toOwnedSlice(self.allocator);
if (existing_tabs.len != self.tabs.len)
return true;
for (existing_tabs, self.tabs) |tab_a, tab_b| {
if (tab_a.buffer_ref == tab_b.buffer_ref and
tab_a.view == tab_b.view)
continue;
return true;
}
return false;
} }
fn place_new_tab(self: *Self, result: *std.ArrayListUnmanaged(TabBarTab), buffer: *Buffer) !void { fn place_new_tab(self: *Self, result: *std.ArrayListUnmanaged(TabBarTab), buffer: *Buffer) !void {
@ -338,14 +295,14 @@ pub const TabBar = struct {
else else
try result.addOne(self.allocator), try result.addOne(self.allocator),
}; };
pos.* = .{ .buffer_ref = buffer_ref, .widget = tab, .view = buffer.get_last_view() }; pos.* = .{ .buffer_ref = buffer_ref, .widget = tab };
self.place_next = .atend; self.place_next = .atend;
} }
fn make_spacer(self: @This(), parent: Plane) !Widget { fn make_spacer(self: @This()) !Widget {
return spacer.create( return spacer.create(
self.allocator, self.allocator,
parent, self.widget_list.plane,
self.tab_style.spacer, self.tab_style.spacer,
self.tab_style.spacer_fg, self.tab_style.spacer_fg,
self.tab_style.spacer_bg, self.tab_style.spacer_bg,
@ -414,23 +371,9 @@ pub const TabBar = struct {
tp.trace(tp.channel.debug, .{ "swap_tabs", "not_found", "buffer_ref_b" }); tp.trace(tp.channel.debug, .{ "swap_tabs", "not_found", "buffer_ref_b" });
return; return;
}; };
self.swap_tabs_by_index(tab_a_idx, tab_b_idx);
}
fn swap_tabs_by_index(self: *Self, tab_a_idx: usize, tab_b_idx: usize) void {
const tmp = self.tabs[tab_a_idx]; const tmp = self.tabs[tab_a_idx];
self.tabs[tab_a_idx] = self.tabs[tab_b_idx]; self.tabs[tab_a_idx] = self.tabs[tab_b_idx];
self.tabs[tab_b_idx] = tmp; self.tabs[tab_b_idx] = tmp;
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
if (buffer_manager.buffer_from_ref(self.tabs[tab_a_idx].buffer_ref)) |buffer_a|
if (buffer_manager.buffer_from_ref(self.tabs[tab_b_idx].buffer_ref)) |buffer_b| {
const view_a = buffer_a.get_last_view();
const view_b = buffer_b.get_last_view();
if (view_a != view_b) {
buffer_a.set_last_view(view_b);
buffer_b.set_last_view(view_a);
}
};
tp.trace(tp.channel.debug, .{ "swap_tabs", "swapped", "indexes", tab_a_idx, tab_b_idx }); tp.trace(tp.channel.debug, .{ "swap_tabs", "swapped", "indexes", tab_a_idx, tab_b_idx });
} }
@ -474,27 +417,21 @@ pub const TabBar = struct {
while (count > 0) : (count -= 1) { while (count > 0) : (count -= 1) {
var buffer_name: ?[]const u8 = undefined; var buffer_name: ?[]const u8 = undefined;
if (!(cbor.matchValue(&iter2, cbor.extract(&buffer_name)) catch false)) return error.MatchTabBufferNameFailed; if (!(cbor.matchValue(&iter2, cbor.extract(&buffer_name)) catch false)) return error.MatchTabBufferNameFailed;
if (buffer_name) |name| { if (buffer_name) |name| if (name_to_ref(name)) |buffer_ref| {
const buffer_ref_, const buffer_view = name_to_ref_and_view(name);
if (buffer_ref_) |buffer_ref|
(try result.addOne(self.allocator)).* = .{ (try result.addOne(self.allocator)).* = .{
.buffer_ref = buffer_ref, .buffer_ref = buffer_ref,
.widget = try Tab.create(self, buffer_ref, &self.tab_style), .widget = try Tab.create(self, buffer_ref, &self.tab_style),
.view = buffer_view,
}; };
} };
} }
self.tabs = try result.toOwnedSlice(self.allocator); self.tabs = try result.toOwnedSlice(self.allocator);
iter.* = iter2; iter.* = iter2;
} }
fn name_to_ref_and_view(buffer_name: []const u8) struct { ?usize, ?usize } { fn name_to_ref(buffer_name: []const u8) ?usize {
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager"); const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
return if (buffer_manager.get_buffer_for_file(buffer_name)) |buffer| return if (buffer_manager.get_buffer_for_file(buffer_name)) |buffer| buffer_manager.buffer_to_ref(buffer) else null;
.{ buffer_manager.buffer_to_ref(buffer), buffer.get_last_view() }
else
.{ null, null };
} }
}; };

View file

@ -58,7 +58,7 @@ last_hover_y: c_int = -1,
commands: Commands = undefined, commands: Commands = undefined,
logger: log.Logger, logger: log.Logger,
drag_source: ?*Widget = null, drag_source: ?*Widget = null,
drag_button: input.MouseType = 0, drag_button: ?input.MouseType = null,
dark_theme: Widget.Theme, dark_theme: Widget.Theme,
dark_parsed_theme: ?std.json.Parsed(Widget.Theme), dark_parsed_theme: ?std.json.Parsed(Widget.Theme),
light_theme: Widget.Theme, light_theme: Widget.Theme,
@ -407,7 +407,7 @@ fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) !void {
}; };
try self.dispatch_flush_input_event(); try self.dispatch_flush_input_event();
if (self.unrendered_input_events_count > 0 and !self.frame_clock_running) if (self.unrendered_input_events_count > 0 and !self.frame_clock_running)
need_render(@src()); need_render();
return; return;
} }
@ -556,7 +556,7 @@ fn receive_safe(self: *Self, from: tp.pid_ref, m: tp.message) !void {
if (try m.match(.{"MOUSE_IDLE"})) { if (try m.match(.{"MOUSE_IDLE"})) {
if (self.mouse_idle_timer) |*t| t.deinit(); if (self.mouse_idle_timer) |*t| t.deinit();
self.mouse_idle_timer = null; self.mouse_idle_timer = null;
try self.clear_hover_focus(@src()); try self.clear_hover_focus();
return; return;
} }
@ -668,13 +668,11 @@ fn render(self: *Self) void {
if (!self.frame_clock_running) { if (!self.frame_clock_running) {
self.frame_clock.start() catch {}; self.frame_clock.start() catch {};
self.frame_clock_running = true; self.frame_clock_running = true;
tp.trace(tp.channel.widget, .{ "frame_clock_running", "started", more });
} }
} else { } else {
if (self.frame_clock_running) { if (self.frame_clock_running) {
self.frame_clock.stop() catch {}; self.frame_clock.stop() catch {};
self.frame_clock_running = false; self.frame_clock_running = false;
tp.trace(tp.channel.widget, .{ "frame_clock_running", "stopped", more });
} }
} }
} }
@ -851,34 +849,32 @@ fn update_hover(self: *Self, y: c_int, x: c_int) !?*Widget {
self.last_hover_x = x; self.last_hover_x = x;
if (y >= 0 and x >= 0) if (self.find_coord_widget(@intCast(y), @intCast(x))) |w| { if (y >= 0 and x >= 0) if (self.find_coord_widget(@intCast(y), @intCast(x))) |w| {
if (if (self.hover_focus) |h| h != w else true) { if (if (self.hover_focus) |h| h != w else true) {
tp.trace(tp.channel.debug, .{ "update_hover", if (self.hover_focus) |h| @intFromPtr(h) else 0, @intFromPtr(w) }); var buf: [256]u8 = undefined;
if (self.hover_focus) |h| if (self.is_live_widget_ptr(h)) if (self.hover_focus) |h| {
try send_hover_msg(h, false); if (self.is_live_widget_ptr(h))
_ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e, @errorReturnTrace()));
}
self.hover_focus = w; self.hover_focus = w;
try send_hover_msg(w, true); _ = try w.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", true }) catch |e| return tp.exit_error(e, @errorReturnTrace()));
} }
return w; return w;
}; };
try self.clear_hover_focus(@src()); try self.clear_hover_focus();
return null; return null;
} }
fn clear_hover_focus(self: *Self, src: std.builtin.SourceLocation) tp.result { fn clear_hover_focus(self: *Self) tp.result {
if (self.hover_focus) |h| if (self.is_live_widget_ptr(h)) if (self.hover_focus) |h| {
try send_hover_msg(h, false); var buf: [256]u8 = undefined;
tp.trace(tp.channel.debug, .{ "tui", "clear_hover_focus", if (self.hover_focus) |h| @intFromPtr(h) else 0, src.fn_name, src.file, src.line }); if (self.is_live_widget_ptr(h))
_ = try h.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", false }) catch |e| return tp.exit_error(e, @errorReturnTrace()));
}
self.hover_focus = null; self.hover_focus = null;
} }
fn send_hover_msg(widget: *const Widget, hover: bool) tp.result { pub fn refresh_hover() void {
var buf: [256]u8 = undefined;
tp.trace(tp.channel.debug, .{ "hover_msg", @intFromPtr(widget), hover });
_ = try widget.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", hover }) catch |e| return tp.exit_error(e, @errorReturnTrace()));
}
pub fn refresh_hover(src: std.builtin.SourceLocation) void {
const self = current(); const self = current();
tp.trace(tp.channel.debug, .{ "tui", "refresh_hover", if (self.hover_focus) |h| @intFromPtr(h) else 0, src.fn_name, src.file, src.line }); self.clear_hover_focus() catch return;
_ = self.update_hover(self.last_hover_y, self.last_hover_x) catch {}; _ = self.update_hover(self.last_hover_y, self.last_hover_x) catch {};
} }
@ -902,7 +898,7 @@ fn enter_overlay_mode(self: *Self, mode: type) command.Result {
self.input_mode_outer_ = self.input_mode_; self.input_mode_outer_ = self.input_mode_;
self.input_mode_ = new_mode; self.input_mode_ = new_mode;
if (self.input_mode_) |*m| m.run_init(); if (self.input_mode_) |*m| m.run_init();
refresh_hover(@src()); refresh_hover();
} }
fn enter_overlay_mode_with_args(self: *Self, mode: type, ctx: command.Context) command.Result { fn enter_overlay_mode_with_args(self: *Self, mode: type, ctx: command.Context) command.Result {
@ -914,7 +910,7 @@ fn enter_overlay_mode_with_args(self: *Self, mode: type, ctx: command.Context) c
self.input_mode_outer_ = self.input_mode_; self.input_mode_outer_ = self.input_mode_;
self.input_mode_ = try mode.create_with_args(self.allocator, ctx); self.input_mode_ = try mode.create_with_args(self.allocator, ctx);
if (self.input_mode_) |*m| m.run_init(); if (self.input_mode_) |*m| m.run_init();
refresh_hover(@src()); refresh_hover();
} }
fn get_input_mode(self: *Self, mode_name: []const u8) !Mode { fn get_input_mode(self: *Self, mode_name: []const u8) !Mode {
@ -1390,7 +1386,7 @@ const cmds = struct {
if (self.input_mode_) |*mode| mode.deinit(); if (self.input_mode_) |*mode| mode.deinit();
self.input_mode_ = self.input_mode_outer_; self.input_mode_ = self.input_mode_outer_;
self.input_mode_outer_ = null; self.input_mode_outer_ = null;
refresh_hover(@src()); refresh_hover();
} }
pub const exit_overlay_mode_meta: Meta = .{}; pub const exit_overlay_mode_meta: Meta = .{};
@ -1617,21 +1613,21 @@ const cmds = struct {
pub fn panel_next_widget_style(_: *Self, _: Ctx) Result { pub fn panel_next_widget_style(_: *Self, _: Ctx) Result {
set_next_style(.panel); set_next_style(.panel);
need_render(@src()); need_render();
try save_config(); try save_config();
} }
pub const panel_next_widget_style_meta: Meta = .{}; pub const panel_next_widget_style_meta: Meta = .{};
pub fn hint_window_next_widget_style(_: *Self, _: Ctx) Result { pub fn hint_window_next_widget_style(_: *Self, _: Ctx) Result {
set_next_style(.hint_window); set_next_style(.hint_window);
need_render(@src()); need_render();
try save_config(); try save_config();
} }
pub const hint_window_next_widget_style_meta: Meta = .{}; pub const hint_window_next_widget_style_meta: Meta = .{};
pub fn dropdown_next_widget_style(_: *Self, _: Ctx) Result { pub fn dropdown_next_widget_style(_: *Self, _: Ctx) Result {
set_next_style(.dropdown); set_next_style(.dropdown);
need_render(@src()); need_render();
try save_config(); try save_config();
} }
pub const dropdown_next_widget_style_meta: Meta = .{}; pub const dropdown_next_widget_style_meta: Meta = .{};
@ -1779,10 +1775,9 @@ pub fn get_keybind_mode() ?Mode {
return self.input_mode_ orelse self.delayed_init_input_mode; return self.input_mode_ orelse self.delayed_init_input_mode;
} }
pub fn update_drag_source(drag_source: *Widget, btn: input.MouseType) void { pub fn update_drag_source(drag_source: *Widget) void {
const self = current(); const self = current();
self.drag_source = drag_source; self.drag_source = drag_source;
self.drag_button = btn;
} }
fn set_drag_source(self: *Self, drag_source: ?*Widget, btn: input.MouseType) void { fn set_drag_source(self: *Self, drag_source: ?*Widget, btn: input.MouseType) void {
@ -1790,11 +1785,6 @@ fn set_drag_source(self: *Self, drag_source: ?*Widget, btn: input.MouseType) voi
self.drag_button = btn; self.drag_button = btn;
} }
pub fn get_drag_source() struct { ?*Widget, input.MouseType } {
const self = current();
return .{ self.drag_source, self.drag_button };
}
pub fn reset_drag_context() void { pub fn reset_drag_context() void {
const self = current(); const self = current();
self.drag_source = null; self.drag_source = null;
@ -1807,10 +1797,9 @@ fn maybe_reset_drag_source(self: *Self, btn: input.MouseType) void {
self.drag_button = 0; self.drag_button = 0;
} }
pub fn need_render(src: std.builtin.SourceLocation) void { pub fn need_render() void {
const self = current(); const self = current();
if (!(self.render_pending or self.frame_clock_running)) { if (!(self.render_pending or self.frame_clock_running)) {
tp.trace(tp.channel.debug, .{ "tui", "need_render", src.fn_name, src.file, src.line });
self.render_pending = true; self.render_pending = true;
tp.self_pid().send(.{"render"}) catch {}; tp.self_pid().send(.{"render"}) catch {};
} }
@ -1823,8 +1812,8 @@ pub fn frames_rendered() usize {
pub fn resize() void { pub fn resize() void {
mainview_widget().resize(screen()); mainview_widget().resize(screen());
refresh_hover(@src()); refresh_hover();
need_render(@src()); need_render();
} }
pub fn plane() renderer.Plane { pub fn plane() renderer.Plane {