feat: add support for scrolling and transparent windows in vaxis backend
This commit is contained in:
parent
0707b52d8a
commit
8c9338ddd2
1 changed files with 29 additions and 14 deletions
|
@ -15,6 +15,8 @@ name_len: usize,
|
||||||
cache: GraphemeCache = .{},
|
cache: GraphemeCache = .{},
|
||||||
style: vaxis.Cell.Style = .{},
|
style: vaxis.Cell.Style = .{},
|
||||||
style_base: vaxis.Cell.Style = .{},
|
style_base: vaxis.Cell.Style = .{},
|
||||||
|
scrolling: bool = false,
|
||||||
|
transparent: bool = false,
|
||||||
|
|
||||||
pub const Options = struct {
|
pub const Options = struct {
|
||||||
y: usize = 0,
|
y: usize = 0,
|
||||||
|
@ -42,6 +44,7 @@ pub fn init(nopts: *const Options, parent_: Plane) !Plane {
|
||||||
.window = parent_.window.child(opts),
|
.window = parent_.window.child(opts),
|
||||||
.name_buf = undefined,
|
.name_buf = undefined,
|
||||||
.name_len = std.mem.span(nopts.name).len,
|
.name_len = std.mem.span(nopts.name).len,
|
||||||
|
.scrolling = nopts.flags == .VSCROLL,
|
||||||
};
|
};
|
||||||
@memcpy(plane.name_buf[0..plane.name_len], nopts.name);
|
@memcpy(plane.name_buf[0..plane.name_len], nopts.name);
|
||||||
return plane;
|
return plane;
|
||||||
|
@ -135,6 +138,7 @@ pub fn print_aligned_center(self: *Plane, y: c_int, comptime fmt: anytype, args:
|
||||||
|
|
||||||
pub fn putstr(self: *Plane, text: []const u8) !usize {
|
pub fn putstr(self: *Plane, text: []const u8) !usize {
|
||||||
var result: usize = 0;
|
var result: usize = 0;
|
||||||
|
const height = self.window.height;
|
||||||
const width = self.window.width;
|
const width = self.window.width;
|
||||||
var iter = self.window.screen.unicode.graphemeIterator(text);
|
var iter = self.window.screen.unicode.graphemeIterator(text);
|
||||||
while (iter.next()) |grapheme| {
|
while (iter.next()) |grapheme| {
|
||||||
|
@ -142,21 +146,15 @@ pub fn putstr(self: *Plane, text: []const u8) !usize {
|
||||||
return result;
|
return result;
|
||||||
const s = grapheme.bytes(text);
|
const s = grapheme.bytes(text);
|
||||||
if (std.mem.eql(u8, s, "\n")) {
|
if (std.mem.eql(u8, s, "\n")) {
|
||||||
self.row += 1;
|
if (self.scrolling and self.row == height - 1)
|
||||||
|
self.window.scroll(1)
|
||||||
|
else
|
||||||
|
self.row += 1;
|
||||||
self.col = 0;
|
self.col = 0;
|
||||||
result += 1;
|
result += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const w = self.window.gwidth(s);
|
self.write_cell(@intCast(self.col), @intCast(self.row), s);
|
||||||
if (w == 0) continue;
|
|
||||||
self.window.writeCell(@intCast(self.col), @intCast(self.row), .{
|
|
||||||
.char = .{
|
|
||||||
.grapheme = self.cache.put(s),
|
|
||||||
.width = w,
|
|
||||||
},
|
|
||||||
.style = self.style,
|
|
||||||
});
|
|
||||||
self.col += @intCast(w);
|
|
||||||
result += 1;
|
result += 1;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -175,6 +173,20 @@ pub fn putc_yx(self: *Plane, y: c_int, x: c_int, cell: *const Cell) !usize {
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_cell(self: *Plane, col: usize, row: usize, egc: []const u8) void {
|
||||||
|
var cell: vaxis.Cell = self.window.readCell(col, row) orelse .{ .style = self.style };
|
||||||
|
const w = self.window.gwidth(egc);
|
||||||
|
cell.char.grapheme = self.cache.put(egc);
|
||||||
|
cell.char.width = w;
|
||||||
|
if (self.transparent) {
|
||||||
|
cell.style.fg = self.style.fg;
|
||||||
|
} else {
|
||||||
|
cell.style = self.style;
|
||||||
|
}
|
||||||
|
self.window.writeCell(col, row, cell);
|
||||||
|
self.col += @intCast(w);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cursor_yx(self: Plane, y: *c_uint, x: *c_uint) void {
|
pub fn cursor_yx(self: Plane, y: *c_uint, x: *c_uint) void {
|
||||||
y.* = @intCast(self.row);
|
y.* = @intCast(self.row);
|
||||||
x.* = @intCast(self.col);
|
x.* = @intCast(self.col);
|
||||||
|
@ -212,7 +224,6 @@ pub fn cell_init(self: Plane) Cell {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cell_load(self: *Plane, cell: *Cell, gcluster: [:0]const u8) !usize {
|
pub fn cell_load(self: *Plane, cell: *Cell, gcluster: [:0]const u8) !usize {
|
||||||
cell.* = .{ .cell = .{ .style = self.style } };
|
|
||||||
var cols: c_int = 0;
|
var cols: c_int = 0;
|
||||||
const bytes = self.egc_length(gcluster, &cols, 0);
|
const bytes = self.egc_length(gcluster, &cols, 0);
|
||||||
cell.cell.char.grapheme = self.cache.put(gcluster[0..bytes]);
|
cell.cell.char.grapheme = self.cache.put(gcluster[0..bytes]);
|
||||||
|
@ -275,28 +286,32 @@ pub inline fn set_base_style(self: *Plane, _: [*c]const u8, style_: Style) void
|
||||||
|
|
||||||
pub fn set_base_style_transparent(self: *Plane, _: [*:0]const u8, style_: Style) void {
|
pub fn set_base_style_transparent(self: *Plane, _: [*:0]const u8, style_: Style) void {
|
||||||
self.style_base.fg = if (style_.fg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
self.style_base.fg = if (style_.fg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
||||||
self.style_base.bg = if (style_.bg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
self.style.bg = .default;
|
||||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||||
self.set_style(style_);
|
self.set_style(style_);
|
||||||
|
self.transparent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_base_style_bg_transparent(self: *Plane, _: [*:0]const u8, style_: Style) void {
|
pub fn set_base_style_bg_transparent(self: *Plane, _: [*:0]const u8, style_: Style) void {
|
||||||
self.style_base.fg = if (style_.fg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
self.style_base.fg = if (style_.fg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
||||||
self.style_base.bg = if (style_.bg) |color| vaxis.Cell.Color.rgbFromUint(@intCast(color)) else .default;
|
self.style.bg = .default;
|
||||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||||
self.set_style(style_);
|
self.set_style(style_);
|
||||||
|
self.transparent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn set_style(self: *Plane, style_: Style) void {
|
pub inline fn set_style(self: *Plane, style_: Style) void {
|
||||||
if (style_.fg) |color| self.style.fg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
if (style_.fg) |color| self.style.fg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
||||||
if (style_.bg) |color| self.style.bg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
if (style_.bg) |color| self.style.bg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
||||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||||
|
self.transparent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn set_style_bg_transparent(self: *Plane, style_: Style) void {
|
pub inline fn set_style_bg_transparent(self: *Plane, style_: Style) void {
|
||||||
if (style_.fg) |color| self.style.fg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
if (style_.fg) |color| self.style.fg = vaxis.Cell.Color.rgbFromUint(@intCast(color));
|
||||||
self.style.bg = .default;
|
self.style.bg = .default;
|
||||||
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
if (style_.fs) |fs| set_font_style(&self.style, fs);
|
||||||
|
self.transparent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn set_font_style(style: *vaxis.Cell.Style, fs: FontStyle) void {
|
inline fn set_font_style(style: *vaxis.Cell.Style, fs: FontStyle) void {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue