Wrap some stuff around things and whatnot
This commit is contained in:
@@ -4,6 +4,7 @@ const container = @import("root.zig");
|
||||
|
||||
const Block = container.Block;
|
||||
const Point = container.Point;
|
||||
const Rect = container.Rect;
|
||||
const Rowable = container.Rowable;
|
||||
const Matrix = container.Matrix;
|
||||
const Error = container.Error;
|
||||
@@ -52,6 +53,11 @@ pub fn SubMatrix(comptime T: type) type {
|
||||
return r[self._mask.loc.x .. self._mask.loc.x + self._mask.size.width];
|
||||
}
|
||||
|
||||
// size returns the size of the submask
|
||||
pub fn size(self: *@This()) Rect {
|
||||
return self._mask.size;
|
||||
}
|
||||
|
||||
pub fn row_iterator(self: *@This()) RowIterator(T) {
|
||||
return .init(&self.rowable);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
const std = @import("std");
|
||||
const grome = @import("../root.zig");
|
||||
|
||||
const Point = grome.container.Point;
|
||||
const Block = grome.container.Block;
|
||||
const SubMatrix = grome.container.SubMatrix;
|
||||
const Widget = grome.view.Widget;
|
||||
const Rect = grome.view.Rect;
|
||||
const WidgetError = grome.view.WidgetError;
|
||||
const Cell = grome.view.Cell;
|
||||
const Style = grome.view.style.Style;
|
||||
|
||||
pub const Rectangle = struct {
|
||||
style: ?Style,
|
||||
block: Block,
|
||||
widget: Widget,
|
||||
|
||||
pub fn init(
|
||||
block: Block,
|
||||
style: ?Style,
|
||||
) Rectangle {
|
||||
return .{
|
||||
.style = style,
|
||||
.block = block,
|
||||
.widget = .{
|
||||
.geometryFn = Rectangle.geometry,
|
||||
.renderFn = Rectangle.render,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn geometry(widget: *Widget) Block {
|
||||
const self: *@This() = @fieldParentPtr("widget", widget);
|
||||
|
||||
return self.block;
|
||||
}
|
||||
|
||||
pub fn render(widget: *Widget, frame: *SubMatrix(Cell)) WidgetError!void {
|
||||
const self: *@This() = @fieldParentPtr("widget", widget);
|
||||
const size = frame.size();
|
||||
|
||||
var first = frame.rowable.row(0) catch return WidgetError.UnknownError;
|
||||
first[0] = Cell{
|
||||
.char = ("┌ " ** 2).*,
|
||||
.style = self.style,
|
||||
.width = 3,
|
||||
};
|
||||
@memset(first[1 .. first.len - 1], Cell{
|
||||
.char = ("─ " ** 2).*,
|
||||
.style = self.style,
|
||||
.width = 3,
|
||||
});
|
||||
first[first.len - 1] = Cell{
|
||||
.char = ("┐ " ** 2).*,
|
||||
.style = self.style,
|
||||
.width = 3,
|
||||
};
|
||||
|
||||
for (1..size.height - 1) |row_num| {
|
||||
var row = frame.rowable.row(row_num) catch return WidgetError.UnknownError;
|
||||
row[0] = Cell{
|
||||
.char = ("│ " ** 2).*,
|
||||
.style = self.style,
|
||||
.width = 3,
|
||||
};
|
||||
row[row.len - 1] = Cell{
|
||||
.char = ("│ " ** 2).*,
|
||||
.style = self.style,
|
||||
.width = 3,
|
||||
};
|
||||
}
|
||||
|
||||
var last = frame.rowable.row(size.height - 1) catch return WidgetError.UnknownError;
|
||||
last[0] = Cell{
|
||||
.char = ("└ " ** 2).*,
|
||||
.style = self.style,
|
||||
.width = 3,
|
||||
};
|
||||
@memset(last[1 .. last.len - 1], Cell{
|
||||
.char = ("─ " ** 2).*,
|
||||
.style = self.style,
|
||||
.width = 3,
|
||||
});
|
||||
last[last.len - 1] = Cell{
|
||||
.char = ("┘ " ** 2).*,
|
||||
.style = self.style,
|
||||
.width = 3,
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -1,2 +1,3 @@
|
||||
pub const Text = @import("text.zig").Text;
|
||||
pub const Nucleus = @import("nucleus.zig").Nucleus;
|
||||
pub const Rectangle = @import("rect.zig").Rectangle;
|
||||
|
||||
+5
-2
@@ -8,17 +8,19 @@ const Widget = grome.view.Widget;
|
||||
const WidgetError = grome.view.WidgetError;
|
||||
const Cell = grome.view.Cell;
|
||||
const Block = grome.container.Block;
|
||||
const Point = grome.container.Point;
|
||||
const SubMatrix = grome.container.SubMatrix;
|
||||
const Style = style.Style;
|
||||
|
||||
pub const Text = struct {
|
||||
// TODO: This should be a matrix instead and we should add the ability
|
||||
// to turn raw text into a Matrix(Cell)
|
||||
location: Point,
|
||||
text: [1024]Cell,
|
||||
text_width: usize,
|
||||
widget: Widget,
|
||||
|
||||
pub fn init(text: []const u8, s: ?Style) @This() {
|
||||
pub fn init(text: []const u8, location: Point, s: ?Style) @This() {
|
||||
// TODO: this is bad, but I want to see it work.
|
||||
var cells: [1024]Cell = undefined;
|
||||
|
||||
@@ -33,6 +35,7 @@ pub const Text = struct {
|
||||
return .{
|
||||
.text = cells,
|
||||
.text_width = text.len,
|
||||
.location = location,
|
||||
.widget = .{
|
||||
.geometryFn = @This().geometry,
|
||||
.renderFn = @This().render,
|
||||
@@ -43,7 +46,7 @@ pub const Text = struct {
|
||||
pub fn geometry(widget: *Widget) Block {
|
||||
const self: *@This() = @fieldParentPtr("widget", widget);
|
||||
return Block{
|
||||
.loc = .{ .x = 0, .y = 0 },
|
||||
.loc = self.location,
|
||||
.size = .{ .height = 1, .width = self.text_width },
|
||||
};
|
||||
}
|
||||
|
||||
+8
-6
@@ -1,5 +1,6 @@
|
||||
const std = @import("std");
|
||||
const grome = @import("root.zig");
|
||||
const term = grome.view.term;
|
||||
const style = grome.view.style;
|
||||
|
||||
const Duration = std.Io.Duration;
|
||||
@@ -9,6 +10,7 @@ const Rect = grome.container.Rect;
|
||||
const Text = grome.game.Text;
|
||||
const Nucleus = grome.game.Nucleus;
|
||||
const Viewport = grome.view.Viewport;
|
||||
const Rectangle = grome.game.Rectangle;
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
// This is appropriate for anything that lives as long as the process.
|
||||
@@ -20,18 +22,18 @@ pub fn main(init: std.process.Init) !void {
|
||||
var w = &stdout_file_writer.interface;
|
||||
|
||||
// alright lets play with the matrix
|
||||
const size = Rect{
|
||||
.height = 70,
|
||||
.width = 120,
|
||||
};
|
||||
const size = try term.term_size(init.io);
|
||||
|
||||
var viewport = try Viewport.init(arena, size);
|
||||
defer viewport.deinit(arena);
|
||||
|
||||
var text = Text.init("Hello Olive", style.Blue);
|
||||
var rect = Rectangle.init(.{ .loc = .{ .x = 0, .y = 0 }, .size = size }, null);
|
||||
try viewport.add_widget(arena, &rect.widget);
|
||||
|
||||
var text = Text.init("Hello Olive", .{ .x = 1, .y = 1 }, style.Blue);
|
||||
try viewport.add_widget(arena, &text.widget);
|
||||
|
||||
var nucleus = Nucleus.init(.{ .x = 1, .y = 1 });
|
||||
var nucleus = Nucleus.init(.{ .x = 3, .y = 3 });
|
||||
try viewport.add_widget(arena, &nucleus.widget);
|
||||
|
||||
try viewport.hard_refresh(w);
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const grome = @import("../root.zig");
|
||||
|
||||
const Writer = std.Io.Writer;
|
||||
const Rect = grome.container.Rect;
|
||||
|
||||
pub const Error = error{
|
||||
PlatformNotSupported,
|
||||
UnknownError,
|
||||
};
|
||||
|
||||
/// clear clears the terminal screen entierly
|
||||
pub fn clear(w: *Writer) !void {
|
||||
@@ -33,3 +41,33 @@ pub fn clear_remaining_line(w: *Writer) !void {
|
||||
pub fn hide_cursor(w: *Writer) !void {
|
||||
_ = try w.write("\x1b[?25l");
|
||||
}
|
||||
|
||||
/// term_size defineds the terminal size when run. I hope
|
||||
pub fn term_size(io: std.Io) !Rect {
|
||||
return switch (builtin.os.tag) {
|
||||
.linux => {
|
||||
var winsize: std.posix.winsize = .{
|
||||
.row = 0,
|
||||
.col = 0,
|
||||
.xpixel = 0,
|
||||
.ypixel = 0,
|
||||
};
|
||||
|
||||
const err = (try std.Io.operate(io, .{ .device_io_control = .{
|
||||
.file = .stdout(),
|
||||
.code = std.posix.T.IOCGWINSZ,
|
||||
.arg = &winsize,
|
||||
} })).device_io_control;
|
||||
|
||||
if (err >= 0) {
|
||||
return Rect{
|
||||
.height = winsize.row,
|
||||
.width = winsize.col,
|
||||
};
|
||||
} else {
|
||||
return Error.UnknownError;
|
||||
}
|
||||
},
|
||||
else => Error.PlatformNotSupported,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user