mirror of
https://github.com/fairyglade/ly.git
synced 2026-03-25 01:36:05 +00:00
Completely refactor widget placement code
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
const std = @import("std");
|
||||
|
||||
const TerminalBuffer = @import("../TerminalBuffer.zig");
|
||||
const Position = @import("../Position.zig");
|
||||
|
||||
pub fn CyclableLabel(comptime ItemType: type, comptime ChangeItemType: type) type {
|
||||
return struct {
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ItemList = std.ArrayListUnmanaged(ItemType);
|
||||
const DrawItemFn = *const fn (*Self, ItemType, usize, usize) bool;
|
||||
const DrawItemFn = *const fn (*Self, ItemType, usize, usize, usize) void;
|
||||
const ChangeItemFn = *const fn (ItemType, ?ChangeItemType) void;
|
||||
|
||||
const termbox = TerminalBuffer.termbox;
|
||||
@@ -17,26 +18,34 @@ pub fn CyclableLabel(comptime ItemType: type, comptime ChangeItemType: type) typ
|
||||
buffer: *TerminalBuffer,
|
||||
list: ItemList,
|
||||
current: usize,
|
||||
visible_length: usize,
|
||||
x: usize,
|
||||
y: usize,
|
||||
first_char_x: usize,
|
||||
width: usize,
|
||||
component_pos: Position,
|
||||
children_pos: Position,
|
||||
text_in_center: bool,
|
||||
item_width: usize,
|
||||
draw_item_fn: DrawItemFn,
|
||||
change_item_fn: ?ChangeItemFn,
|
||||
change_item_arg: ?ChangeItemType,
|
||||
|
||||
pub fn init(allocator: Allocator, buffer: *TerminalBuffer, draw_item_fn: DrawItemFn, change_item_fn: ?ChangeItemFn, change_item_arg: ?ChangeItemType) Self {
|
||||
pub fn init(
|
||||
allocator: Allocator,
|
||||
buffer: *TerminalBuffer,
|
||||
draw_item_fn: DrawItemFn,
|
||||
change_item_fn: ?ChangeItemFn,
|
||||
change_item_arg: ?ChangeItemType,
|
||||
width: usize,
|
||||
text_in_center: bool,
|
||||
) Self {
|
||||
return .{
|
||||
.allocator = allocator,
|
||||
.buffer = buffer,
|
||||
.list = .empty,
|
||||
.current = 0,
|
||||
.visible_length = 0,
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.first_char_x = 0,
|
||||
.text_in_center = false,
|
||||
.width = width,
|
||||
.component_pos = TerminalBuffer.START_POSITION,
|
||||
.children_pos = TerminalBuffer.START_POSITION,
|
||||
.text_in_center = text_in_center,
|
||||
.item_width = 0,
|
||||
.draw_item_fn = draw_item_fn,
|
||||
.change_item_fn = change_item_fn,
|
||||
.change_item_arg = change_item_arg,
|
||||
@@ -47,14 +56,29 @@ pub fn CyclableLabel(comptime ItemType: type, comptime ChangeItemType: type) typ
|
||||
self.list.deinit(self.allocator);
|
||||
}
|
||||
|
||||
pub fn position(self: *Self, x: usize, y: usize, visible_length: usize, text_in_center: ?bool) void {
|
||||
self.x = x;
|
||||
self.y = y;
|
||||
self.visible_length = visible_length;
|
||||
self.first_char_x = x + 2;
|
||||
if (text_in_center) |value| {
|
||||
self.text_in_center = value;
|
||||
}
|
||||
pub fn positionX(self: *Self, original_pos: Position) void {
|
||||
self.component_pos = original_pos;
|
||||
self.item_width = self.component_pos.x + 2;
|
||||
self.children_pos = original_pos.addX(self.width);
|
||||
}
|
||||
|
||||
pub fn positionY(self: *Self, original_pos: Position) void {
|
||||
self.component_pos = original_pos;
|
||||
self.item_width = self.component_pos.x + 2;
|
||||
self.children_pos = original_pos.addY(1);
|
||||
}
|
||||
|
||||
pub fn positionXY(self: *Self, original_pos: Position) void {
|
||||
self.component_pos = original_pos;
|
||||
self.item_width = self.component_pos.x + 2;
|
||||
self.children_pos = Position.init(
|
||||
self.width,
|
||||
1,
|
||||
).add(original_pos);
|
||||
}
|
||||
|
||||
pub fn childrenPosition(self: Self) Position {
|
||||
return self.children_pos;
|
||||
}
|
||||
|
||||
pub fn addItem(self: *Self, item: ItemType) !void {
|
||||
@@ -81,28 +105,51 @@ pub fn CyclableLabel(comptime ItemType: type, comptime ChangeItemType: type) typ
|
||||
}
|
||||
}
|
||||
|
||||
_ = termbox.tb_set_cursor(@intCast(self.first_char_x), @intCast(self.y));
|
||||
_ = termbox.tb_set_cursor(
|
||||
@intCast(self.component_pos.x + self.item_width + 2),
|
||||
@intCast(self.component_pos.y),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn draw(self: *Self) void {
|
||||
if (self.list.items.len == 0) return;
|
||||
|
||||
_ = termbox.tb_set_cell(
|
||||
@intCast(self.component_pos.x),
|
||||
@intCast(self.component_pos.y),
|
||||
'<',
|
||||
self.buffer.fg,
|
||||
self.buffer.bg,
|
||||
);
|
||||
_ = termbox.tb_set_cell(
|
||||
@intCast(self.component_pos.x + self.width - 1),
|
||||
@intCast(self.component_pos.y),
|
||||
'>',
|
||||
self.buffer.fg,
|
||||
self.buffer.bg,
|
||||
);
|
||||
|
||||
const current_item = self.list.items[self.current];
|
||||
const x = self.buffer.box_x + self.buffer.margin_box_h;
|
||||
const y = self.buffer.box_y + self.buffer.margin_box_v + 2;
|
||||
const x = self.component_pos.x + 2;
|
||||
const y = self.component_pos.y;
|
||||
const width = self.width - 2;
|
||||
|
||||
const continue_drawing = @call(.auto, self.draw_item_fn, .{ self, current_item, x, y });
|
||||
if (!continue_drawing) return;
|
||||
|
||||
_ = termbox.tb_set_cell(@intCast(self.x), @intCast(self.y), '<', self.buffer.fg, self.buffer.bg);
|
||||
_ = termbox.tb_set_cell(@intCast(self.x + self.visible_length - 1), @intCast(self.y), '>', self.buffer.fg, self.buffer.bg);
|
||||
@call(
|
||||
.auto,
|
||||
self.draw_item_fn,
|
||||
.{ self, current_item, x, y, width },
|
||||
);
|
||||
}
|
||||
|
||||
fn goLeft(self: *Self) void {
|
||||
self.current = if (self.current == 0) self.list.items.len - 1 else self.current - 1;
|
||||
|
||||
if (self.change_item_fn) |change_item_fn| {
|
||||
@call(.auto, change_item_fn, .{ self.list.items[self.current], self.change_item_arg });
|
||||
@call(
|
||||
.auto,
|
||||
change_item_fn,
|
||||
.{ self.list.items[self.current], self.change_item_arg },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +157,11 @@ pub fn CyclableLabel(comptime ItemType: type, comptime ChangeItemType: type) typ
|
||||
self.current = if (self.current == self.list.items.len - 1) 0 else self.current + 1;
|
||||
|
||||
if (self.change_item_fn) |change_item_fn| {
|
||||
@call(.auto, change_item_fn, .{ self.list.items[self.current], self.change_item_arg });
|
||||
@call(
|
||||
.auto,
|
||||
change_item_fn,
|
||||
.{ self.list.items[self.current], self.change_item_arg },
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user