Text can now be scrolled.

This commit is contained in:
IntegratedQuantum 2023-03-11 17:45:20 +01:00
parent 44eed8026d
commit b8f5b84322
8 changed files with 219 additions and 46 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

View File

@ -62,29 +62,34 @@ pub const draw = struct {
} }
/// Returns the previous clip. /// Returns the previous clip.
pub fn setClip(newClip: Vec4i) ?Vec4i { pub fn setClip(clipRect: Vec2f) ?Vec4i {
var newClip = Vec4i {
@floatToInt(i32, translation[0]),
main.Window.height - @floatToInt(i32, translation[1] + clipRect[1]*scale),
@floatToInt(i32, clipRect[0]*scale),
@floatToInt(i32, clipRect[1]*scale),
};
if(clip) |oldClip| {
if (newClip[0] < oldClip[0]) {
newClip[2] -= oldClip[0] - newClip[0];
newClip[0] += oldClip[0] - newClip[0];
}
if (newClip[1] < oldClip[1]) {
newClip[3] -= oldClip[1] - newClip[1];
newClip[1] += oldClip[1] - newClip[1];
}
if (newClip[0] + newClip[2] > oldClip[0] + oldClip[2]) {
newClip[2] -= (newClip[0] + newClip[2]) - (oldClip[0] + oldClip[2]);
}
if (newClip[1] + newClip[3] > oldClip[1] + oldClip[3]) {
newClip[3] -= (newClip[1] + newClip[3]) - (oldClip[1] + oldClip[3]);
}
} else {
c.glEnable(c.GL_SCISSOR_TEST);
}
c.glScissor(newClip[0], newClip[1], newClip[2], newClip[3]);
const oldClip = clip; const oldClip = clip;
clip = newClip; clip = newClip;
var clipRef: *Vec4i = &clip.?;
if(oldClip == null) {
c.glEnable(c.GL_SCISSOR_TEST);
} else {
if (clipRef.x < oldClip.x) {
clipRef.z -= oldClip.x - clipRef.x;
clipRef.x += oldClip.x - clipRef.x;
}
if (clipRef.y < oldClip.y) {
clipRef.w -= oldClip.y - clipRef.y;
clipRef.y += oldClip.y - clipRef.y;
}
if (clipRef.x + clipRef.z > oldClip.x + oldClip.z) {
clipRef.z -= (clipRef.x + clipRef.z) - (oldClip.x + oldClip.z);
}
if (clipRef.y + clipRef.w > oldClip.y + oldClip.w) {
clipRef.w -= (clipRef.y + clipRef.w) - (oldClip.y + oldClip.w);
}
}
c.glScissor(clipRef.x, clipRef.y, clipRef.z, clipRef.w);
return oldClip; return oldClip;
} }
@ -92,7 +97,7 @@ pub const draw = struct {
pub fn restoreClip(previousClip: ?Vec4i) void { pub fn restoreClip(previousClip: ?Vec4i) void {
clip = previousClip; clip = previousClip;
if (clip) |clipRef| { if (clip) |clipRef| {
c.glScissor(clipRef.x, clipRef.y, clipRef.z, clipRef.w); c.glScissor(clipRef[0], clipRef[1], clipRef[2], clipRef[3]);
} else { } else {
c.glDisable(c.GL_SCISSOR_TEST); c.glDisable(c.GL_SCISSOR_TEST);
} }
@ -668,6 +673,16 @@ pub const TextBuffer = struct {
var lastSpaceIndex: u32 = 0; var lastSpaceIndex: u32 = 0;
for(self.glyphs, 0..) |glyph, i| { for(self.glyphs, 0..) |glyph, i| {
lineWidth += glyph.x_advance; lineWidth += glyph.x_advance;
if(glyph.character == ' ') {
lastSpaceWidth = lineWidth;
lastSpaceIndex = @intCast(u32, i+1);
}
if(glyph.character == '\n') {
try self.lineBreaks.append(.{.index = @intCast(u32, i+1), .width = lineWidth - spaceCharacterWidth});
lineWidth = 0;
lastSpaceIndex = 0;
lastSpaceWidth = 0;
}
if(lineWidth > scaledMaxWidth) { if(lineWidth > scaledMaxWidth) {
if(lastSpaceIndex != 0) { if(lastSpaceIndex != 0) {
lineWidth -= lastSpaceWidth; lineWidth -= lastSpaceWidth;
@ -681,16 +696,6 @@ pub const TextBuffer = struct {
lastSpaceWidth = 0; lastSpaceWidth = 0;
} }
} }
if(glyph.character == ' ') {
lastSpaceWidth = lineWidth;
lastSpaceIndex = @intCast(u32, i+1);
}
if(glyph.character == '\n') {
try self.lineBreaks.append(.{.index = @intCast(u32, i+1), .width = lineWidth - spaceCharacterWidth});
lineWidth = 0;
lastSpaceIndex = 0;
lastSpaceWidth = 0;
}
} }
self.width = maxLineWidth; self.width = maxLineWidth;
try self.lineBreaks.append(.{.index = @intCast(u32, self.glyphs.len), .width = lineWidth}); try self.lineBreaks.append(.{.index = @intCast(u32, self.glyphs.len), .width = lineWidth});

View File

@ -8,6 +8,7 @@ pub const Button = @import("components/Button.zig");
pub const CheckBox = @import("components/CheckBox.zig"); pub const CheckBox = @import("components/CheckBox.zig");
pub const Label = @import("components/Label.zig"); pub const Label = @import("components/Label.zig");
pub const Slider = @import("components/Slider.zig"); pub const Slider = @import("components/Slider.zig");
pub const ScrollBar = @import("components/ScrollBar.zig");
pub const TextInput = @import("components/TextInput.zig"); pub const TextInput = @import("components/TextInput.zig");
pub const VerticalList = @import("components/VerticalList.zig"); pub const VerticalList = @import("components/VerticalList.zig");
@ -21,6 +22,7 @@ const Impl = union(enum) {
button: Button, button: Button,
checkBox: CheckBox, checkBox: CheckBox,
label: Label, label: Label,
scrollBar: ScrollBar,
slider: Slider, slider: Slider,
textInput: TextInput, textInput: TextInput,
verticalList: VerticalList, verticalList: VerticalList,

View File

@ -0,0 +1,104 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const main = @import("root");
const graphics = main.graphics;
const draw = graphics.draw;
const Image = graphics.Image;
const Shader = graphics.Shader;
const TextBuffer = graphics.TextBuffer;
const Texture = graphics.Texture;
const random = main.random;
const vec = main.vec;
const Vec2f = vec.Vec2f;
const gui = @import("../gui.zig");
const GuiComponent = gui.GuiComponent;
const Button = GuiComponent.Button;
const Label = GuiComponent.Label;
const ScrollBar = @This();
const fontSize: f32 = 16;
var texture: Texture = undefined;
// TODO: Scroll wheel support.
currentState: f32,
button: Button,
buttonSize: Vec2f,
buttonPos: Vec2f = .{0, 0},
mouseAnchor: f32 = undefined,
pub fn __init() !void {
texture = Texture.init();
const image = try Image.readFromFile(main.threadAllocator, "assets/cubyz/ui/scrollbar.png");
defer image.deinit(main.threadAllocator);
try texture.generate(image);
}
pub fn __deinit() void {
texture.deinit();
}
pub fn init(pos: Vec2f, width: f32, height: f32, initialState: f32) Allocator.Error!GuiComponent {
const buttonComponent = try Button.init(undefined, undefined, "", null);
var self = ScrollBar {
.currentState = initialState,
.button = buttonComponent.impl.button,
.buttonSize = .{width, 16},
};
const size = Vec2f{width, height};
self.setButtonPosFromValue(size);
return GuiComponent {
.pos = pos,
.size = size,
.impl = .{.scrollBar = self}
};
}
pub fn deinit(self: ScrollBar) void {
self.button.deinit();
}
fn setButtonPosFromValue(self: *ScrollBar, size: Vec2f) void {
const range: f32 = size[1] - self.buttonSize[1];
self.buttonPos[1] = range*self.currentState;
}
fn updateValueFromButtonPos(self: *ScrollBar, size: Vec2f) void {
const range: f32 = size[1] - self.buttonSize[1];
const value = self.buttonPos[1]/range;
if(value != self.currentState) {
self.currentState = value;
}
}
pub fn mainButtonPressed(self: *ScrollBar, pos: Vec2f, _: Vec2f, mousePosition: Vec2f) void {
if(GuiComponent.contains(self.buttonPos, self.buttonSize, mousePosition - pos)) {
self.button.mainButtonPressed(self.buttonPos, self.buttonSize, mousePosition - pos);
self.mouseAnchor = mousePosition[1] - self.buttonPos[1];
}
}
pub fn mainButtonReleased(self: *ScrollBar, _: Vec2f, _: Vec2f, _: Vec2f) void {
self.button.mainButtonReleased(undefined, undefined, undefined);
}
pub fn render(self: *ScrollBar, pos: Vec2f, size: Vec2f, mousePosition: Vec2f) !void {
graphics.c.glActiveTexture(graphics.c.GL_TEXTURE0);
texture.bind();
Button.shader.bind();
draw.setColor(0xff000000);
draw.customShadedRect(Button.buttonUniforms, pos, size);
const range: f32 = size[1] - self.buttonSize[1];
self.setButtonPosFromValue(size);
if(self.button.pressed) {
self.buttonPos[1] = mousePosition[1] - self.mouseAnchor;
self.buttonPos[1] = @min(@max(self.buttonPos[1], 0), range - 0.001);
self.updateValueFromButtonPos(size);
}
try self.button.render(pos + self.buttonPos, self.buttonSize, mousePosition);
}

View File

@ -13,9 +13,12 @@ const Vec2f = vec.Vec2f;
const gui = @import("../gui.zig"); const gui = @import("../gui.zig");
const GuiComponent = gui.GuiComponent; const GuiComponent = gui.GuiComponent;
const Button = GuiComponent.Button; const Button = GuiComponent.Button;
const ScrollBar = GuiComponent.ScrollBar;
const TextInput = @This(); const TextInput = @This();
const scrollBarWidth = 5;
const border: f32 = 3;
const fontSize: f32 = 16; const fontSize: f32 = 16;
var texture: Texture = undefined; var texture: Texture = undefined;
@ -26,7 +29,10 @@ selectionStart: ?u32 = null,
currentString: std.ArrayList(u8), currentString: std.ArrayList(u8),
textBuffer: TextBuffer, textBuffer: TextBuffer,
maxWidth: f32, maxWidth: f32,
maxHeight: f32,
textSize: Vec2f = undefined, textSize: Vec2f = undefined,
scrollBar: ScrollBar,
scrollBarSize: Vec2f,
pub fn __init() !void { pub fn __init() !void {
texture = Texture.init(); texture = Texture.init();
@ -39,19 +45,21 @@ pub fn __deinit() void {
texture.deinit(); texture.deinit();
} }
// TODO: Make this scrollable. pub fn init(pos: Vec2f, maxWidth: f32, maxHeight: f32, text: []const u8) Allocator.Error!GuiComponent {
const scrollBarComponent = try ScrollBar.init(undefined, scrollBarWidth, maxHeight - 2*border, 0);
pub fn init(pos: Vec2f, maxWidth: f32, text: []const u8) Allocator.Error!GuiComponent {
var self = TextInput { var self = TextInput {
.currentString = std.ArrayList(u8).init(gui.allocator), .currentString = std.ArrayList(u8).init(gui.allocator),
.textBuffer = try TextBuffer.init(gui.allocator, text, .{}, true, .left), .textBuffer = try TextBuffer.init(gui.allocator, text, .{}, true, .left),
.maxWidth = maxWidth, .maxWidth = maxWidth,
.maxHeight = maxHeight,
.scrollBar = scrollBarComponent.impl.scrollBar,
.scrollBarSize = scrollBarComponent.size,
}; };
try self.currentString.appendSlice(text); try self.currentString.appendSlice(text);
self.textSize = try self.textBuffer.calculateLineBreaks(fontSize, maxWidth); self.textSize = try self.textBuffer.calculateLineBreaks(fontSize, maxWidth - 2*border - scrollBarWidth);
return GuiComponent { return GuiComponent {
.pos = pos, .pos = pos,
.size = self.textSize, .size = .{maxWidth, maxHeight},
.impl = .{.textInput = self} .impl = .{.textInput = self}
}; };
} }
@ -59,15 +67,23 @@ pub fn init(pos: Vec2f, maxWidth: f32, text: []const u8) Allocator.Error!GuiComp
pub fn deinit(self: TextInput) void { pub fn deinit(self: TextInput) void {
self.textBuffer.deinit(); self.textBuffer.deinit();
self.currentString.deinit(); self.currentString.deinit();
self.scrollBar.deinit();
} }
pub fn mainButtonPressed(self: *TextInput, pos: Vec2f, _: Vec2f, mousePosition: Vec2f) void { pub fn mainButtonPressed(self: *TextInput, pos: Vec2f, size: Vec2f, mousePosition: Vec2f) void {
if(self.textSize[1] > self.maxHeight - 2*border) {
const scrollBarPos = Vec2f{size[0] - border - scrollBarWidth, border};
if(GuiComponent.contains(scrollBarPos, self.scrollBarSize, mousePosition - pos)) {
self.scrollBar.mainButtonPressed(scrollBarPos, self.scrollBarSize, mousePosition - pos);
return;
}
}
self.cursor = null; self.cursor = null;
self.selectionStart = self.textBuffer.mousePosToIndex(mousePosition - pos, self.currentString.items.len); self.selectionStart = self.textBuffer.mousePosToIndex(mousePosition - pos, self.currentString.items.len);
self.pressed = true; self.pressed = true;
} }
pub fn mainButtonReleased(self: *TextInput, pos: Vec2f, _: Vec2f, mousePosition: Vec2f) void { pub fn mainButtonReleased(self: *TextInput, pos: Vec2f, size: Vec2f, mousePosition: Vec2f) void {
if(self.pressed) { if(self.pressed) {
self.cursor = self.textBuffer.mousePosToIndex(mousePosition - pos, self.currentString.items.len); self.cursor = self.textBuffer.mousePosToIndex(mousePosition - pos, self.currentString.items.len);
if(self.cursor == self.selectionStart) { if(self.cursor == self.selectionStart) {
@ -75,6 +91,9 @@ pub fn mainButtonReleased(self: *TextInput, pos: Vec2f, _: Vec2f, mousePosition:
} }
self.pressed = false; self.pressed = false;
gui.setSelectedTextInput(self); gui.setSelectedTextInput(self);
} else if(self.textSize[1] > self.maxHeight - 2*border) {
self.scrollBar.mainButtonReleased(.{size[0] - border - scrollBarWidth, border}, self.scrollBarSize, mousePosition - pos);
gui.setSelectedTextInput(self);
} }
} }
@ -86,7 +105,7 @@ pub fn deselect(self: *TextInput) void {
fn reloadText(self: *TextInput) !void { fn reloadText(self: *TextInput) !void {
self.textBuffer.deinit(); self.textBuffer.deinit();
self.textBuffer = try TextBuffer.init(gui.allocator, self.currentString.items, .{}, true, .left); self.textBuffer = try TextBuffer.init(gui.allocator, self.currentString.items, .{}, true, .left);
self.textSize = try self.textBuffer.calculateLineBreaks(fontSize, self.maxWidth); self.textSize = try self.textBuffer.calculateLineBreaks(fontSize, self.maxWidth - 2*border - scrollBarWidth);
} }
fn moveCursorLeft(self: *TextInput, mods: main.Key.Modifiers) void { fn moveCursorLeft(self: *TextInput, mods: main.Key.Modifiers) void {
@ -131,6 +150,7 @@ pub fn left(self: *TextInput, mods: main.Key.Modifiers) void {
self.moveCursorLeft(mods); self.moveCursorLeft(mods);
} }
} }
self.ensureCursorVisibility();
} }
} }
@ -172,6 +192,7 @@ pub fn right(self: *TextInput, mods: main.Key.Modifiers) void {
self.moveCursorRight(mods); self.moveCursorRight(mods);
} }
} }
self.ensureCursorVisibility();
} }
} }
@ -197,6 +218,7 @@ pub fn down(self: *TextInput, mods: main.Key.Modifiers) void {
self.moveCursorVertically(1); self.moveCursorVertically(1);
} }
} }
self.ensureCursorVisibility();
} }
} }
@ -218,6 +240,7 @@ pub fn up(self: *TextInput, mods: main.Key.Modifiers) void {
self.moveCursorVertically(-1); self.moveCursorVertically(-1);
} }
} }
self.ensureCursorVisibility();
} }
} }
@ -247,6 +270,7 @@ pub fn gotoStart(self: *TextInput, mods: main.Key.Modifiers) void {
self.moveCursorToStart(mods); self.moveCursorToStart(mods);
} }
} }
self.ensureCursorVisibility();
} }
} }
@ -276,6 +300,7 @@ pub fn gotoEnd(self: *TextInput, mods: main.Key.Modifiers) void {
self.moveCursorToEnd(mods); self.moveCursorToEnd(mods);
} }
} }
self.ensureCursorVisibility();
} }
} }
@ -287,6 +312,7 @@ fn deleteSelection(self: *TextInput) void {
self.currentString.replaceRange(start, end - start, &[0]u8{}) catch unreachable; self.currentString.replaceRange(start, end - start, &[0]u8{}) catch unreachable;
self.cursor.? = start; self.cursor.? = start;
self.selectionStart = null; self.selectionStart = null;
self.ensureCursorVisibility();
} }
} }
@ -300,6 +326,7 @@ pub fn deleteLeft(self: *TextInput, _: main.Key.Modifiers) void {
self.reloadText() catch |err| { self.reloadText() catch |err| {
std.log.err("Error while deleting text: {s}", .{@errorName(err)}); std.log.err("Error while deleting text: {s}", .{@errorName(err)});
}; };
self.ensureCursorVisibility();
} }
pub fn deleteRight(self: *TextInput, _: main.Key.Modifiers) void { pub fn deleteRight(self: *TextInput, _: main.Key.Modifiers) void {
@ -312,6 +339,7 @@ pub fn deleteRight(self: *TextInput, _: main.Key.Modifiers) void {
self.reloadText() catch |err| { self.reloadText() catch |err| {
std.log.err("Error while deleting text: {s}", .{@errorName(err)}); std.log.err("Error while deleting text: {s}", .{@errorName(err)});
}; };
self.ensureCursorVisibility();
} }
pub fn inputCharacter(self: *TextInput, character: u21) !void { pub fn inputCharacter(self: *TextInput, character: u21) !void {
@ -322,6 +350,7 @@ pub fn inputCharacter(self: *TextInput, character: u21) !void {
try self.currentString.insertSlice(cursor.*, utf8); try self.currentString.insertSlice(cursor.*, utf8);
try self.reloadText(); try self.reloadText();
cursor.* += @intCast(u32, utf8.len); cursor.* += @intCast(u32, utf8.len);
self.ensureCursorVisibility();
} }
} }
@ -334,6 +363,7 @@ pub fn copy(self: *TextInput, mods: main.Key.Modifiers) void {
main.Window.setClipboardString(self.currentString.items[start..end]); main.Window.setClipboardString(self.currentString.items[start..end]);
} }
} }
self.ensureCursorVisibility();
} }
} }
@ -348,6 +378,7 @@ pub fn paste(self: *TextInput, mods: main.Key.Modifiers) void {
self.reloadText() catch |err| { self.reloadText() catch |err| {
std.log.err("Error while pasting text: {s}", .{@errorName(err)}); std.log.err("Error while pasting text: {s}", .{@errorName(err)});
}; };
self.ensureCursorVisibility();
} }
} }
@ -358,6 +389,7 @@ pub fn cut(self: *TextInput, mods: main.Key.Modifiers) void {
self.reloadText() catch |err| { self.reloadText() catch |err| {
std.log.err("Error while cutting text: {s}", .{@errorName(err)}); std.log.err("Error while cutting text: {s}", .{@errorName(err)});
}; };
self.ensureCursorVisibility();
} }
} }
@ -365,6 +397,23 @@ pub fn newline(self: *TextInput, _: main.Key.Modifiers) void {
self.inputCharacter('\n') catch |err| { self.inputCharacter('\n') catch |err| {
std.log.err("Error while entering text: {s}", .{@errorName(err)}); std.log.err("Error while entering text: {s}", .{@errorName(err)});
}; };
self.ensureCursorVisibility();
}
fn ensureCursorVisibility(self: *TextInput) void {
if(self.textSize[1] > self.maxHeight - 2*border) {
var y: f32 = 0;
const diff = self.textSize[1] - (self.maxHeight - 2*border);
y -= diff*self.scrollBar.currentState;
if(self.cursor) |cursor| {
var cursorPos = y + self.textBuffer.indexToCursorPos(cursor)[1];
if(cursorPos < 0) {
self.scrollBar.currentState += cursorPos/diff;
} else if(cursorPos + 16 >= self.maxHeight - 2*border) {
self.scrollBar.currentState += (cursorPos + 16 - (self.maxHeight - 2*border))/diff;
}
}
}
} }
pub fn render(self: *TextInput, pos: Vec2f, size: Vec2f, mousePosition: Vec2f) !void { pub fn render(self: *TextInput, pos: Vec2f, size: Vec2f, mousePosition: Vec2f) !void {
@ -373,18 +422,28 @@ pub fn render(self: *TextInput, pos: Vec2f, size: Vec2f, mousePosition: Vec2f) !
Button.shader.bind(); Button.shader.bind();
draw.setColor(0xff000000); draw.setColor(0xff000000);
draw.customShadedRect(Button.buttonUniforms, pos, size); draw.customShadedRect(Button.buttonUniforms, pos, size);
const oldTranslation = draw.setTranslation(pos);
defer draw.restoreTranslation(oldTranslation);
const oldClip = draw.setClip(size);
defer draw.restoreClip(oldClip);
try self.textBuffer.render(pos[0], pos[1], fontSize); var textPos = Vec2f{border, border};
if(self.textSize[1] > self.maxHeight - 2*border) {
const diff = self.textSize[1] - (self.maxHeight - 2*border);
textPos[1] -= diff*self.scrollBar.currentState;
try self.scrollBar.render(.{size[0] - self.scrollBarSize[0] - border, border}, self.scrollBarSize, mousePosition - pos);
}
try self.textBuffer.render(textPos[0], textPos[1], fontSize);
if(self.pressed) { if(self.pressed) {
self.cursor = self.textBuffer.mousePosToIndex(mousePosition - pos, self.currentString.items.len); self.cursor = self.textBuffer.mousePosToIndex(mousePosition - pos, self.currentString.items.len);
} }
if(self.cursor) |cursor| { if(self.cursor) |cursor| {
var cursorPos = textPos + self.textBuffer.indexToCursorPos(cursor);
if(self.selectionStart) |selectionStart| { if(self.selectionStart) |selectionStart| {
draw.setColor(0x440000ff); draw.setColor(0x440000ff);
try self.textBuffer.drawSelection(pos, @min(selectionStart, cursor), @max(selectionStart, cursor)); try self.textBuffer.drawSelection(textPos, @min(selectionStart, cursor), @max(selectionStart, cursor));
} }
draw.setColor(0xff000000); draw.setColor(0xff000000);
const cursorPos = pos + self.textBuffer.indexToCursorPos(cursor);
draw.line(cursorPos, cursorPos + Vec2f{0, 16}); draw.line(cursorPos, cursorPos + Vec2f{0, 16});
} }
} }

