refactor: make tab bar split aware
This commit is contained in:
parent
120a9f0bf5
commit
ff38c37df7
1 changed files with 80 additions and 33 deletions
|
|
@ -104,6 +104,7 @@ 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 {
|
||||||
|
|
@ -138,9 +139,14 @@ pub const TabBar = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(self: *Self) void {
|
pub fn update(self: *Self) void {
|
||||||
self.update_tabs() catch {};
|
const drag_source, const drag_btn = tui.get_drag_source();
|
||||||
|
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 {
|
||||||
|
|
@ -200,14 +206,9 @@ pub const TabBar = struct {
|
||||||
if (btn.hover) break idx;
|
if (btn.hover) break idx;
|
||||||
} else return;
|
} else return;
|
||||||
if (dragging != hover_) {
|
if (dragging != hover_) {
|
||||||
const tmp = self.tabs[dragging];
|
self.swap_tabs_by_index(dragging, hover_);
|
||||||
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, 0);
|
|
||||||
tui.refresh_hover(@src());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -229,25 +230,51 @@ pub const TabBar = struct {
|
||||||
return self.widget_list_widget.hover();
|
return self.widget_list_widget.hover();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_tabs(self: *Self) !void {
|
fn update_tabs(self: *Self, drag_source: ?*Widget) !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");
|
||||||
try self.update_tab_buffers();
|
try self.update_tab_buffers();
|
||||||
const prev_widget_count = self.widget_list.widgets.items.len;
|
var prev_widget_count: usize = 0;
|
||||||
while (self.widget_list.pop()) |widget| if (widget.dynamic_cast(Tab.ButtonType) == null)
|
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 self.widget_list.add(try self.make_spacer());
|
try view_widget_list.add(try self.make_spacer(view_widget_list.plane));
|
||||||
|
widget_count += 1;
|
||||||
}
|
}
|
||||||
try self.widget_list.add(tab.widget);
|
try view_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 != self.widget_list.widgets.items.len)
|
||||||
tui.refresh_hover(@src());
|
tui.refresh_hover(@src());
|
||||||
}
|
}
|
||||||
|
|
@ -295,14 +322,14 @@ pub const TabBar = struct {
|
||||||
else
|
else
|
||||||
try result.addOne(self.allocator),
|
try result.addOne(self.allocator),
|
||||||
};
|
};
|
||||||
pos.* = .{ .buffer_ref = buffer_ref, .widget = tab };
|
pos.* = .{ .buffer_ref = buffer_ref, .widget = tab, .view = buffer.get_last_view() };
|
||||||
self.place_next = .atend;
|
self.place_next = .atend;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_spacer(self: @This()) !Widget {
|
fn make_spacer(self: @This(), parent: Plane) !Widget {
|
||||||
return spacer.create(
|
return spacer.create(
|
||||||
self.allocator,
|
self.allocator,
|
||||||
self.widget_list.plane,
|
parent,
|
||||||
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,
|
||||||
|
|
@ -371,9 +398,23 @@ 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 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,21 +458,27 @@ 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 (name_to_ref(name)) |buffer_ref| {
|
if (buffer_name) |name| {
|
||||||
|
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(buffer_name: []const u8) ?usize {
|
fn name_to_ref_and_view(buffer_name: []const u8) struct { ?usize, ?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| buffer_manager.buffer_to_ref(buffer) else null;
|
return if (buffer_manager.get_buffer_for_file(buffer_name)) |buffer|
|
||||||
|
.{ buffer_manager.buffer_to_ref(buffer), buffer.get_last_view() }
|
||||||
|
else
|
||||||
|
.{ null, null };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue