Compare commits
2 Commits
a83e86f8d9
...
8ebab702ac
| Author | SHA1 | Date | |
|---|---|---|---|
|
8ebab702ac
|
|||
|
e53bb7880b
|
@@ -27,7 +27,6 @@ const QuitText = struct {
|
||||
pub fn main() !void {
|
||||
errdefer |err| log.err("Application Error: {any}", .{err});
|
||||
|
||||
// TODO maybe create own allocator as some sort of arena allocator to have consistent memory usage
|
||||
var gpa: std.heap.DebugAllocator(.{}) = .init;
|
||||
defer if (gpa.deinit() == .leak) log.err("memory leak", .{});
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ const HelloWorldText = packed struct {
|
||||
pub fn main() !void {
|
||||
errdefer |err| log.err("Application Error: {any}", .{err});
|
||||
|
||||
// TODO maybe create own allocator as some sort of arena allocator to have consistent memory usage
|
||||
var gpa: std.heap.DebugAllocator(.{}) = .init;
|
||||
defer {
|
||||
const deinit_status = gpa.deinit();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
//! Cell type containing content and formatting for each character in the terminal screen.
|
||||
|
||||
// TODO embrace `zg` dependency more due to utf-8 encoding
|
||||
cp: u21 = ' ',
|
||||
style: Style = .{ .emphasis = &.{} },
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ pub const Color = enum(u8) {
|
||||
white,
|
||||
// TODO add further colors as described in https://gist.github.com/ConnerWill/d4b6c776b509add763e17f9f113fd25b # Color / Graphics Mode - 256 Colors
|
||||
|
||||
// TODO might be useful to use the std.ascii stuff!
|
||||
|
||||
pub inline fn write(this: Color, writer: *std.Io.Writer, comptime coloring: enum { fg, bg, ul }) !void {
|
||||
if (this == .default) {
|
||||
switch (coloring) {
|
||||
|
||||
@@ -891,7 +891,7 @@ pub fn Container(Model: type, Event: type) type {
|
||||
const fit_size = this.fit_resize();
|
||||
// if (fit_size.y > size.y or fit_size.x > size.x) @panic("error: cannot render in available space");
|
||||
switch (this.properties.size.grow) {
|
||||
.both => this.size = Point.max(size, fit_size),
|
||||
.both => this.size = .max(size, fit_size),
|
||||
.fixed => {},
|
||||
.horizontal => this.size = .{
|
||||
.x = @max(size.x, fit_size.x),
|
||||
|
||||
@@ -228,11 +228,16 @@ pub fn Scrollable(Model: type, Event: type) type {
|
||||
configuration: Configuration,
|
||||
|
||||
pub const Configuration = packed struct {
|
||||
// TODO the scrollbar bool and the color should be in their own struct using `enabled` and `color` inside of the struct to be more consistent with other `Configuration` structs
|
||||
scrollbar: bool,
|
||||
/// Primary color to be used for the scrollbar (and background if enabled)
|
||||
color: Color = .default,
|
||||
/// With a backgroud the `color` rendered with emphasis `.dim`
|
||||
/// will be used to highlight the scrollbar from the background;
|
||||
/// otherwise nothing is shown for the background
|
||||
show_background: bool = false,
|
||||
/// should the scrollbar be shown for the x-axis (horizontal)
|
||||
x_axis: bool = false,
|
||||
/// should the scrollbar be shown for the y-axis (vertical)
|
||||
y_axis: bool = false,
|
||||
|
||||
pub const disabled: @This() = .{ .scrollbar = false };
|
||||
@@ -270,26 +275,26 @@ pub fn Scrollable(Model: type, Event: type) type {
|
||||
const last_max_anchor_x = this.container_size.x -| this.size.x;
|
||||
const last_max_anchor_y = this.container_size.y -| this.size.y;
|
||||
|
||||
this.size = size;
|
||||
// NOTE `container_size` denotes the `size` required for the container contents
|
||||
var container_size = this.container.element.minSize(size);
|
||||
if (this.configuration.scrollbar) {
|
||||
this.configuration.y_axis = this.container.properties.size.dim.x > this.size.x or this.container.size.x > this.size.x;
|
||||
this.configuration.x_axis = this.container.properties.size.dim.y > this.size.y or this.container.size.y > this.size.y;
|
||||
this.configuration.y_axis = this.container.properties.size.dim.x > size.x or container_size.x > size.x;
|
||||
this.configuration.x_axis = this.container.properties.size.dim.y > size.y or container_size.y > size.y;
|
||||
// correct size dimensions due to space needed for the axis (if any)
|
||||
container_size.x -= if (this.configuration.x_axis) 1 else 0;
|
||||
container_size.y -= if (this.configuration.y_axis) 1 else 0;
|
||||
}
|
||||
|
||||
const min_size = this.container.element.minSize(size);
|
||||
this.container.resize(.{
|
||||
.x = min_size.x - if (this.configuration.x_axis) @as(u16, 1) else @as(u16, 0),
|
||||
.y = min_size.y - if (this.configuration.y_axis) @as(u16, 1) else @as(u16, 0),
|
||||
});
|
||||
} else this.container.resize(this.container.element.minSize(size)); // notify the container about the minimal size it should have (can be larger)
|
||||
|
||||
const new_max_anchor_x = this.container.size.x -| size.x;
|
||||
const new_max_anchor_y = this.container.size.y -| size.y;
|
||||
const new_max_anchor_x = container_size.x -| size.x;
|
||||
const new_max_anchor_y = container_size.y -| size.y;
|
||||
|
||||
// correct anchor if necessary
|
||||
if (new_max_anchor_x < last_max_anchor_x and this.anchor.x > new_max_anchor_x) this.anchor.x = new_max_anchor_x;
|
||||
if (new_max_anchor_y < last_max_anchor_y and this.anchor.y > new_max_anchor_y) this.anchor.y = new_max_anchor_y;
|
||||
|
||||
this.container_size = this.container.size;
|
||||
this.size = size;
|
||||
this.container.resize(container_size); // notify the container about the minimal size it should have
|
||||
this.container_size = container_size;
|
||||
}
|
||||
|
||||
fn reposition(ctx: *anyopaque, _: Point) void {
|
||||
@@ -300,7 +305,6 @@ pub fn Scrollable(Model: type, Event: type) type {
|
||||
fn handle(ctx: *anyopaque, model: *Model, event: Event) !void {
|
||||
const this: *@This() = @ptrCast(@alignCast(ctx));
|
||||
switch (event) {
|
||||
.init => this.container.resize(this.container.element.minSize(this.size)),
|
||||
// TODO what about multiple scrollable `Element` usages? mouse
|
||||
// can differ between them (due to the event being only send to
|
||||
// the `Container` / `Element` one under the cursor!)
|
||||
@@ -671,6 +675,7 @@ pub fn Button(Model: type, Event: type, Queue: type) fn (meta.FieldEnum(Event))
|
||||
pub fn button_fn(accept_event: meta.FieldEnum(Event)) type {
|
||||
{ // check for type correctness and the associated type to use for the passed `accept_event`
|
||||
const err_msg = "Unexpected type for the associated input completion event to trigger. Only `void` is allowed.";
|
||||
// TODO supported nested tagged unions to be also be used for triggering if the enum is then still of `void`type!
|
||||
switch (@typeInfo(@FieldType(Event, @tagName(accept_event)))) {
|
||||
.void => |_| {},
|
||||
else => @compileError(err_msg),
|
||||
|
||||
@@ -9,6 +9,9 @@ pub const SystemEvent = union(enum) {
|
||||
/// Quit event to signify the end of the event loop (rendering should stop afterwards)
|
||||
quit,
|
||||
/// Resize event to signify that the application should re-draw to resize
|
||||
///
|
||||
/// Usually no `Container` nor `Element` should act on that event, as it
|
||||
/// only serves for event based loops to force a re-draw with a new `Event`.
|
||||
resize,
|
||||
/// Error event to notify other containers about a recoverable error
|
||||
err: struct {
|
||||
|
||||
@@ -65,8 +65,6 @@ pub const Key = packed struct {
|
||||
return meta.eql(this, other);
|
||||
}
|
||||
|
||||
// TODO might be useful to use the std.ascii stuff!
|
||||
|
||||
/// Determine if the `Key` is an ascii character that can be printed to
|
||||
/// the screen. This means that the code point of the `Key` is an ascii
|
||||
/// character between 32 - 255 (with the exception of 127 = Delete) and no
|
||||
|
||||
@@ -40,8 +40,6 @@ pub fn eql(this: Style, other: Style) bool {
|
||||
return meta.eql(this, other);
|
||||
}
|
||||
|
||||
// TODO might be useful to use the std.ascii stuff!
|
||||
|
||||
pub fn value(this: Style, writer: *std.Io.Writer, cp: u21) !void {
|
||||
var buffer: [4]u8 = undefined;
|
||||
const bytes = try unicode.utf8Encode(cp, &buffer);
|
||||
|
||||
Reference in New Issue
Block a user