View File

@ -10,6 +10,7 @@ const Vec2f = vec.Vec2f;
const Button = @import("components/Button.zig"); const Button = @import("components/Button.zig");
const CheckBox = @import("components/CheckBox.zig"); const CheckBox = @import("components/CheckBox.zig");
const ScrollBar = @import("components/ScrollBar.zig");
const Slider = @import("components/Slider.zig"); const Slider = @import("components/Slider.zig");
const TextInput = @import("components/TextInput.zig"); const TextInput = @import("components/TextInput.zig");
pub const GuiComponent = @import("GuiComponent.zig"); pub const GuiComponent = @import("GuiComponent.zig");
@ -36,6 +37,7 @@ pub fn init(_allocator: Allocator) !void {
try GuiWindow.__init(); try GuiWindow.__init();
try Button.__init(); try Button.__init();
try CheckBox.__init(); try CheckBox.__init();
try ScrollBar.__init();
try Slider.__init(); try Slider.__init();
try TextInput.__init(); try TextInput.__init();
} }
@ -50,6 +52,7 @@ pub fn deinit() void {
GuiWindow.__deinit(); GuiWindow.__deinit();
Button.__deinit(); Button.__deinit();
CheckBox.__deinit(); CheckBox.__deinit();
ScrollBar.__deinit();
Slider.__deinit(); Slider.__deinit();
TextInput.__deinit(); TextInput.__deinit();
} }

