diff --git a/src/renderer/vaxis/Layer.zig b/src/renderer/vaxis/Layer.zig deleted file mode 100644 index f43d827..0000000 --- a/src/renderer/vaxis/Layer.zig +++ /dev/null @@ -1,117 +0,0 @@ -const std = @import("std"); -const vaxis = @import("vaxis"); - -pub const Plane = @import("Plane.zig"); - -const Layer = @This(); - -view: View, -y_off: i32 = 0, -x_off: i32 = 0, -plane_: Plane, - -const View = struct { - allocator: std.mem.Allocator, - screen: vaxis.Screen, - unicode: *const vaxis.Unicode, - - pub const Config = struct { - h: u16, - w: u16, - }; - - pub fn init(allocator: std.mem.Allocator, unicode: *const vaxis.Unicode, config: Config) std.mem.Allocator.Error!View { - return .{ - .allocator = allocator, - .screen = try vaxis.Screen.init(allocator, .{ - .rows = config.h, - .cols = config.w, - .x_pixel = 0, - .y_pixel = 0, - }), - .unicode = unicode, - }; - } - - pub fn deinit(self: *View) void { - self.screen.deinit(self.allocator); - } -}; - -pub const Options = struct { - y: i32 = 0, - x: i32 = 0, - h: u16 = 0, - w: u16 = 0, -}; - -pub fn init(allocator: std.mem.Allocator, unicode: *const vaxis.Unicode, opts: Options) std.mem.Allocator.Error!*Layer { - const self = try allocator.create(Layer); - self.* = .{ - .view = try View.init(allocator, unicode, .{ - .h = opts.h, - .w = opts.w, - }), - .y_off = opts.y, - .x_off = opts.x, - .plane_ = undefined, - }; - const name = "layer"; - self.plane_ = .{ - .window = self.window(), - .name_buf = undefined, - .name_len = name.len, - }; - @memcpy(self.plane_.name_buf[0..name.len], name); - return self; -} - -pub fn deinit(self: *Layer) void { - const allocator = self.view.allocator; - self.view.deinit(); - allocator.destroy(self); -} - -fn window(self: *Layer) vaxis.Window { - return .{ - .x_off = 0, - .y_off = 0, - .parent_x_off = 0, - .parent_y_off = 0, - .width = self.view.screen.width, - .height = self.view.screen.height, - .screen = &self.view.screen, - .unicode = self.view.unicode, - }; -} - -pub fn plane(self: *Layer) *Plane { - return &self.plane_; -} - -pub fn draw(self: *const Layer, plane_: Plane) void { - if (self.x_off >= plane_.window.width) return; - if (self.y_off >= plane_.window.height) return; - - const src_y = 0; - const src_x = 0; - const src_h: usize = self.view.screen.height; - const src_w = self.view.screen.width; - - const dst_dim_y: i32 = @intCast(plane_.dim_y()); - const dst_dim_x: i32 = @intCast(plane_.dim_x()); - const dst_y = self.y_off; - const dst_x = self.x_off; - const dst_w = @min(src_w, dst_dim_x - dst_x); - - for (src_y..src_h) |src_row_| { - const src_row: i32 = @intCast(src_row_); - const src_row_offset = src_row * src_w; - const dst_row_offset = (dst_y + src_row) * plane_.window.screen.width; - if (dst_y + src_row > dst_dim_y) return; - @memcpy( - plane_.window.screen.buf[@intCast(dst_row_offset + dst_x)..@intCast(dst_row_offset + dst_x + dst_w)], - self.view.screen.buf[@intCast(src_row_offset + src_x)..@intCast(src_row_offset + dst_w)], - ); - } -} diff --git a/src/renderer/vaxis/renderer.zig b/src/renderer/vaxis/renderer.zig index b71767c..7ecf83d 100644 --- a/src/renderer/vaxis/renderer.zig +++ b/src/renderer/vaxis/renderer.zig @@ -9,7 +9,6 @@ const builtin = @import("builtin"); const RGB = @import("color").RGB; pub const Plane = @import("Plane.zig"); -pub const Layer = @import("Layer.zig"); pub const Cell = @import("Cell.zig"); pub const CursorShape = vaxis.Cell.CursorShape; diff --git a/src/tui/Box.zig b/src/tui/Box.zig index c11b441..cb31862 100644 --- a/src/tui/Box.zig +++ b/src/tui/Box.zig @@ -1,5 +1,4 @@ const Plane = @import("renderer").Plane; -const Layer = @import("renderer").Layer; const Self = @This(); @@ -36,15 +35,6 @@ pub fn from(n: Plane) Self { }; } -pub fn to_layer(self: Self) Layer.Options { - return .{ - .y = @intCast(self.y), - .x = @intCast(self.x), - .h = @intCast(self.h), - .w = @intCast(self.w), - }; -} - pub fn is_abs_coord_inside(self: Self, y: usize, x: usize) bool { return y >= self.y and y < self.y + self.h and x >= self.x and x < self.x + self.w; } diff --git a/src/tui/Button.zig b/src/tui/Button.zig index 0fc77be..04356d7 100644 --- a/src/tui/Button.zig +++ b/src/tui/Button.zig @@ -77,8 +77,6 @@ fn State(ctx_type: type) type { plane: Plane, active: bool = false, hover: bool = false, - drag_anchor: ?Widget.Pos = null, - drag_pos: ?Widget.Pos = null, opts: Options(ctx_type), const Self = @This(); @@ -122,7 +120,6 @@ fn State(ctx_type: type) type { switch (btn_enum) { input.mouse.BUTTON1 => { self.active = true; - self.drag_anchor = self.to_rel_cursor(x, y); tui.need_render(); }, input.mouse.BUTTON4, input.mouse.BUTTON5 => { @@ -134,12 +131,9 @@ fn State(ctx_type: type) type { return true; } else if (try m.match(.{ "B", input.event.release, tp.extract(&btn), tp.any, tp.extract(&x), tp.extract(&y), tp.any, tp.any })) { self.call_click_handler(@enumFromInt(btn), self.to_rel_cursor(x, y)); - self.drag_anchor = null; - self.drag_pos = null; tui.need_render(); 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 })) { - self.drag_pos = .{ .x = x, .y = y }; + } else if (try m.match(.{ "D", input.event.press, tp.extract(&btn), tp.more })) { if (self.opts.on_event) |h| { self.active = false; h.send(from, m) catch {}; @@ -151,8 +145,6 @@ fn State(ctx_type: type) type { h.send(from, m) catch {}; } self.call_click_handler(@enumFromInt(btn), self.to_rel_cursor(x, y)); - self.drag_anchor = null; - self.drag_pos = null; tui.need_render(); return true; } else if (try m.match(.{ "H", tp.extract(&self.hover) })) { @@ -160,8 +152,6 @@ fn State(ctx_type: type) type { tui.need_render(); return true; } - self.drag_anchor = null; - self.drag_pos = null; return self.opts.on_receive(&self.opts.ctx, self, from, m); } diff --git a/src/tui/status/tabs.zig b/src/tui/status/tabs.zig index ab15adc..b9699c0 100644 --- a/src/tui/status/tabs.zig +++ b/src/tui/status/tabs.zig @@ -6,7 +6,6 @@ const root = @import("soft_root").root; const EventHandler = @import("EventHandler"); const Plane = @import("renderer").Plane; const Buffer = @import("Buffer"); -const input = @import("input"); const tui = @import("../tui.zig"); const Widget = @import("../Widget.zig"); @@ -188,30 +187,6 @@ pub const TabBar = struct { return false; } - 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 (try m.match(.{ "D", input.event.press, @intFromEnum(input.mouse.BUTTON1), tp.more })) { - const dragging = for (self.tabs, 0..) |*tab, idx| { - if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn| - if (btn.drag_pos) |_| break idx; - } else return; - const hover_ = for (self.tabs, 0..) |*tab, idx| { - if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn| - if (btn.hover) break idx; - } else return; - if (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; - self.update(); - for (self.widget_list.widgets.items) |*widgetstate| if (widgetstate.widget.dynamic_cast(Tab.ButtonType)) |btn| if (btn.drag_pos) |_| - tui.set_drag_source(&widgetstate.widget); - tui.refresh_hover(); - } - } - } - pub fn handle_resize(self: *Self, pos: Widget.Box) void { self.widget_list_widget.resize(pos); self.plane = self.widget_list.plane; @@ -283,7 +258,7 @@ pub const TabBar = struct { fn place_new_tab(self: *Self, result: *std.ArrayListUnmanaged(TabBarTab), buffer: *Buffer) !void { const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager"); const buffer_ref = buffer_manager.buffer_to_ref(buffer); - const tab = try Tab.create(self, buffer_ref, &self.tab_style); + const tab = try Tab.create(self, buffer_ref, &self.tab_style, self.event_handler); const pos = switch (self.place_next) { .atend => try result.addOne(self.allocator), .before => |i| if (i < result.items.len) @@ -420,7 +395,7 @@ pub const TabBar = struct { if (buffer_name) |name| if (name_to_ref(name)) |buffer_ref| { (try result.addOne(self.allocator)).* = .{ .buffer_ref = buffer_ref, - .widget = try Tab.create(self, buffer_ref, &self.tab_style), + .widget = try Tab.create(self, buffer_ref, &self.tab_style, self.event_handler), }; }; } @@ -441,7 +416,6 @@ const Tab = struct { tab_style: *const Style, close_pos: ?c_uint = null, save_pos: ?c_uint = null, - on_event: ?EventHandler = null, const Mode = enum { active, inactive, selected }; @@ -451,6 +425,7 @@ const Tab = struct { tabbar: *TabBar, buffer_ref: usize, tab_style: *const Style, + event_handler: ?EventHandler, ) !Widget { const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager"); const buffer = buffer_manager.buffer_from_ref(buffer_ref); @@ -461,7 +436,7 @@ const Tab = struct { .on_click2 = Tab.on_click2, .on_layout = Tab.layout, .on_render = Tab.render, - .on_event = EventHandler.bind(tabbar, TabBar.handle_event), + .on_event = event_handler, }); } @@ -488,182 +463,159 @@ const Tab = struct { 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| { - self.render_dragging(&btn.plane, theme); - const anchor: Widget.Pos = btn.drag_anchor orelse .{}; - var box = Widget.Box.from(btn.plane); - box.y = @intCast(@max(pos.y, anchor.y) - anchor.y); - box.x = @intCast(@max(pos.x, anchor.x) - anchor.x); - if (tui.top_layer(box.to_layer())) |top_layer| { - self.render_selected(top_layer, btn.opts.label, false, theme, active); - } - } else { - const mode: Mode = if (btn.hover) .selected else if (active) .active else .inactive; - switch (mode) { - .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), - .inactive => self.render_inactive(&btn.plane, btn.opts.label, btn.hover, theme), - } + const mode: Mode = if (btn.hover) .selected else if (active) .active else .inactive; + switch (mode) { + .selected => self.render_selected(btn, theme, active), + .active => self.render_active(btn, theme), + .inactive => self.render_inactive(btn, theme), } return false; } - fn render_selected(self: *@This(), plane: *Plane, label: []const u8, hover: bool, theme: *const Widget.Theme, active: bool) void { - plane.set_base_style(theme.editor); - plane.erase(); - plane.home(); - plane.set_style(.{ + fn render_selected(self: *@This(), btn: *ButtonType, theme: *const Widget.Theme, active: bool) void { + btn.plane.set_base_style(theme.editor); + btn.plane.erase(); + btn.plane.home(); + btn.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(); + btn.plane.fill(" "); + btn.plane.home(); if (active) { - plane.set_style(.{ + btn.plane.set_style(.{ .fg = self.tab_style.selected_fg.from_theme(theme), .bg = self.tab_style.selected_bg.from_theme(theme), }); - plane.fill(" "); - plane.home(); + btn.plane.fill(" "); + btn.plane.home(); } - plane.set_style(.{ + btn.plane.set_style(.{ .fg = self.tab_style.selected_left_fg.from_theme(theme), .bg = self.tab_style.selected_left_bg.from_theme(theme), }); - _ = plane.putstr(self.tab_style.selected_left) catch {}; + _ = btn.plane.putstr(self.tab_style.selected_left) catch {}; - plane.set_style(.{ + btn.plane.set_style(.{ .fg = self.tab_style.selected_fg.from_theme(theme), .bg = self.tab_style.selected_bg.from_theme(theme), }); - self.render_content(plane, label, hover, self.tab_style.selected_fg.from_theme(theme), theme); + self.render_content(btn, self.tab_style.selected_fg.from_theme(theme), theme); - plane.set_style(.{ + btn.plane.set_style(.{ .fg = self.tab_style.selected_right_fg.from_theme(theme), .bg = self.tab_style.selected_right_bg.from_theme(theme), }); - _ = plane.putstr(self.tab_style.selected_right) catch {}; + _ = btn.plane.putstr(self.tab_style.selected_right) catch {}; } - fn render_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(.{ + fn render_active(self: *@This(), btn: *ButtonType, theme: *const Widget.Theme) void { + btn.plane.set_base_style(theme.editor); + btn.plane.erase(); + btn.plane.home(); + btn.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(.{ + btn.plane.fill(" "); + btn.plane.home(); + btn.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(); + btn.plane.fill(" "); + btn.plane.home(); - plane.set_style(.{ + btn.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.active_left) catch {}; + _ = btn.plane.putstr(self.tab_style.active_left) catch {}; - plane.set_style(.{ + btn.plane.set_style(.{ .fg = self.tab_style.active_fg.from_theme(theme), .bg = self.tab_style.active_bg.from_theme(theme), }); - self.render_content(plane, label, hover, self.tab_style.active_fg.from_theme(theme), theme); + self.render_content(btn, self.tab_style.active_fg.from_theme(theme), theme); - plane.set_style(.{ + btn.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.active_right) catch {}; + _ = btn.plane.putstr(self.tab_style.active_right) catch {}; } - fn render_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(.{ + fn render_inactive(self: *@This(), btn: *ButtonType, theme: *const Widget.Theme) void { + btn.plane.set_base_style(theme.editor); + btn.plane.erase(); + btn.plane.home(); + btn.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(); + btn.plane.fill(" "); + btn.plane.home(); - plane.set_style(.{ + btn.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.inactive_left) catch {}; + _ = btn.plane.putstr(self.tab_style.inactive_left) catch {}; - plane.set_style(.{ + btn.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.inactive_fg.from_theme(theme), theme); + self.render_content(btn, self.tab_style.inactive_fg.from_theme(theme), theme); - plane.set_style(.{ + btn.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.inactive_right) catch {}; + _ = btn.plane.putstr(self.tab_style.inactive_right) catch {}; } - fn render_dragging(self: *@This(), plane: *Plane, 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(); - } - - 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(), btn: *ButtonType, fg: ?Widget.Theme.Color, theme: *const Widget.Theme) void { const buffer_manager = tui.get_buffer_manager() orelse @panic("tabs no buffer manager"); const buffer_ = buffer_manager.buffer_from_ref(self.buffer_ref); const is_dirty = if (buffer_) |buffer| buffer.is_dirty() else false; - self.render_padding(plane, .left); + self.render_padding(&btn.plane, .left); if (self.tab_style.file_type_icon) if (buffer_) |buffer| if (buffer.file_type_icon) |icon| { const color_: ?u24 = if (buffer.file_type_color) |color| if (!(color == 0xFFFFFF or color == 0x000000 or color == 0x000001)) color else null else null; if (color_) |color| - plane.set_style(.{ .fg = .{ .color = color } }); - _ = plane.putstr(icon) catch {}; + btn.plane.set_style(.{ .fg = .{ .color = color } }); + _ = btn.plane.putstr(icon) catch {}; if (color_) |_| - plane.set_style(.{ .fg = fg }); - _ = plane.putstr(" ") catch {}; + btn.plane.set_style(.{ .fg = fg }); + _ = btn.plane.putstr(" ") catch {}; }; - _ = plane.putstr(label) catch {}; - _ = plane.putstr(" ") catch {}; + _ = btn.plane.putstr(btn.opts.label) catch {}; + _ = btn.plane.putstr(" ") catch {}; self.close_pos = null; self.save_pos = null; - if (hover) { + if (btn.hover) { if (is_dirty) { if (self.tab_style.save_icon_fg) |color| - plane.set_style(.{ .fg = color.from_theme(theme) }); - self.save_pos = plane.cursor_x(); - _ = plane.putstr(self.tabbar.tab_style.save_icon) catch {}; + btn.plane.set_style(.{ .fg = color.from_theme(theme) }); + self.save_pos = btn.plane.cursor_x(); + _ = btn.plane.putstr(self.tabbar.tab_style.save_icon) catch {}; } else { - plane.set_style(.{ .fg = self.tab_style.close_icon_fg.from_theme(theme) }); - self.close_pos = plane.cursor_x(); - _ = plane.putstr(self.tabbar.tab_style.close_icon) catch {}; + btn.plane.set_style(.{ .fg = self.tab_style.close_icon_fg.from_theme(theme) }); + self.close_pos = btn.plane.cursor_x(); + _ = btn.plane.putstr(self.tabbar.tab_style.close_icon) catch {}; } } else if (is_dirty) { if (self.tab_style.dirty_indicator_fg) |color| - plane.set_style(.{ .fg = color.from_theme(theme) }); - _ = plane.putstr(self.tabbar.tab_style.dirty_indicator) catch {}; + btn.plane.set_style(.{ .fg = color.from_theme(theme) }); + _ = btn.plane.putstr(self.tabbar.tab_style.dirty_indicator) catch {}; } else { if (self.tab_style.clean_indicator_fg) |color| - plane.set_style(.{ .fg = color.from_theme(theme) }); - _ = plane.putstr(self.tabbar.tab_style.clean_indicator) catch {}; + btn.plane.set_style(.{ .fg = color.from_theme(theme) }); + _ = btn.plane.putstr(self.tabbar.tab_style.clean_indicator) catch {}; } - plane.set_style(.{ .fg = fg }); - self.render_padding(plane, .right); + btn.plane.set_style(.{ .fg = fg }); + self.render_padding(&btn.plane, .right); } fn render_padding(self: *@This(), plane: *Plane, side: enum { left, right }) void { diff --git a/src/tui/tui.zig b/src/tui/tui.zig index eee435f..a5cbf37 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -31,7 +31,6 @@ const Allocator = std.mem.Allocator; allocator: Allocator, rdr_: renderer, -top_layer_: ?*renderer.Layer = null, config_: @import("config"), config_bufs: [][]const u8, session_tab_width: ?usize = null, @@ -508,25 +507,12 @@ fn render(self: *Self) void { break :ret if (self.mainview_) |mv| mv.render(self.current_theme()) else false; }; - if (self.top_layer_) |top_layer_| { - const frame = tracy.initZone(@src(), .{ .name = "tui blit top layer" }); - defer frame.deinit(); - self.logger.print("top_layer: {}:{}:{}:{}", .{ - top_layer_.y_off, - top_layer_.x_off, - top_layer_.view.screen.height, - top_layer_.view.screen.width, - }); - top_layer_.draw(self.rdr_.stdplane()); - } - { const frame = tracy.initZone(@src(), .{ .name = renderer.log_name ++ " render" }); defer frame.deinit(); self.rdr_.render() catch |e| self.logger.err("render", e); tracy.frameMark(); } - self.top_layer_reset(); self.idle_frame_count = if (self.unrendered_input_events_count > 0) 0 @@ -1409,11 +1395,6 @@ pub fn get_keybind_mode() ?Mode { return self.input_mode_ orelse self.delayed_init_input_mode; } -pub fn set_drag_source(drag_source: *Widget) void { - const self = current(); - self.drag_source = drag_source; -} - pub fn reset_drag_context() void { const self = current(); self.drag_source = null; @@ -1446,24 +1427,6 @@ fn stdplane(self: *Self) renderer.Plane { return self.rdr_.stdplane(); } -pub fn top_layer(opts: renderer.Layer.Options) ?*renderer.Plane { - const self = current(); - if (self.top_layer_) |_| return null; - self.top_layer_ = renderer.Layer.init( - self.allocator, - self.rdr_.stdplane().window.unicode, - opts, - ) catch @panic("OOM toplayer"); - return self.top_layer_.?.plane(); -} - -fn top_layer_reset(self: *Self) void { - if (self.top_layer_) |top_layer_| { - top_layer_.deinit(); - self.top_layer_ = null; - } -} - pub fn egc_chunk_width(chunk: []const u8, abs_col: usize, tab_width: usize) usize { return plane().egc_chunk_width(chunk, abs_col, tab_width); }