rem: Scroll from Propierties of Container

Updated the corresponding documentation and ideas for how to realize
scrollable contents.
This commit is contained in:
2025-02-15 18:50:36 +01:00
parent 01eb14f1bd
commit d951906b2b
4 changed files with 93 additions and 27 deletions

View File

@@ -185,17 +185,6 @@ pub const Rectangle = packed struct {
}
};
/// Scroll configuration struct
pub const Scroll = packed struct {
/// Enable horizontal scrolling for this element
horizontal: bool = false,
/// Enable vertical scrolling for this element
vertical: bool = false,
// TODO: rendering enhancements:
// - render corresponding scroll-bars?
};
/// Layout configuration struct
pub const Layout = packed struct {
/// control the direction in which child elements are laid out
@@ -244,7 +233,6 @@ pub fn Container(comptime Event: type) type {
pub const Properties = packed struct {
border: Border = .{},
rectangle: Rectangle = .{},
scroll: Scroll = .{},
layout: Layout = .{},
};
@@ -328,9 +316,7 @@ pub fn Container(comptime Event: type) type {
break :blk rows - element_rows * len;
},
};
// TODO: make sure that items cannot underflow in size!
// - make their size and position still according (even if outside of the visible space!)
// - don't render them then accordingly -> avoid index out of bounce accesses!
for (this.elements.items) |*element| {
var element_size: Size = undefined;
switch (layout.direction) {

View File

@@ -1,4 +1,6 @@
//! Interface for Element's which describe the contents of a `Container`.
const std = @import("std");
const Cell = @import("cell.zig");
const Size = @import("size.zig").Size;
@@ -12,12 +14,57 @@ pub fn Element(Event: type) type {
content: ?*const fn (ctx: *anyopaque, cells: []Cell, size: Size) anyerror!void = null,
};
/// Handle the received event. The event is one of the user provided
/// events or a system event, with the exception of the `.resize`
/// `Event` as every `Container` already handles that event.
///
/// In case of user errors this function should return an error. This
/// error may then be used by the application to display information
/// about the user error.
pub inline fn handle(this: @This(), event: Event) !void {
if (this.vtable.handle) |handle_fn| try handle_fn(this.ptr, event);
if (this.vtable.handle) |handle_fn|
try handle_fn(this.ptr, event);
}
/// Write content into the `cells` of the `Container`. The associated
/// `cells` slice has the size of (`size.cols * size.rows`). The
/// renderer will know where to place the contents on the screen.
///
/// This function should only fail with an error if the error is
/// non-recoverable (i.e. an allocation error, system error, etc.).
/// Otherwise user specific errors should be caught using the `handle`
/// function before the rendering of the `Container` happens.
pub inline fn content(this: @This(), cells: []Cell, size: Size) !void {
if (this.vtable.content) |content_fn| try content_fn(this.ptr, cells, size);
if (this.vtable.content) |content_fn|
try content_fn(this.ptr, cells, size);
}
};
}
/// This is an empty template implementation for an Element type which `zterm` may provide.
///
/// TODO: Should elements need to be composible with each other, such that they may build complexer outputs?
/// - the goal would rather be to have re-usable parts of handlers and/or content functions which serve similar functionalities.
pub fn Template(Event: type) type {
return packed struct {
pub fn element(this: *@This()) Element(Event) {
return .{
.ptr = this,
.vtable = &.{
.handle = handle,
.content = content,
},
};
}
fn handle(ctx: *anyopaque, event: Event) !void {
_ = ctx;
_ = event;
}
fn content(ctx: *anyopaque, cells: []Cell, size: Size) !void {
_ = ctx;
std.debug.assert(cells.len == @as(usize, size.cols) * @as(usize, size.rows));
}
};
}