View File

@ -30,7 +30,7 @@ const padding: f32 = 8;
pub fn onOpen() Allocator.Error!void { pub fn onOpen() Allocator.Error!void {
var list = try VerticalList.init(); var list = try VerticalList.init();
// TODO Please change your name bla bla // TODO Please change your name bla bla
try list.add(try TextInput.init(.{0, 16}, 128, "gr da jkwa hfeka fuei \n ofuiewo\natg78o4ea74e8t\nz57 t4738qa0 47a80 t47803a t478aqv t487 5t478a0 tg478a09 t748ao t7489a rt4e5 okv5895 678v54vgvo6r z8or z578v rox74et8ys9otv 4z3789so z4oa9t z489saoyt z")); try list.add(try TextInput.init(.{0, 16}, 128, 256, "gr da jkwa hfeka fuei \n ofuiewo\natg78o4ea74e8t\nz57 t4738qa0 47a80 t47803a t478aqv t487 5t478a0 tg478a09 t748ao t7489a rt4e5 okv5895 678v54vgvo6r z8or z578v rox74et8ys9otv 4z3789so z4oa9t z489saoyt z"));
// TODO: Done button. // TODO: Done button.
components[0] = list.toComponent(.{padding, padding}); components[0] = list.toComponent(.{padding, padding});
window.contentSize = components[0].size + @splat(2, @as(f32, 2*padding)); window.contentSize = components[0].size + @splat(2, @as(f32, 2*padding));

View File

@ -421,12 +421,12 @@ pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{.thread_safe=false}){}; var gpa = std.heap.GeneralPurposeAllocator(.{.thread_safe=false}){};
threadAllocator = gpa.allocator(); threadAllocator = gpa.allocator();
defer if(gpa.deinit()) { defer if(gpa.deinit()) {
@panic("Memory leak"); std.log.err("Memory leak", .{});
}; };
var global_gpa = std.heap.GeneralPurposeAllocator(.{.thread_safe=true}){}; var global_gpa = std.heap.GeneralPurposeAllocator(.{.thread_safe=true}){};
globalAllocator = global_gpa.allocator(); globalAllocator = global_gpa.allocator();
defer if(global_gpa.deinit()) { defer if(global_gpa.deinit()) {
@panic("Memory leak"); std.log.err("Memory leak", .{});
}; };
// init logging. // init logging.