Compare commits
3 commits
a532665afb
...
8dcbed86aa
| Author | SHA1 | Date | |
|---|---|---|---|
| 8dcbed86aa | |||
| d891af6553 | |||
| dac695f010 |
3 changed files with 94 additions and 2 deletions
|
|
@ -549,6 +549,12 @@ pub fn request_windows_clipboard(allocator: std.mem.Allocator) ![]u8 {
|
||||||
return allocator.dupe(u8, text);
|
return allocator.dupe(u8, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const MouseCursorShape = vaxis.Mouse.Shape;
|
||||||
|
|
||||||
|
pub fn request_mouse_cursor(self: *Self, shape: MouseCursorShape, push_or_pop: bool) void {
|
||||||
|
if (push_or_pop) self.vx.setMouseShape(shape) else self.vx.setMouseShape(.default);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn request_mouse_cursor_text(self: *Self, push_or_pop: bool) void {
|
pub fn request_mouse_cursor_text(self: *Self, push_or_pop: bool) void {
|
||||||
if (push_or_pop) self.vx.setMouseShape(.text) else self.vx.setMouseShape(.default);
|
if (push_or_pop) self.vx.setMouseShape(.text) else self.vx.setMouseShape(.default);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ pub fn Options(context: type) type {
|
||||||
label: []const u8 = "button",
|
label: []const u8 = "button",
|
||||||
pos: Widget.Box = .{ .y = 0, .x = 0, .w = 8, .h = 1 },
|
pos: Widget.Box = .{ .y = 0, .x = 0, .w = 8, .h = 1 },
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
|
cursor: tui.renderer.MouseCursorShape = .pointer,
|
||||||
|
|
||||||
on_click: ClickHandler = do_nothing,
|
on_click: ClickHandler = do_nothing,
|
||||||
on_click2: ClickHandler = do_nothing,
|
on_click2: ClickHandler = do_nothing,
|
||||||
|
|
@ -156,7 +157,7 @@ fn State(ctx_type: type) type {
|
||||||
tui.need_render(@src());
|
tui.need_render(@src());
|
||||||
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(self.opts.cursor, self.hover);
|
||||||
tui.need_render(@src());
|
tui.need_render(@src());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ pub const TabBar = struct {
|
||||||
const hover_ = for (self.tabs, 0..) |*tab, idx| {
|
const hover_ = for (self.tabs, 0..) |*tab, idx| {
|
||||||
if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn|
|
if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn|
|
||||||
if (btn.hover) break idx;
|
if (btn.hover) break idx;
|
||||||
} else return;
|
} else return self.handle_event_drop_target(dragging);
|
||||||
if (dragging != hover_) {
|
if (dragging != hover_) {
|
||||||
self.move_tab_to(hover_, dragging);
|
self.move_tab_to(hover_, dragging);
|
||||||
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;
|
||||||
|
|
@ -231,6 +231,22 @@ pub const TabBar = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_event_drop_target(self: *Self, dragging: usize) tp.result {
|
||||||
|
var hover_view: ?usize = null;
|
||||||
|
for (self.widget_list.widgets.items, 0..) |*split_widgetstate, idx|
|
||||||
|
if (split_widgetstate.widget.dynamic_cast(WidgetList)) |split| {
|
||||||
|
for (split.widgets.items) |*widgetstate|
|
||||||
|
if (widgetstate.widget.dynamic_cast(drop_target.ButtonType)) |btn| {
|
||||||
|
if (btn.hover)
|
||||||
|
hover_view = idx;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (hover_view) |view| {
|
||||||
|
self.move_tab_to_view(view, dragging);
|
||||||
|
self.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_resize(self: *Self, pos: Widget.Box) void {
|
pub fn handle_resize(self: *Self, pos: Widget.Box) void {
|
||||||
self.widget_list_widget.resize(pos);
|
self.widget_list_widget.resize(pos);
|
||||||
self.plane = self.widget_list.plane;
|
self.plane = self.widget_list.plane;
|
||||||
|
|
@ -303,6 +319,7 @@ pub const TabBar = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try view_widget_list.add(try self.make_drop_target(view));
|
||||||
}
|
}
|
||||||
if (prev_widget_count != widget_count)
|
if (prev_widget_count != widget_count)
|
||||||
tui.refresh_hover(@src());
|
tui.refresh_hover(@src());
|
||||||
|
|
@ -377,6 +394,10 @@ pub const TabBar = struct {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_drop_target(self: *@This(), view: usize) !Widget {
|
||||||
|
return drop_target.create(self, view);
|
||||||
|
}
|
||||||
|
|
||||||
fn find_buffer_tab(self: *Self, buffer_ref: usize) ?usize {
|
fn find_buffer_tab(self: *Self, buffer_ref: usize) ?usize {
|
||||||
for (self.tabs, 0..) |*tab, idx|
|
for (self.tabs, 0..) |*tab, idx|
|
||||||
if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn|
|
if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn|
|
||||||
|
|
@ -481,6 +502,37 @@ pub const TabBar = struct {
|
||||||
navigate_to_buffer(src_tab.buffer_ref);
|
navigate_to_buffer(src_tab.buffer_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn move_tab_to_view(self: *Self, new_view: usize, src_idx: usize) void {
|
||||||
|
const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager");
|
||||||
|
const mv = tui.mainview() orelse return;
|
||||||
|
|
||||||
|
var tabs: std.ArrayListUnmanaged(TabBarTab) = .fromOwnedSlice(self.tabs);
|
||||||
|
defer self.tabs = tabs.toOwnedSlice(self.allocator) catch @panic("OOM move_tab_to_view");
|
||||||
|
|
||||||
|
const old_view = tabs.items[src_idx].view;
|
||||||
|
|
||||||
|
if (new_view == old_view) return;
|
||||||
|
var src_tab = &tabs.items[src_idx];
|
||||||
|
src_tab.view = new_view;
|
||||||
|
const src_buffer_ref = src_tab.buffer_ref;
|
||||||
|
|
||||||
|
tabs.append(self.allocator, tabs.orderedRemove(src_idx)) catch @panic("OOM move_tab_to_view");
|
||||||
|
|
||||||
|
const buffer = buffer_manager.buffer_from_ref(src_buffer_ref);
|
||||||
|
const active = if (buffer) |buf| if (mv.get_editor_for_buffer(buf)) |_| true else false else false;
|
||||||
|
|
||||||
|
if (buffer) |buf| {
|
||||||
|
buf.set_last_view(new_view);
|
||||||
|
if (mv.get_editor_for_buffer(buf)) |editor|
|
||||||
|
editor.close_editor() catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const drag_source, _ = tui.get_drag_source();
|
||||||
|
self.update_tab_widgets(drag_source) catch {};
|
||||||
|
if (active)
|
||||||
|
navigate_to_buffer(src_tab.buffer_ref);
|
||||||
|
}
|
||||||
|
|
||||||
fn place_next_tab(self: *Self, position: enum { before, after }, buffer_ref: usize) void {
|
fn place_next_tab(self: *Self, position: enum { before, after }, buffer_ref: usize) void {
|
||||||
tp.trace(tp.channel.debug, .{ "place_next_tab", position, buffer_ref });
|
tp.trace(tp.channel.debug, .{ "place_next_tab", position, buffer_ref });
|
||||||
const tab_idx = for (self.tabs, 0..) |*tab, idx| if (tab.buffer_ref == buffer_ref) break idx else continue else {
|
const tab_idx = for (self.tabs, 0..) |*tab, idx| if (tab.buffer_ref == buffer_ref) break idx else continue else {
|
||||||
|
|
@ -918,6 +970,39 @@ const Tab = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const drop_target = struct {
|
||||||
|
tabbar: *TabBar,
|
||||||
|
view: usize,
|
||||||
|
on_event: ?EventHandler = null,
|
||||||
|
|
||||||
|
const ButtonType = Button.Options(@This()).ButtonType;
|
||||||
|
|
||||||
|
fn create(
|
||||||
|
tabbar: *TabBar,
|
||||||
|
view: usize,
|
||||||
|
) !Widget {
|
||||||
|
return Button.create_widget(@This(), tabbar.allocator, tabbar.widget_list.plane, .{
|
||||||
|
.ctx = .{ .tabbar = tabbar, .view = view },
|
||||||
|
.label = &.{},
|
||||||
|
.on_layout = @This().layout,
|
||||||
|
.on_render = @This().render,
|
||||||
|
.on_event = EventHandler.bind(tabbar, TabBar.handle_event),
|
||||||
|
.cursor = .default,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(self: *@This(), btn: *ButtonType, theme: *const Widget.Theme) bool {
|
||||||
|
_ = self;
|
||||||
|
_ = btn;
|
||||||
|
_ = theme;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout(_: *@This(), _: *ButtonType) Widget.Layout {
|
||||||
|
return .dynamic;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const spacer = struct {
|
const spacer = struct {
|
||||||
plane: Plane,
|
plane: Plane,
|
||||||
layout_: Widget.Layout,
|
layout_: Widget.Layout,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue