Better styling
This commit is contained in:
parent
a4ee6e5961
commit
c1eea0352e
@ -2,24 +2,28 @@ const std = @import("std");
|
||||
const dim = @import("dimensions.zig");
|
||||
const pane = @import("pane.zig");
|
||||
const term = @import("term.zig");
|
||||
const Pane = pane.Pane;
|
||||
const TermIO = term.TermIO;
|
||||
|
||||
pub const ButtonConfig = struct {
|
||||
text: []const u8,
|
||||
callback: *const fn () void,
|
||||
};
|
||||
const Pane = pane.Pane;
|
||||
const Style = pane.Style;
|
||||
const TermIO = term.TermIO;
|
||||
|
||||
pub const Button = struct {
|
||||
pane: Pane,
|
||||
text: []const u8,
|
||||
callback: *const fn () void,
|
||||
|
||||
pub fn create(mem: *Button, config: ButtonConfig) *Pane {
|
||||
pub const Config = struct {
|
||||
text: []const u8,
|
||||
callback: *const fn () void,
|
||||
style: Style = .{},
|
||||
};
|
||||
|
||||
pub fn create(mem: *Button, config: Config) *Pane {
|
||||
mem.text = config.text;
|
||||
mem.callback = config.callback;
|
||||
mem.pane = Pane{
|
||||
.focusable = true,
|
||||
.style = config.style,
|
||||
.vtable = .{
|
||||
.draw = draw,
|
||||
.update = update,
|
||||
|
23
src/line.zig
23
src/line.zig
@ -34,4 +34,27 @@ pub const HorizontalLine = struct {
|
||||
|
||||
pub const VerticalLine = struct {
|
||||
pane: Pane,
|
||||
border: borders.Border,
|
||||
|
||||
pub fn create(mem: *VerticalLine, border: borders.Border) *Pane {
|
||||
mem.border = border;
|
||||
mem.pane = Pane{
|
||||
.vtable = .{
|
||||
.draw = draw,
|
||||
},
|
||||
};
|
||||
|
||||
return &mem.pane;
|
||||
}
|
||||
|
||||
fn draw(pane_ptr: *Pane, term_io: *TermIO) !void {
|
||||
const self: *VerticalLine = @fieldParentPtr("pane", pane_ptr);
|
||||
const x = pane_ptr.dimensions.size.width / 2;
|
||||
|
||||
for (0..pane_ptr.dimensions.size.height) |h| {
|
||||
pane_ptr.cursor = .{ .x = x, .y = h };
|
||||
pane_ptr.moveCursor(term_io);
|
||||
term_io.print("{u}", .{self.border.left});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
35
src/main.zig
35
src/main.zig
@ -50,28 +50,36 @@ pub fn main() !void {
|
||||
var child: stack.Stack = undefined;
|
||||
var button: btn.Button = undefined;
|
||||
var tabbar: tabs.TabBar = undefined;
|
||||
var lineV: line.VerticalLine = undefined;
|
||||
var lineH: line.HorizontalLine = undefined;
|
||||
|
||||
var items = [_]menu.MenuItem{ .{ .name = "Item 1" }, .{ .name = "Item ab" } };
|
||||
var items2 = [_]menu.MenuItem{ .{ .name = "Item 1" }, .{ .name = "Item ab" } };
|
||||
var tabs_ = [_]tabs.Tab{ .{ .name = "Tab 1", .pane = &side_menu.pane }, .{ .name = "Tab 2", .pane = &child.pane }, .{ .name = "Tab 3", .pane = &child.pane }, .{ .name = "Tab 4", .pane = &child.pane }, .{ .name = "Tab 5", .pane = &child.pane } };
|
||||
|
||||
_ = stack.Stack.create(&top, .Horizontal, &[_]stack.StackedPane{
|
||||
const green = color.RGB(0, 255, 0);
|
||||
const purple = color.RGB(125, 0, 125);
|
||||
const orange = color.RGB(255, 125, 10);
|
||||
|
||||
_ = stack.Stack.create(&top, .{ .direction = .Horizontal, .style = .{ .border = borders.BoldBorder, .background = color.RGB(30, 30, 30), .foreground = green } }, &[_]stack.StackedPane{
|
||||
.{
|
||||
.pane = menu.Menu.create(&side_menu, .{ .title = "Menu", .align_text = .Center, .expand_highlight = true, .on_select = on_side_select }, &items2),
|
||||
.pane = menu.Menu.create(&side_menu, .{ .title = "Menu", .style = .{ .background = color.RGB(80, 80, 80), .foreground = green }, .align_text = .Center, .expand_highlight = true, .on_select = on_side_select }, &items2),
|
||||
.dimensions = .{ .width = .{ .type = .Fill, .value = 1 }, .height = .{ .type = .Fill, .value = 100 } },
|
||||
},
|
||||
.{ .pane = line.VerticalLine.create(&lineV, borders.BoldBorder), .dimensions = .{ .width = .{ .type = .Absolute, .value = 1 }, .height = .{ .type = .Fill, .value = 100 } } },
|
||||
.{
|
||||
.pane = stack.Stack.create(&child, .Vertical, &[_]stack.StackedPane{
|
||||
.pane = stack.Stack.create(&child, .{ .direction = .Vertical, .style = .{ .border = borders.BoldBorder, .background = purple, .foreground = orange } }, &[_]stack.StackedPane{
|
||||
.{
|
||||
.pane = tabs.TabBar.create(&tabbar, .{ .highlight_color = color.RGB(0, 0, 255) }, &tabs_),
|
||||
.dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Absolute, .value = 1 } },
|
||||
},
|
||||
.{
|
||||
.pane = menu.Menu.create(&m, .{ .title = "Test", .align_text = .Left, .expand_highlight = true, .on_select = on_select }, &items),
|
||||
.pane = menu.Menu.create(&m, .{ .title = "Test", .style = .{ .background = purple, .foreground = orange }, .align_text = .Left, .expand_highlight = true, .on_select = on_select }, &items),
|
||||
.dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Fill, .value = 1 } },
|
||||
},
|
||||
.{ .pane = line.HorizontalLine.create(&lineH, borders.BoldBorder), .dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Absolute, .value = 1 } } },
|
||||
.{
|
||||
.pane = btn.Button.create(&button, .{ .text = "<Button>", .callback = on_click }),
|
||||
.pane = btn.Button.create(&button, .{ .text = "<Button>", .style = .{ .background = purple, .foreground = orange }, .callback = on_click }),
|
||||
.dimensions = .{ .width = .{ .type = .Absolute, .value = 8 }, .height = .{ .type = .Absolute, .value = 1 } },
|
||||
},
|
||||
}),
|
||||
@ -79,23 +87,6 @@ pub fn main() !void {
|
||||
},
|
||||
});
|
||||
|
||||
top.pane.border = borders.BoldBorder;
|
||||
top.pane.background = color.RGB(30, 30, 30);
|
||||
top.pane.foreground = color.RGB(0, 255, 0);
|
||||
|
||||
side_menu.pane.background = color.RGB(80, 80, 80);
|
||||
side_menu.pane.foreground = top.pane.foreground;
|
||||
|
||||
child.pane.border = borders.BoldBorder;
|
||||
child.pane.background = color.RGB(125, 0, 125);
|
||||
child.pane.foreground = color.RGB(255, 125, 10);
|
||||
|
||||
button.pane.background = child.pane.background;
|
||||
button.pane.foreground = child.pane.foreground;
|
||||
|
||||
m.pane.background = child.pane.background;
|
||||
m.pane.foreground = child.pane.foreground;
|
||||
|
||||
pane.set_layout(&top.pane, &m.pane);
|
||||
try pane.init(&term_io);
|
||||
defer pane.cleanup(&term_io);
|
||||
|
24
src/menu.zig
24
src/menu.zig
@ -3,7 +3,9 @@ const log = @import("log.zig");
|
||||
const dim = @import("dimensions.zig");
|
||||
const pane = @import("pane.zig");
|
||||
const term = @import("term.zig");
|
||||
|
||||
const Pane = pane.Pane;
|
||||
const Style = pane.Style;
|
||||
const TermIO = term.TermIO;
|
||||
|
||||
pub const TextAlignment = enum {
|
||||
@ -17,26 +19,28 @@ pub const MenuItem = struct {
|
||||
disabled: bool = false,
|
||||
};
|
||||
|
||||
pub const MenuConfig = struct {
|
||||
title: []const u8 = "",
|
||||
align_text: TextAlignment = .Left,
|
||||
expand_highlight: bool = false,
|
||||
on_select: *const fn (usize) void,
|
||||
};
|
||||
|
||||
pub const Menu = struct {
|
||||
pane: Pane,
|
||||
config: MenuConfig,
|
||||
config: Config,
|
||||
items: []MenuItem,
|
||||
on_select: *const fn (usize) void,
|
||||
index: usize = 0,
|
||||
|
||||
pub fn create(mem: *Menu, config: MenuConfig, items: []MenuItem) *Pane {
|
||||
pub const Config = struct {
|
||||
title: []const u8 = "",
|
||||
style: pane.Style = .{},
|
||||
align_text: TextAlignment = .Left,
|
||||
expand_highlight: bool = false,
|
||||
on_select: *const fn (usize) void,
|
||||
};
|
||||
|
||||
pub fn create(mem: *Menu, config: Config, items: []MenuItem) *Pane {
|
||||
mem.config = config;
|
||||
mem.on_select = config.on_select;
|
||||
mem.items = items;
|
||||
mem.pane = .{
|
||||
mem.pane = Pane{
|
||||
.focusable = true,
|
||||
.style = config.style,
|
||||
.vtable = .{
|
||||
.draw = draw,
|
||||
.focus = focus,
|
||||
|
88
src/pane.zig
88
src/pane.zig
@ -8,34 +8,6 @@ const Border = @import("borders.zig").Border;
|
||||
|
||||
const TermIO = term.TermIO;
|
||||
|
||||
const Window = struct {
|
||||
pane: Pane,
|
||||
child: ?*Pane,
|
||||
|
||||
fn resize(self: *Window, term_io: *TermIO) void {
|
||||
const size = term.getTermSize(term_io);
|
||||
window.pane.dimensions = dim.CalculatedDimensions{
|
||||
.pos = .{ .x = 1, .y = 1 },
|
||||
.internal_pos = .{ .x = 1, .y = 1 },
|
||||
.size = size,
|
||||
.internal_size = size,
|
||||
};
|
||||
|
||||
if (self.child) |child| {
|
||||
child.dimensions.size = self.pane.dimensions.size;
|
||||
child.dimensions.pos = self.pane.dimensions.pos;
|
||||
child.resize();
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(self: *Window, term_io: *TermIO) !void {
|
||||
if (self.child) |child| {
|
||||
try child.draw(term_io);
|
||||
term_io.flush();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var window = Window{ .pane = Pane{}, .child = null };
|
||||
pub var focused_pane: *Pane = undefined;
|
||||
pub var focused_index: usize = 1;
|
||||
@ -43,6 +15,12 @@ pub var should_exit: std.atomic.Value(bool) = std.atomic.Value(bool).init(false)
|
||||
var needs_redraw: std.atomic.Value(bool) = std.atomic.Value(bool).init(false);
|
||||
var redraw_count: usize = 0;
|
||||
|
||||
pub const Style = struct {
|
||||
border: ?Border = null,
|
||||
background: color.Color = color.Default,
|
||||
foreground: color.Color = color.Default,
|
||||
};
|
||||
|
||||
fn resize_signal(_: i32) callconv(.C) void {
|
||||
needs_redraw.store(true, .release);
|
||||
}
|
||||
@ -157,12 +135,10 @@ pub const Cursor = struct {
|
||||
|
||||
pub const Pane = struct {
|
||||
parent: *Pane = undefined,
|
||||
border: ?Border = null,
|
||||
cursor: Cursor = .{ .x = 0, .y = 0 },
|
||||
overflow: Overflow = .{ .x = .Hidden, .y = .Hidden },
|
||||
dimensions: dim.CalculatedDimensions = undefined,
|
||||
background: color.Color = color.Default,
|
||||
foreground: color.Color = color.Default,
|
||||
style: Style = .{},
|
||||
should_draw: bool = true,
|
||||
focusable: bool = false,
|
||||
focused: bool = false,
|
||||
@ -272,7 +248,7 @@ pub const Pane = struct {
|
||||
// }
|
||||
|
||||
pub fn resize(self: *Pane) void {
|
||||
if (self.border) |_| {
|
||||
if (self.style.border) |_| {
|
||||
self.dimensions.internal_pos = .{ .x = self.dimensions.pos.x + 1, .y = self.dimensions.pos.y + 1 };
|
||||
self.dimensions.internal_size = .{ .height = self.dimensions.size.height - 2, .width = self.dimensions.size.width - 2 };
|
||||
} else {
|
||||
@ -284,11 +260,11 @@ pub const Pane = struct {
|
||||
}
|
||||
|
||||
pub fn draw(self: *Pane, term_io: *TermIO) !void {
|
||||
if (self.border) |border| {
|
||||
term_io.setColor(self.background, self.foreground);
|
||||
try term_io.drawBox(self.dimensions, border, !self.background.equal(self.parent.background));
|
||||
} else if (!self.background.equal(self.parent.background)) {
|
||||
term_io.setColor(self.background, self.foreground);
|
||||
if (self.style.border) |border| {
|
||||
term_io.setColor(self.style.background, self.style.foreground);
|
||||
try term_io.drawBox(self.dimensions, border, !self.style.background.equal(self.parent.style.background));
|
||||
} else if (!self.style.background.equal(self.parent.style.background)) {
|
||||
term_io.setColor(self.style.background, self.style.foreground);
|
||||
term_io.fillBox(self.dimensions);
|
||||
}
|
||||
try self.vtable.draw(self, term_io);
|
||||
@ -304,7 +280,7 @@ pub const Pane = struct {
|
||||
self.cursor = .{ .x = 0, .y = 0 };
|
||||
|
||||
self.moveCursor(term_io);
|
||||
term_io.setColor(self.background, self.foreground);
|
||||
term_io.setColor(self.style.background, self.style.foreground);
|
||||
|
||||
self.vtable.focus(self, term_io) catch {};
|
||||
}
|
||||
@ -317,12 +293,12 @@ pub const Pane = struct {
|
||||
}
|
||||
|
||||
pub fn moveCursor(self: *Pane, term_io: *const TermIO) void {
|
||||
const borderWidth: u1 = if (self.border != null) 1 else 0;
|
||||
const borderWidth: u1 = if (self.style.border != null) 1 else 0;
|
||||
term_io.moveCursor(self.dimensions.pos.x + self.cursor.x + borderWidth, self.dimensions.pos.y + self.cursor.y + borderWidth);
|
||||
}
|
||||
|
||||
pub fn print(self: *Pane, term_io: *const TermIO, string: []const u8) !void {
|
||||
const borderWidth: u2 = if (self.border != null) 1 else 0;
|
||||
const borderWidth: u2 = if (self.style.border != null) 1 else 0;
|
||||
var space = self.dimensions.size.width - self.cursor.x - (2 * borderWidth);
|
||||
var i: usize = 0;
|
||||
|
||||
@ -346,8 +322,8 @@ pub const Pane = struct {
|
||||
}
|
||||
|
||||
pub fn write(self: WriterContext, bytes: []const u8) !usize {
|
||||
self.term_io.setColor(self.pane.background, self.pane.foreground);
|
||||
const borderWidth: u2 = if (self.pane.border != null) 1 else 0;
|
||||
self.term_io.setColor(self.pane.style.background, self.pane.style.foreground);
|
||||
const borderWidth: u2 = if (self.pane.style.border != null) 1 else 0;
|
||||
for (bytes) |byte| {
|
||||
switch (byte) {
|
||||
'\x1b' => continue,
|
||||
@ -367,3 +343,31 @@ pub const Pane = struct {
|
||||
return bytes.len;
|
||||
}
|
||||
};
|
||||
|
||||
const Window = struct {
|
||||
pane: Pane,
|
||||
child: ?*Pane,
|
||||
|
||||
fn resize(self: *Window, term_io: *TermIO) void {
|
||||
const size = term.getTermSize(term_io);
|
||||
window.pane.dimensions = dim.CalculatedDimensions{
|
||||
.pos = .{ .x = 1, .y = 1 },
|
||||
.internal_pos = .{ .x = 1, .y = 1 },
|
||||
.size = size,
|
||||
.internal_size = size,
|
||||
};
|
||||
|
||||
if (self.child) |child| {
|
||||
child.dimensions.size = self.pane.dimensions.size;
|
||||
child.dimensions.pos = self.pane.dimensions.pos;
|
||||
child.resize();
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(self: *Window, term_io: *TermIO) !void {
|
||||
if (self.child) |child| {
|
||||
try child.draw(term_io);
|
||||
term_io.flush();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,8 +1,10 @@
|
||||
const dim = @import("dimensions.zig");
|
||||
const term = @import("term.zig");
|
||||
const pane = @import("pane.zig");
|
||||
const std = @import("std");
|
||||
|
||||
const Pane = @import("pane.zig").Pane;
|
||||
const Pane = pane.Pane;
|
||||
const Style = pane.Style;
|
||||
const TermIO = term.TermIO;
|
||||
|
||||
pub const StackDirection = enum {
|
||||
@ -32,24 +34,17 @@ pub const Stack = struct {
|
||||
direction: StackDirection,
|
||||
children: []const StackedPane,
|
||||
|
||||
pub fn create(mem: *Stack, direction: StackDirection, children: []const StackedPane) *Pane {
|
||||
// if (@typeInfo(@TypeOf(children)) != .Struct) {
|
||||
// @compileError("Invalid type" ++ @typeName(@TypeOf(children)));
|
||||
// }
|
||||
//
|
||||
// const fields = std.meta.fields(@TypeOf(children));
|
||||
// var children_array: [fields.len]StackedPane = undefined;
|
||||
// inline for (fields, 0..) |field, i| {
|
||||
// if (field.type != StackedPane) {
|
||||
// @compileError("Invalid child type");
|
||||
// }
|
||||
// children_array[i] = @field(children, field.name);
|
||||
// }
|
||||
const Config = struct {
|
||||
direction: StackDirection,
|
||||
style: Style = .{},
|
||||
};
|
||||
|
||||
mem.direction = direction;
|
||||
pub fn create(mem: *Stack, config: Config, children: []const StackedPane) *Pane {
|
||||
mem.direction = config.direction;
|
||||
mem.children = children;
|
||||
mem.pane = Pane{
|
||||
.focusable = false,
|
||||
.style = config.style,
|
||||
.vtable = .{
|
||||
.resize = resize,
|
||||
.draw = draw,
|
||||
@ -246,14 +241,6 @@ pub const Stack = struct {
|
||||
fn draw(pane_ptr: *Pane, term_io: *TermIO) !void {
|
||||
const self: *Stack = @fieldParentPtr("pane", pane_ptr);
|
||||
|
||||
if (self.pane.border) |border| {
|
||||
term_io.setColor(self.pane.background, self.pane.foreground);
|
||||
try term_io.drawBox(self.pane.dimensions, border, !self.pane.background.equal(self.pane.parent.background));
|
||||
} else if (!self.pane.background.equal(self.pane.parent.background)) {
|
||||
term_io.setColor(self.pane.background, self.pane.foreground);
|
||||
term_io.fillBox(self.pane.dimensions);
|
||||
}
|
||||
|
||||
for (self.children) |child| {
|
||||
if (child.pane.should_draw and self.pane.dimensions.size.width > 0 and self.pane.dimensions.size.height > 0) {
|
||||
try child.pane.draw(term_io);
|
||||
|
11
src/tabs.zig
11
src/tabs.zig
@ -7,6 +7,7 @@ const term = @import("term.zig");
|
||||
const std = @import("std");
|
||||
|
||||
const Pane = pane.Pane;
|
||||
const Style = pane.Style;
|
||||
const TermIO = term.TermIO;
|
||||
|
||||
pub const Tab = struct {
|
||||
@ -22,6 +23,7 @@ pub const TabBar = struct {
|
||||
|
||||
const Config = struct {
|
||||
align_text: menu.TextAlignment = .Center,
|
||||
style: Style = .{},
|
||||
highlight_color: colors.Color,
|
||||
expand_highlight: bool = true,
|
||||
underline: bool = true,
|
||||
@ -33,6 +35,7 @@ pub const TabBar = struct {
|
||||
mem.index = 0;
|
||||
mem.pane = Pane{
|
||||
.focusable = true,
|
||||
.style = config.style,
|
||||
.vtable = .{
|
||||
.draw = draw,
|
||||
.update = update,
|
||||
@ -51,13 +54,13 @@ pub const TabBar = struct {
|
||||
self.pane.cursor = .{ .x = 0, .y = 0 };
|
||||
self.pane.moveCursor(term_io);
|
||||
|
||||
const normal_background = self.pane.background;
|
||||
const normal_background = self.pane.style.background;
|
||||
term_io.enableFormats(.{ .underline = self.config.underline });
|
||||
for (self.tabs, 0..) |tab, i| {
|
||||
if (i == self.index) {
|
||||
self.pane.background = self.config.highlight_color;
|
||||
self.pane.style.background = self.config.highlight_color;
|
||||
} else {
|
||||
self.pane.background = normal_background;
|
||||
self.pane.style.background = normal_background;
|
||||
}
|
||||
|
||||
const width = if (i < extra) tab_width + 1 else tab_width;
|
||||
@ -70,7 +73,7 @@ pub const TabBar = struct {
|
||||
try writer.writeAll(tab.name);
|
||||
try writer.writeByteNTimes(' ', width - (tab.name.len + left));
|
||||
}
|
||||
self.pane.background = normal_background;
|
||||
self.pane.style.background = normal_background;
|
||||
term_io.disableFormats(.{ .underline = self.config.underline });
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user