feat(renderer): render cells instead of raw u8 array contents
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 39s
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 39s
This commit is contained in:
@@ -14,6 +14,7 @@ const std = @import("std");
|
||||
const terminal = @import("terminal.zig");
|
||||
|
||||
const Contents = std.ArrayList(u8); // TODO: this may contain more than just a single character! (i.e. styled)
|
||||
const Cells = []const terminal.Cell;
|
||||
const Position = terminal.Position;
|
||||
const Size = terminal.Size;
|
||||
|
||||
@@ -136,16 +137,18 @@ pub fn Direct(comptime _: bool) type {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(this: *@This(), size: Size, contents: []u8) !void {
|
||||
pub fn render(this: *@This(), size: Size, cells: Cells) !void {
|
||||
_ = this;
|
||||
try terminal.setCursorPosition(size.anchor);
|
||||
var row: u16 = 0;
|
||||
var idx: usize = 0;
|
||||
var skip_next_line = false;
|
||||
for (contents, 0..) |item, i| {
|
||||
if (item == '\n') { // do not print newlines
|
||||
if (!skip_next_line) {
|
||||
_ = try terminal.write(contents[idx..i]); // does not include '\n' at position _i_
|
||||
var remaining_cols = size.cols;
|
||||
const writer = terminal.writer();
|
||||
for (cells) |cell| {
|
||||
var idx: usize = 0;
|
||||
print_cell: while (true) {
|
||||
const cell_len = cell.len(idx);
|
||||
if (cell_len > remaining_cols) {
|
||||
const result = try cell.writeUpToNewline(writer, idx, idx + remaining_cols);
|
||||
row += 1;
|
||||
if (row >= size.rows) {
|
||||
return; // we are done
|
||||
@@ -154,34 +157,46 @@ pub fn Direct(comptime _: bool) type {
|
||||
.col = size.anchor.col,
|
||||
.row = size.anchor.row + row,
|
||||
});
|
||||
}
|
||||
skip_next_line = false;
|
||||
idx = i + 1; // skip over '\n'
|
||||
continue;
|
||||
}
|
||||
if (i - idx == size.cols) {
|
||||
// FIXME: this will introduce another additional line which is not accounted for and will cut off these lines in the end from rendering
|
||||
// -> *current solution*: cut of the line and skip that remaining content (not sure if that should be done)
|
||||
// - however the widget has actually knowledge about the size and could change the reported contents which fit to the size or simply don't care and leave it to the renderer?
|
||||
// flush line
|
||||
if (!skip_next_line) {
|
||||
_ = try terminal.write(contents[idx..i]);
|
||||
row += 1;
|
||||
if (row >= size.rows) {
|
||||
return; // we are done
|
||||
remaining_cols = size.cols;
|
||||
idx = result.idx;
|
||||
if (result.newline) {
|
||||
idx += 1; // skip over newline
|
||||
} else {
|
||||
// there is still content to the newline (which will not be printed)
|
||||
for (idx..cell.content.len) |i| {
|
||||
if (cell.content[i] == '\n') {
|
||||
idx = i + 1;
|
||||
continue :print_cell;
|
||||
}
|
||||
}
|
||||
break; // go to next cell (as we went to the end of the cell and do not print on the next line)
|
||||
}
|
||||
} else {
|
||||
// print rest of cell
|
||||
const result = try cell.writeUpToNewline(writer, idx, idx + cell_len);
|
||||
if (result.newline) {
|
||||
row += 1;
|
||||
if (row >= size.rows) {
|
||||
return; // we are done
|
||||
}
|
||||
try terminal.setCursorPosition(.{
|
||||
.col = size.anchor.col,
|
||||
.row = size.anchor.row + row,
|
||||
});
|
||||
remaining_cols = size.cols;
|
||||
idx = result.idx + 1; // skip over newline
|
||||
} else {
|
||||
remaining_cols -= @truncate(cell_len - idx);
|
||||
idx = 0;
|
||||
break; // go to next cell
|
||||
}
|
||||
try terminal.setCursorPosition(.{
|
||||
.col = size.anchor.col,
|
||||
.row = size.anchor.row + row,
|
||||
});
|
||||
}
|
||||
skip_next_line = true;
|
||||
idx = i;
|
||||
// written all cell contents
|
||||
if (idx >= cell.content.len) {
|
||||
break; // go to next cell
|
||||
}
|
||||
}
|
||||
}
|
||||
if (idx < contents.len) {
|
||||
_ = try terminal.write(contents[idx..]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flush(this: @This()) !void {
|
||||
|
||||
Reference in New Issue
Block a user