Compare commits
7 commits
a1fbd9cf7b
...
f34285d2aa
| Author | SHA1 | Date | |
|---|---|---|---|
| f34285d2aa | |||
| 0992f08a94 | |||
| 6029c705e6 | |||
| 95cb63c42a | |||
| 18f4d9cef3 | |||
| abe15a973d | |||
| ad44443bba |
4 changed files with 178 additions and 44 deletions
|
|
@ -22,8 +22,8 @@
|
||||||
.hash = "thespian-0.0.1-owFOjjMiBgCXFa9f0-RKTDgWwYzQp1Mnec_p6hsGXj_G",
|
.hash = "thespian-0.0.1-owFOjjMiBgCXFa9f0-RKTDgWwYzQp1Mnec_p6hsGXj_G",
|
||||||
},
|
},
|
||||||
.themes = .{
|
.themes = .{
|
||||||
.url = "https://github.com/neurocyte/flow-themes/releases/download/master-870b0340c61ff0d14910d0f29be0857aed38e3d2/flow-themes.tar.gz",
|
.url = "https://github.com/neurocyte/flow-themes/releases/download/master-c6c7f18cfb2e3945cd0b71dab24271465074dbc3/flow-themes.tar.gz",
|
||||||
.hash = "N-V-__8AANPpIwA9FUVFxIHNwdWgzLqyY0Y6Va1XsbROZMN9",
|
.hash = "N-V-__8AAOKzJACguNxU76WX9M7RIhOYGuLnlasJ1-GDdhqT",
|
||||||
},
|
},
|
||||||
.fuzzig = .{
|
.fuzzig = .{
|
||||||
.url = "https://github.com/fjebaker/fuzzig/archive/4251fe4230d38e721514394a485db62ee1667ff3.tar.gz",
|
.url = "https://github.com/fjebaker/fuzzig/archive/4251fe4230d38e721514394a485db62ee1667ff3.tar.gz",
|
||||||
|
|
|
||||||
|
|
@ -1496,7 +1496,8 @@ pub fn handle_editor_event(self: *Self, editor: *ed.Editor, m: tp.message) tp.re
|
||||||
|
|
||||||
if (try m.match(.{ "E", "close" })) {
|
if (try m.match(.{ "E", "close" })) {
|
||||||
if (!self.closing_project) {
|
if (!self.closing_project) {
|
||||||
if (self.get_next_mru_buffer_for_view(self.active_view, .non_hidden)) |file_path|
|
const view = self.get_view_for_editor(editor) orelse return;
|
||||||
|
if (self.get_next_mru_buffer_for_view(view, .non_hidden)) |file_path|
|
||||||
self.show_file_async(file_path)
|
self.show_file_async(file_path)
|
||||||
else {
|
else {
|
||||||
if (self.views.widgets.items.len == 1)
|
if (self.views.widgets.items.len == 1)
|
||||||
|
|
@ -1548,7 +1549,7 @@ pub fn location_update(self: *Self, editor: *ed.Editor, m: tp.message) tp.result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn location_update_from_editor(self: *Self) void {
|
fn location_update_from_editor(self: *Self) void {
|
||||||
const editor = self.get_active_editor() orelse return;
|
const editor = self.get_active_editor() orelse return;
|
||||||
const file_path = editor.file_path orelse return;
|
const file_path = editor.file_path orelse return;
|
||||||
const ephemeral = if (editor.buffer) |buffer| buffer.is_ephemeral() else false;
|
const ephemeral = if (editor.buffer) |buffer| buffer.is_ephemeral() else false;
|
||||||
|
|
@ -1590,9 +1591,22 @@ fn store_last_match_text(self: *Self, text: ?[]const u8) void {
|
||||||
self.last_match_text = text;
|
self.last_match_text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_active_view(self: *const Self) usize {
|
||||||
|
return self.active_view;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_view_count(self: *const Self) usize {
|
||||||
|
return self.views.widgets.items.len;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_active_editor(self: *Self) ?*ed.Editor {
|
pub fn get_active_editor(self: *Self) ?*ed.Editor {
|
||||||
const active_view = self.views.get_at(self.active_view) orelse return null;
|
return self.get_editor_for_view(self.active_view);
|
||||||
const editor = active_view.get("editor") orelse return null;
|
}
|
||||||
|
|
||||||
|
pub fn get_editor_for_view(self: *Self, view_idx: usize) ?*ed.Editor {
|
||||||
|
if (view_idx >= self.get_view_count()) return null;
|
||||||
|
const view = self.views.get_at(view_idx) orelse return null;
|
||||||
|
const editor = view.get("editor") orelse return null;
|
||||||
if (editor.dynamic_cast(ed.EditorWidget)) |p| {
|
if (editor.dynamic_cast(ed.EditorWidget)) |p| {
|
||||||
return &p.editor;
|
return &p.editor;
|
||||||
}
|
}
|
||||||
|
|
@ -1641,6 +1655,16 @@ pub fn get_view_for_file(self: *Self, file_path: []const u8) ?usize {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_view_for_editor(self: *Self, editor: *ed.Editor) ?usize {
|
||||||
|
for (self.views.widgets.items, 0..) |*view, n| {
|
||||||
|
const widget = view.widget.get("editor") orelse continue;
|
||||||
|
if (widget.dynamic_cast(ed.EditorWidget)) |p|
|
||||||
|
if (&p.editor == editor)
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_file_for_view(self: *Self, view_: usize) ?[]const u8 {
|
pub fn get_file_for_view(self: *Self, view_: usize) ?[]const u8 {
|
||||||
const view = self.views.get_at(view_) orelse return null;
|
const view = self.views.get_at(view_) orelse return null;
|
||||||
const editor = view.get("editor") orelse return null;
|
const editor = view.get("editor") orelse return null;
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,24 @@ const @"style.config" = struct {
|
||||||
selected_right_fg: colors = .active_bg,
|
selected_right_fg: colors = .active_bg,
|
||||||
selected_right_bg: colors = .inactive_bg,
|
selected_right_bg: colors = .inactive_bg,
|
||||||
|
|
||||||
|
unfocused_active_fg: colors = .unfocused_active_fg,
|
||||||
|
unfocused_active_bg: colors = .unfocused_active_bg,
|
||||||
|
unfocused_active_left: []const u8 = "🭅",
|
||||||
|
unfocused_active_left_fg: colors = .unfocused_active_bg,
|
||||||
|
unfocused_active_left_bg: colors = .unfocused_inactive_bg,
|
||||||
|
unfocused_active_right: []const u8 = "🭐",
|
||||||
|
unfocused_active_right_fg: colors = .unfocused_active_bg,
|
||||||
|
unfocused_active_right_bg: colors = .unfocused_inactive_bg,
|
||||||
|
|
||||||
|
unfocused_inactive_fg: colors = .unfocused_inactive_fg,
|
||||||
|
unfocused_inactive_bg: colors = .unfocused_inactive_bg,
|
||||||
|
unfocused_inactive_left: []const u8 = " ",
|
||||||
|
unfocused_inactive_left_fg: colors = .unfocused_inactive_fg,
|
||||||
|
unfocused_inactive_left_bg: colors = .unfocused_inactive_bg,
|
||||||
|
unfocused_inactive_right: []const u8 = " ",
|
||||||
|
unfocused_inactive_right_fg: colors = .unfocused_inactive_fg,
|
||||||
|
unfocused_inactive_right_bg: colors = .unfocused_inactive_bg,
|
||||||
|
|
||||||
file_type_icon: bool = true,
|
file_type_icon: bool = true,
|
||||||
|
|
||||||
include_files: []const u8 = "",
|
include_files: []const u8 = "",
|
||||||
|
|
@ -86,7 +104,7 @@ pub const TabBar = struct {
|
||||||
widget_list_widget: Widget,
|
widget_list_widget: Widget,
|
||||||
event_handler: ?EventHandler,
|
event_handler: ?EventHandler,
|
||||||
tabs: []TabBarTab = &[_]TabBarTab{},
|
tabs: []TabBarTab = &[_]TabBarTab{},
|
||||||
active_buffer_ref: ?usize = null,
|
active_focused_buffer_ref: ?usize = null,
|
||||||
minimum_tabs_shown: usize,
|
minimum_tabs_shown: usize,
|
||||||
place_next: Placement = .atend,
|
place_next: Placement = .atend,
|
||||||
|
|
||||||
|
|
@ -164,8 +182,6 @@ pub const TabBar = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
|
|
||||||
var file_path: []const u8 = undefined;
|
|
||||||
var buffer_ref: usize = undefined;
|
var buffer_ref: usize = undefined;
|
||||||
if (try m.match(.{"next_tab"})) {
|
if (try m.match(.{"next_tab"})) {
|
||||||
self.select_next_tab();
|
self.select_next_tab();
|
||||||
|
|
@ -181,17 +197,21 @@ pub const TabBar = struct {
|
||||||
self.place_next_tab(.before, buffer_ref);
|
self.place_next_tab(.before, buffer_ref);
|
||||||
} else if (try m.match(.{ "place_next_tab", "atend" })) {
|
} else if (try m.match(.{ "place_next_tab", "atend" })) {
|
||||||
self.place_next = .atend;
|
self.place_next = .atend;
|
||||||
} else if (try m.match(.{ "E", "open", tp.extract(&file_path), tp.more })) {
|
} else if (try m.match(.{ "E", "open", tp.more })) {
|
||||||
self.active_buffer_ref = if (buffer_manager.get_buffer_for_file(file_path)) |buffer|
|
self.refresh_active_buffer();
|
||||||
buffer_manager.buffer_to_ref(buffer)
|
|
||||||
else
|
|
||||||
null;
|
|
||||||
} else if (try m.match(.{ "E", "close" })) {
|
} else if (try m.match(.{ "E", "close" })) {
|
||||||
self.active_buffer_ref = null;
|
self.refresh_active_buffer();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn refresh_active_buffer(self: *Self) void {
|
||||||
|
const mv = tui.mainview() orelse @panic("tabs no main view");
|
||||||
|
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
|
||||||
|
const buffer = mv.get_active_buffer();
|
||||||
|
self.active_focused_buffer_ref = if (buffer) |buf| buffer_manager.buffer_to_ref(buf) else null;
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_event(self: *Self, from: tp.pid_ref, m: tp.message) tp.result {
|
fn handle_event(self: *Self, from: tp.pid_ref, m: tp.message) tp.result {
|
||||||
if (self.event_handler) |event_handler| try event_handler.send(from, m);
|
if (self.event_handler) |event_handler| try event_handler.send(from, m);
|
||||||
if (try m.match(.{ "D", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.more })) {
|
if (try m.match(.{ "D", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.more })) {
|
||||||
|
|
@ -239,6 +259,7 @@ pub const TabBar = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_tab_widgets(self: *Self, drag_source: ?*Widget) !void {
|
fn update_tab_widgets(self: *Self, drag_source: ?*Widget) !void {
|
||||||
|
const mv = tui.mainview() orelse @panic("tabs no main view");
|
||||||
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");
|
||||||
var prev_widget_count: usize = 0;
|
var prev_widget_count: usize = 0;
|
||||||
for (self.widget_list.widgets.items) |*split_widgetstate| if (split_widgetstate.widget.dynamic_cast(WidgetList)) |split| {
|
for (self.widget_list.widgets.items) |*split_widgetstate| if (split_widgetstate.widget.dynamic_cast(WidgetList)) |split| {
|
||||||
|
|
@ -256,11 +277,10 @@ pub const TabBar = struct {
|
||||||
split.deinit(self.widget_list.allocator);
|
split.deinit(self.widget_list.allocator);
|
||||||
};
|
};
|
||||||
|
|
||||||
var max_view: usize = 0;
|
const views = mv.get_view_count();
|
||||||
for (self.tabs) |tab| max_view = @max(max_view, tab.view orelse 0);
|
|
||||||
|
|
||||||
var widget_count: usize = 0;
|
var widget_count: usize = 0;
|
||||||
for (0..max_view + 1) |view| {
|
for (0..views) |view| {
|
||||||
var first = true;
|
var first = true;
|
||||||
var view_widget_list = try WidgetList.createH(self.allocator, self.widget_list.plane, "split", .dynamic);
|
var view_widget_list = try WidgetList.createH(self.allocator, self.widget_list.plane, "split", .dynamic);
|
||||||
try self.widget_list.add(view_widget_list.widget());
|
try self.widget_list.add(view_widget_list.widget());
|
||||||
|
|
@ -277,8 +297,10 @@ pub const TabBar = struct {
|
||||||
try view_widget_list.add(tab.widget);
|
try view_widget_list.add(tab.widget);
|
||||||
widget_count += 1;
|
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));
|
||||||
|
btn.opts.ctx.view = buffer.get_last_view() orelse 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -384,7 +406,7 @@ pub const TabBar = struct {
|
||||||
for (split.widgets.items) |*widget_state| if (widget_state.widget.dynamic_cast(Tab.ButtonType)) |btn| {
|
for (split.widgets.items) |*widget_state| if (widget_state.widget.dynamic_cast(Tab.ButtonType)) |btn| {
|
||||||
if (found_active)
|
if (found_active)
|
||||||
return btn.opts.ctx.buffer_ref;
|
return btn.opts.ctx.buffer_ref;
|
||||||
if (btn.opts.ctx.buffer_ref == self.active_buffer_ref)
|
if (btn.opts.ctx.buffer_ref == self.active_focused_buffer_ref)
|
||||||
found_active = true;
|
found_active = true;
|
||||||
};
|
};
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -394,7 +416,7 @@ pub const TabBar = struct {
|
||||||
var previous: ?usize = null;
|
var previous: ?usize = null;
|
||||||
for (self.widget_list.widgets.items) |*split_widget| if (split_widget.widget.dynamic_cast(WidgetList)) |split|
|
for (self.widget_list.widgets.items) |*split_widget| if (split_widget.widget.dynamic_cast(WidgetList)) |split|
|
||||||
for (split.widgets.items) |*widget_state| if (widget_state.widget.dynamic_cast(Tab.ButtonType)) |btn| {
|
for (split.widgets.items) |*widget_state| if (widget_state.widget.dynamic_cast(Tab.ButtonType)) |btn| {
|
||||||
if (btn.opts.ctx.buffer_ref == self.active_buffer_ref)
|
if (btn.opts.ctx.buffer_ref == self.active_focused_buffer_ref)
|
||||||
return previous;
|
return previous;
|
||||||
previous = btn.opts.ctx.buffer_ref;
|
previous = btn.opts.ctx.buffer_ref;
|
||||||
};
|
};
|
||||||
|
|
@ -415,7 +437,7 @@ pub const TabBar = struct {
|
||||||
|
|
||||||
fn move_tab_next(self: *Self) void {
|
fn move_tab_next(self: *Self) void {
|
||||||
tp.trace(tp.channel.debug, .{"move_tab_next"});
|
tp.trace(tp.channel.debug, .{"move_tab_next"});
|
||||||
const this_idx = self.find_buffer_tab(self.active_buffer_ref orelse return) orelse return;
|
const this_idx = self.find_buffer_tab(self.active_focused_buffer_ref orelse return) orelse return;
|
||||||
const other_buffer_ref = self.find_next_tab_buffer() orelse return;
|
const other_buffer_ref = self.find_next_tab_buffer() orelse return;
|
||||||
const other_idx = self.find_buffer_tab(other_buffer_ref) orelse return;
|
const other_idx = self.find_buffer_tab(other_buffer_ref) orelse return;
|
||||||
self.move_tab_to(other_idx, this_idx);
|
self.move_tab_to(other_idx, this_idx);
|
||||||
|
|
@ -423,7 +445,7 @@ pub const TabBar = struct {
|
||||||
|
|
||||||
fn move_tab_previous(self: *Self) void {
|
fn move_tab_previous(self: *Self) void {
|
||||||
tp.trace(tp.channel.debug, .{"move_tab_previous"});
|
tp.trace(tp.channel.debug, .{"move_tab_previous"});
|
||||||
const this_idx = self.find_buffer_tab(self.active_buffer_ref orelse return) orelse return;
|
const this_idx = self.find_buffer_tab(self.active_focused_buffer_ref orelse return) orelse return;
|
||||||
const other_buffer_ref = self.find_previous_tab_buffer() orelse return;
|
const other_buffer_ref = self.find_previous_tab_buffer() orelse return;
|
||||||
const other_idx = self.find_buffer_tab(other_buffer_ref) orelse return;
|
const other_idx = self.find_buffer_tab(other_buffer_ref) orelse return;
|
||||||
self.move_tab_to(other_idx, this_idx);
|
self.move_tab_to(other_idx, this_idx);
|
||||||
|
|
@ -442,16 +464,17 @@ pub const TabBar = struct {
|
||||||
|
|
||||||
var src_tab = tabs.orderedRemove(src_idx);
|
var src_tab = tabs.orderedRemove(src_idx);
|
||||||
src_tab.view = new_view;
|
src_tab.view = new_view;
|
||||||
const active = src_tab.buffer_ref == self.active_buffer_ref;
|
const buffer = buffer_manager.buffer_from_ref(src_tab.buffer_ref);
|
||||||
|
const active = if (buffer) |buf| if (mv.get_editor_for_buffer(buf)) |_| true else false else false;
|
||||||
|
|
||||||
tabs.insert(self.allocator, dst_idx, src_tab) catch @panic("OOM move_tab_to");
|
tabs.insert(self.allocator, dst_idx, src_tab) catch @panic("OOM move_tab_to");
|
||||||
|
|
||||||
if (new_view != old_view) blk: {
|
if (new_view != old_view) if (buffer) |buf| {
|
||||||
const buffer = buffer_manager.buffer_from_ref(src_tab.buffer_ref) orelse break :blk;
|
buf.set_last_view(new_view);
|
||||||
buffer.set_last_view(new_view);
|
if (mv.get_editor_for_buffer(buf)) |editor|
|
||||||
if (mv.get_editor_for_buffer(buffer)) |editor|
|
|
||||||
editor.close_editor() catch {};
|
editor.close_editor() catch {};
|
||||||
}
|
};
|
||||||
|
|
||||||
const drag_source, _ = tui.get_drag_source();
|
const drag_source, _ = tui.get_drag_source();
|
||||||
self.update_tab_widgets(drag_source) catch {};
|
self.update_tab_widgets(drag_source) catch {};
|
||||||
if (active)
|
if (active)
|
||||||
|
|
@ -529,6 +552,7 @@ pub const TabBar = struct {
|
||||||
const Tab = struct {
|
const Tab = struct {
|
||||||
tabbar: *TabBar,
|
tabbar: *TabBar,
|
||||||
buffer_ref: usize,
|
buffer_ref: usize,
|
||||||
|
view: usize,
|
||||||
tab_style: *const Style,
|
tab_style: *const Style,
|
||||||
close_pos: ?i32 = null,
|
close_pos: ?i32 = null,
|
||||||
save_pos: ?i32 = null,
|
save_pos: ?i32 = null,
|
||||||
|
|
@ -546,7 +570,7 @@ const Tab = struct {
|
||||||
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 buffer = buffer_manager.buffer_from_ref(buffer_ref);
|
const buffer = buffer_manager.buffer_from_ref(buffer_ref);
|
||||||
return Button.create_widget(Tab, tabbar.allocator, tabbar.widget_list.plane, .{
|
return Button.create_widget(Tab, tabbar.allocator, tabbar.widget_list.plane, .{
|
||||||
.ctx = .{ .tabbar = tabbar, .buffer_ref = buffer_ref, .tab_style = tab_style },
|
.ctx = .{ .tabbar = tabbar, .buffer_ref = buffer_ref, .view = if (buffer) |buf| buf.get_last_view() orelse 0 else 0, .tab_style = tab_style },
|
||||||
.label = if (buffer) |buf| name_from_buffer(buf) else "???",
|
.label = if (buffer) |buf| name_from_buffer(buf) else "???",
|
||||||
.on_click = Tab.on_click,
|
.on_click = Tab.on_click,
|
||||||
.on_click2 = Tab.on_click2,
|
.on_click2 = Tab.on_click2,
|
||||||
|
|
@ -577,8 +601,19 @@ const Tab = struct {
|
||||||
tp.self_pid().send(.{ "cmd", "close_buffer", .{buffer.get_file_path()} }) catch {};
|
tp.self_pid().send(.{ "cmd", "close_buffer", .{buffer.get_file_path()} }) catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_active(self: *@This()) bool {
|
||||||
|
const mv = tui.mainview() orelse @panic("tabs no main view");
|
||||||
|
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
|
||||||
|
const buffer = buffer_manager.buffer_from_ref(self.buffer_ref) orelse return false;
|
||||||
|
return if (mv.get_editor_for_buffer(buffer)) |_| true else false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_focused(self: *@This()) bool {
|
||||||
|
const mv = tui.mainview() orelse @panic("tabs no main view");
|
||||||
|
return self.view == mv.get_active_view();
|
||||||
|
}
|
||||||
|
|
||||||
fn render(self: *@This(), btn: *ButtonType, theme: *const Widget.Theme) bool {
|
fn render(self: *@This(), btn: *ButtonType, theme: *const Widget.Theme) bool {
|
||||||
const active = self.tabbar.active_buffer_ref == self.buffer_ref;
|
|
||||||
if (btn.drag_pos) |pos| {
|
if (btn.drag_pos) |pos| {
|
||||||
self.render_dragging(&btn.plane, theme);
|
self.render_dragging(&btn.plane, theme);
|
||||||
const anchor: Widget.Pos = btn.drag_anchor orelse .{};
|
const anchor: Widget.Pos = btn.drag_anchor orelse .{};
|
||||||
|
|
@ -586,14 +621,21 @@ const Tab = struct {
|
||||||
box.y = @intCast(@max(pos.y, anchor.y) - anchor.y);
|
box.y = @intCast(@max(pos.y, anchor.y) - anchor.y);
|
||||||
box.x = @intCast(@max(pos.x, anchor.x) - anchor.x);
|
box.x = @intCast(@max(pos.x, anchor.x) - anchor.x);
|
||||||
if (tui.top_layer(box.to_layer())) |top_layer| {
|
if (tui.top_layer(box.to_layer())) |top_layer| {
|
||||||
self.render_selected(top_layer, btn.opts.label, false, theme, active);
|
self.render_selected(top_layer, btn.opts.label, false, theme, self.is_active());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
const active = self.is_active();
|
||||||
const mode: Mode = if (btn.hover) .selected else if (active) .active else .inactive;
|
const mode: Mode = if (btn.hover) .selected else if (active) .active else .inactive;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
.selected => self.render_selected(&btn.plane, btn.opts.label, btn.hover, theme, active),
|
.selected => self.render_selected(&btn.plane, btn.opts.label, btn.hover, theme, active),
|
||||||
.active => self.render_active(&btn.plane, btn.opts.label, btn.hover, theme),
|
.active => if (self.is_focused())
|
||||||
.inactive => self.render_inactive(&btn.plane, btn.opts.label, btn.hover, theme),
|
self.render_active(&btn.plane, btn.opts.label, btn.hover, theme)
|
||||||
|
else
|
||||||
|
self.render_unfocused_active(&btn.plane, btn.opts.label, btn.hover, theme),
|
||||||
|
.inactive => if (self.is_focused())
|
||||||
|
self.render_inactive(&btn.plane, btn.opts.label, btn.hover, theme)
|
||||||
|
else
|
||||||
|
self.render_unfocused_inactive(&btn.plane, btn.opts.label, btn.hover, theme),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -715,6 +757,72 @@ const Tab = struct {
|
||||||
plane.home();
|
plane.home();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_unfocused_active(self: *@This(), plane: *Plane, label: []const u8, hover: bool, theme: *const Widget.Theme) void {
|
||||||
|
plane.set_base_style(theme.editor);
|
||||||
|
plane.erase();
|
||||||
|
plane.home();
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.inactive_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.inactive_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
plane.fill(" ");
|
||||||
|
plane.home();
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.active_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.active_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
plane.fill(" ");
|
||||||
|
plane.home();
|
||||||
|
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.active_left_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.active_left_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
_ = plane.putstr(self.tab_style.unfocused_active_left) catch {};
|
||||||
|
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.unfocused_active_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.active_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
self.render_content(plane, label, hover, self.tab_style.unfocused_active_fg.from_theme(theme), theme);
|
||||||
|
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.active_right_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.active_right_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
_ = plane.putstr(self.tab_style.unfocused_active_right) catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_unfocused_inactive(self: *@This(), plane: *Plane, label: []const u8, hover: bool, theme: *const Widget.Theme) void {
|
||||||
|
plane.set_base_style(theme.editor);
|
||||||
|
plane.erase();
|
||||||
|
plane.home();
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.inactive_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.inactive_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
plane.fill(" ");
|
||||||
|
plane.home();
|
||||||
|
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.inactive_left_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.inactive_left_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
_ = plane.putstr(self.tab_style.unfocused_inactive_left) catch {};
|
||||||
|
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.inactive_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.inactive_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
self.render_content(plane, label, hover, self.tab_style.unfocused_inactive_fg.from_theme(theme), theme);
|
||||||
|
|
||||||
|
plane.set_style(.{
|
||||||
|
.fg = self.tab_style.inactive_right_fg.from_theme(theme),
|
||||||
|
.bg = self.tab_style.inactive_right_bg.from_theme(theme),
|
||||||
|
});
|
||||||
|
_ = plane.putstr(self.tab_style.unfocused_inactive_right) catch {};
|
||||||
|
}
|
||||||
|
|
||||||
fn render_content(self: *@This(), plane: *Plane, label: []const u8, hover: bool, fg: ?Widget.Theme.Color, theme: *const Widget.Theme) void {
|
fn render_content(self: *@This(), plane: *Plane, label: []const u8, hover: bool, fg: ?Widget.Theme.Color, theme: *const Widget.Theme) 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 buffer_ = buffer_manager.buffer_from_ref(self.buffer_ref);
|
const buffer_ = buffer_manager.buffer_from_ref(self.buffer_ref);
|
||||||
|
|
@ -769,7 +877,7 @@ const Tab = struct {
|
||||||
fn layout(self: *@This(), btn: *ButtonType) Widget.Layout {
|
fn layout(self: *@This(), btn: *ButtonType) Widget.Layout {
|
||||||
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 is_dirty = if (buffer_manager.buffer_from_ref(self.buffer_ref)) |buffer| buffer.is_dirty() else false;
|
const is_dirty = if (buffer_manager.buffer_from_ref(self.buffer_ref)) |buffer| buffer.is_dirty() else false;
|
||||||
const active = self.tabbar.active_buffer_ref == self.buffer_ref;
|
const active = self.is_active();
|
||||||
const len = btn.plane.egc_chunk_width(btn.opts.label, 0, 1);
|
const len = btn.plane.egc_chunk_width(btn.opts.label, 0, 1);
|
||||||
const len_padding = padding_len(btn.plane, self.tabbar.tab_style, active, is_dirty);
|
const len_padding = padding_len(btn.plane, self.tabbar.tab_style, active, is_dirty);
|
||||||
return .{ .static = len + len_padding };
|
return .{ .static = len + len_padding };
|
||||||
|
|
@ -808,11 +916,6 @@ const Tab = struct {
|
||||||
try cbor.writeValue(writer, self.meta);
|
try cbor.writeValue(writer, self.meta);
|
||||||
try cbor.writeValue(writer, self.file_type_name);
|
try cbor.writeValue(writer, self.file_type_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_state(self: *@This(), iter: *[]const u8) !void {
|
|
||||||
_ = self;
|
|
||||||
_ = iter;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const spacer = struct {
|
const spacer = struct {
|
||||||
|
|
@ -888,6 +991,10 @@ const colors = enum {
|
||||||
inactive_fg,
|
inactive_fg,
|
||||||
selected_bg,
|
selected_bg,
|
||||||
selected_fg,
|
selected_fg,
|
||||||
|
unfocused_active_bg,
|
||||||
|
unfocused_active_fg,
|
||||||
|
unfocused_inactive_bg,
|
||||||
|
unfocused_inactive_fg,
|
||||||
|
|
||||||
Error,
|
Error,
|
||||||
Warning,
|
Warning,
|
||||||
|
|
@ -904,6 +1011,10 @@ const colors = enum {
|
||||||
.inactive_fg => theme.tab_inactive.fg,
|
.inactive_fg => theme.tab_inactive.fg,
|
||||||
.selected_bg => theme.tab_selected.bg,
|
.selected_bg => theme.tab_selected.bg,
|
||||||
.selected_fg => theme.tab_selected.fg,
|
.selected_fg => theme.tab_selected.fg,
|
||||||
|
.unfocused_active_bg => theme.tab_unfocused_active.bg,
|
||||||
|
.unfocused_active_fg => theme.tab_unfocused_active.fg,
|
||||||
|
.unfocused_inactive_bg => theme.tab_unfocused_inactive.bg,
|
||||||
|
.unfocused_inactive_fg => theme.tab_unfocused_inactive.fg,
|
||||||
.Error => theme.editor_error.fg,
|
.Error => theme.editor_error.fg,
|
||||||
.Warning => theme.editor_warning.fg,
|
.Warning => theme.editor_warning.fg,
|
||||||
.Information => theme.editor_information.fg,
|
.Information => theme.editor_information.fg,
|
||||||
|
|
|
||||||
|
|
@ -2096,13 +2096,12 @@ pub fn render_pointer_vcs(self: *renderer.Plane, vcs_status: u8, selected: bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_file_item(
|
fn render_file_item(
|
||||||
self: *renderer.Plane,
|
self: *renderer.Plane,
|
||||||
file_path_: []const u8,
|
file_path_: []const u8,
|
||||||
icon: []const u8,
|
icon: []const u8,
|
||||||
color: u24,
|
color: u24,
|
||||||
indicator: []const u8,
|
indicator: []const u8,
|
||||||
indicator_suffix: []const u8,
|
|
||||||
matches_cbor: []const u8,
|
matches_cbor: []const u8,
|
||||||
active: bool,
|
active: bool,
|
||||||
selected: bool,
|
selected: bool,
|
||||||
|
|
@ -2130,7 +2129,7 @@ pub fn render_file_item(
|
||||||
_ = self.print("{s} ", .{file_path_}) catch {};
|
_ = self.print("{s} ", .{file_path_}) catch {};
|
||||||
|
|
||||||
self.set_style(style_hint);
|
self.set_style(style_hint);
|
||||||
_ = self.print_aligned_right(0, "{s}{s} ", .{ indicator, indicator_suffix }) catch {};
|
_ = self.print_aligned_right(0, "{s} ", .{indicator}) catch {};
|
||||||
|
|
||||||
var iter = matches_cbor;
|
var iter = matches_cbor;
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
|
|
@ -2157,7 +2156,7 @@ pub fn render_file_item_cbor(self: *renderer.Plane, file_item_cbor: []const u8,
|
||||||
if (!(cbor.matchString(&iter, &indicator) catch false)) indicator = "";
|
if (!(cbor.matchString(&iter, &indicator) catch false)) indicator = "";
|
||||||
|
|
||||||
if (!(cbor.matchValue(&iter, cbor.extract_cbor(&matches_cbor)) catch false)) @panic("invalid matches cbor");
|
if (!(cbor.matchValue(&iter, cbor.extract_cbor(&matches_cbor)) catch false)) @panic("invalid matches cbor");
|
||||||
return render_file_item(self, file_path_, icon, color, indicator, &.{}, matches_cbor, active, selected, hover, theme_);
|
return render_file_item(self, file_path_, icon, color, indicator, matches_cbor, active, selected, hover, theme_);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_file_vcs_item(
|
pub fn render_file_vcs_item(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue