feat(layout): Framing and Padding implementation
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 33s
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 33s
The implementation of `Layout.Framing` however does not use the renderer and instead writes directly to the terminal (which it should not and instead use the renderer). The example has been enhanced with both usage of `Layout.Framing` and `Layout.Padding` Layouts to showcase the `Layout` implementations.
This commit is contained in:
@@ -50,8 +50,23 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
.resize => |size| {
|
.resize => |size| {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
|
log.debug("Event .resize: {{ .anchor = {{ .col = {d}, .row = {d} }}, .cols = {d}, .rows = {d} }}", .{
|
||||||
|
size.anchor.col,
|
||||||
|
size.anchor.row,
|
||||||
|
size.cols,
|
||||||
|
size.rows,
|
||||||
|
});
|
||||||
// adjust size according to the containing elements
|
// adjust size according to the containing elements
|
||||||
const sub_event = event;
|
const sub_event: Event = .{
|
||||||
|
.resize = .{
|
||||||
|
.anchor = .{
|
||||||
|
.col = size.anchor.col + 1,
|
||||||
|
.row = size.anchor.row + 1,
|
||||||
|
},
|
||||||
|
.cols = size.cols -| 2,
|
||||||
|
.rows = size.rows -| 2,
|
||||||
|
},
|
||||||
|
};
|
||||||
switch ((&this.element).*) {
|
switch ((&this.element).*) {
|
||||||
.layout => |*layout| {
|
.layout => |*layout| {
|
||||||
const events = try layout.handle(sub_event);
|
const events = try layout.handle(sub_event);
|
||||||
@@ -82,15 +97,52 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(this: *@This(), renderer: Renderer) !void {
|
pub fn render(this: *@This(), renderer: Renderer) !void {
|
||||||
// TODO: padding contents accordingly
|
// TODO: render frame around the "1" padding
|
||||||
|
try renderer.clear(this.size);
|
||||||
|
// NOTE: round corners: .{ "╭", "─", "╮", "│", "╯", "╰" }
|
||||||
|
// NOTE: hard corners: .{ "┌", "─", "┐", "│", "┘", "└" }
|
||||||
|
// render top: +---+
|
||||||
|
try terminal.setCursorPosition(this.size.anchor);
|
||||||
|
_ = try terminal.write("╭");
|
||||||
|
for (0..this.size.cols -| 2) |_| {
|
||||||
|
_ = try terminal.write("─");
|
||||||
|
}
|
||||||
|
_ = try terminal.write("╮");
|
||||||
|
// render left: |
|
||||||
|
for (1..this.size.rows -| 1) |r| {
|
||||||
|
const row: u16 = @truncate(r);
|
||||||
|
try terminal.setCursorPosition(.{
|
||||||
|
.col = this.size.anchor.col,
|
||||||
|
.row = this.size.anchor.row + row,
|
||||||
|
});
|
||||||
|
_ = try terminal.write("│");
|
||||||
|
}
|
||||||
|
// render right: |
|
||||||
|
for (1..this.size.rows -| 1) |r| {
|
||||||
|
const row: u16 = @truncate(r);
|
||||||
|
try terminal.setCursorPosition(.{
|
||||||
|
.col = this.size.anchor.col + this.size.cols -| 1,
|
||||||
|
.row = this.size.anchor.row + row,
|
||||||
|
});
|
||||||
|
_ = try terminal.write("│");
|
||||||
|
}
|
||||||
|
// render bottom: +---+
|
||||||
|
try terminal.setCursorPosition(.{
|
||||||
|
.col = this.size.anchor.col,
|
||||||
|
.row = this.size.anchor.row + this.size.rows,
|
||||||
|
});
|
||||||
|
_ = try terminal.write("╰");
|
||||||
|
for (0..this.size.cols -| 2) |_| {
|
||||||
|
_ = try terminal.write("─");
|
||||||
|
}
|
||||||
|
_ = try terminal.write("╯");
|
||||||
|
|
||||||
switch ((&this.element).*) {
|
switch ((&this.element).*) {
|
||||||
.layout => |*layout| {
|
.layout => |*layout| {
|
||||||
try layout.render(renderer);
|
try layout.render(renderer);
|
||||||
},
|
},
|
||||||
.widget => |*widget| {
|
.widget => |*widget| {
|
||||||
const content = try widget.content();
|
try widget.render(renderer);
|
||||||
// TODO: use renderer
|
|
||||||
_ = try terminal.write(content);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,13 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
|
|||||||
size: terminal.Size = undefined,
|
size: terminal.Size = undefined,
|
||||||
element: Element = undefined,
|
element: Element = undefined,
|
||||||
events: Events = undefined,
|
events: Events = undefined,
|
||||||
|
padding: u16 = undefined,
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, element: Element) @This() {
|
pub fn init(allocator: std.mem.Allocator, padding: u16, element: Element) @This() {
|
||||||
return .{
|
return .{
|
||||||
.element = element,
|
.element = element,
|
||||||
.events = Events.init(allocator),
|
.events = Events.init(allocator),
|
||||||
|
.padding = padding,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,8 +52,23 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
|
|||||||
switch (event) {
|
switch (event) {
|
||||||
.resize => |size| {
|
.resize => |size| {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
|
log.debug("Event .resize: {{ .anchor = {{ .col = {d}, .row = {d} }}, .cols = {d}, .rows = {d} }}", .{
|
||||||
|
size.anchor.col,
|
||||||
|
size.anchor.row,
|
||||||
|
size.cols,
|
||||||
|
size.rows,
|
||||||
|
});
|
||||||
|
const sub_event: Event = .{
|
||||||
|
.resize = .{
|
||||||
|
.anchor = .{
|
||||||
|
.col = size.anchor.col + this.padding,
|
||||||
|
.row = size.anchor.row + this.padding,
|
||||||
|
},
|
||||||
|
.cols = size.cols -| this.padding -| this.padding,
|
||||||
|
.rows = size.rows -| this.padding -| this.padding,
|
||||||
|
},
|
||||||
|
};
|
||||||
// adjust size according to the containing elements
|
// adjust size according to the containing elements
|
||||||
const sub_event = event;
|
|
||||||
switch ((&this.element).*) {
|
switch ((&this.element).*) {
|
||||||
.layout => |*layout| {
|
.layout => |*layout| {
|
||||||
const events = try layout.handle(sub_event);
|
const events = try layout.handle(sub_event);
|
||||||
@@ -82,15 +99,12 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(this: *@This(), renderer: Renderer) !void {
|
pub fn render(this: *@This(), renderer: Renderer) !void {
|
||||||
// TODO: padding contents accordingly
|
|
||||||
switch ((&this.element).*) {
|
switch ((&this.element).*) {
|
||||||
.layout => |*layout| {
|
.layout => |*layout| {
|
||||||
try layout.render(renderer);
|
try layout.render(renderer);
|
||||||
},
|
},
|
||||||
.widget => |*widget| {
|
.widget => |*widget| {
|
||||||
const content = try widget.content();
|
try widget.render(renderer);
|
||||||
// TODO: use renderer
|
|
||||||
_ = try terminal.write(content);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
src/main.zig
50
src/main.zig
@@ -36,26 +36,38 @@ pub fn main() !void {
|
|||||||
var spacer = Widget.Spacer.init();
|
var spacer = Widget.Spacer.init();
|
||||||
break :blk &spacer;
|
break :blk &spacer;
|
||||||
}),
|
}),
|
||||||
Layout.createFrom(vstack: {
|
Layout.createFrom(framing: {
|
||||||
var vstack = Layout.VStack.init(allocator, .{
|
var framing = Layout.Framing.init(allocator, .{
|
||||||
Widget.createFrom(blk: {
|
.layout = Layout.createFrom(
|
||||||
const file = try std.fs.cwd().openFile("./src/app.zig", .{});
|
padding: {
|
||||||
defer file.close();
|
var padding = Layout.Padding.init(allocator, 2, .{
|
||||||
var widget = Widget.RawText.init(allocator, file);
|
.layout = Layout.createFrom(vstack: {
|
||||||
break :blk &widget;
|
var vstack = Layout.VStack.init(allocator, .{
|
||||||
}),
|
Widget.createFrom(blk: {
|
||||||
Widget.createFrom(blk: {
|
const file = try std.fs.cwd().openFile("./src/app.zig", .{});
|
||||||
var spacer = Widget.Spacer.init();
|
defer file.close();
|
||||||
break :blk &spacer;
|
var widget = Widget.RawText.init(allocator, file);
|
||||||
}),
|
break :blk &widget;
|
||||||
Widget.createFrom(blk: {
|
}),
|
||||||
const file = try std.fs.cwd().openFile("./src/main.zig", .{});
|
Widget.createFrom(blk: {
|
||||||
defer file.close();
|
var spacer = Widget.Spacer.init();
|
||||||
var widget = Widget.RawText.init(allocator, file);
|
break :blk &spacer;
|
||||||
break :blk &widget;
|
}),
|
||||||
}),
|
Widget.createFrom(blk: {
|
||||||
|
const file = try std.fs.cwd().openFile("./src/main.zig", .{});
|
||||||
|
defer file.close();
|
||||||
|
var widget = Widget.RawText.init(allocator, file);
|
||||||
|
break :blk &widget;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
break :vstack &vstack;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
break :padding &padding;
|
||||||
|
},
|
||||||
|
),
|
||||||
});
|
});
|
||||||
break :vstack &vstack;
|
break :framing &framing;
|
||||||
}),
|
}),
|
||||||
Widget.createFrom(blk: {
|
Widget.createFrom(blk: {
|
||||||
var spacer = Widget.Spacer.init();
|
var spacer = Widget.Spacer.init();
|
||||||
|
|||||||
@@ -79,19 +79,16 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
|
|||||||
try renderer.clear(this.size);
|
try renderer.clear(this.size);
|
||||||
try terminal.setCursorPosition(this.size.anchor);
|
try terminal.setCursorPosition(this.size.anchor);
|
||||||
if (this.size.rows >= this.line_index.items.len) {
|
if (this.size.rows >= this.line_index.items.len) {
|
||||||
log.debug("render: {s}", .{this.contents.items});
|
|
||||||
try renderer.render(this.size, this.contents.items);
|
try renderer.render(this.size, this.contents.items);
|
||||||
} else {
|
} else {
|
||||||
// more rows than we can display
|
// more rows than we can display
|
||||||
const i = this.line_index.items[this.line];
|
const i = this.line_index.items[this.line];
|
||||||
const e = this.size.rows + this.line;
|
const e = this.size.rows + this.line;
|
||||||
if (e > this.line_index.items.len) {
|
if (e > this.line_index.items.len) {
|
||||||
log.debug("render: {s}", .{this.contents.items[i..]});
|
|
||||||
try renderer.render(this.size, this.contents.items[i..]);
|
try renderer.render(this.size, this.contents.items[i..]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const x = this.line_index.items[e];
|
const x = this.line_index.items[e];
|
||||||
log.debug("render: {s}", .{this.contents.items[i..x]});
|
|
||||||
try renderer.render(this.size, this.contents.items[i..x]);
|
try renderer.render(this.size, this.contents.items[i..x]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user