Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions src/gui/components/TextInput.zig
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ maxWidth: f32,
maxHeight: f32,
textSize: Vec2f = undefined,
scrollBar: *ScrollBar,
callbacks: Callbacks,
options: Options,
lastBlinkTime: std.Io.Timestamp = .fromNanoseconds(0),
showCusor: bool = true,
showCursor: bool = true,

pub fn globalInit() void {
texture = Texture.initFromFile("assets/cubyz/ui/text_input.png");
Expand All @@ -46,14 +46,15 @@ pub fn globalDeinit() void {
texture.deinit();
}

const Callbacks = struct {
onNewline: main.callbacks.SimpleCallback,
const Options = struct {
disabled: bool = false,
onNewline: main.callbacks.SimpleCallback = .{},
onUp: main.callbacks.SimpleCallback = .{},
onDown: main.callbacks.SimpleCallback = .{},
onUpdate: main.callbacks.SimpleCallback = .{},
};

pub fn init(pos: Vec2f, maxWidth: f32, maxHeight: f32, text: []const u8, callbacks: Callbacks) *TextInput {
pub fn init(pos: Vec2f, maxWidth: f32, maxHeight: f32, text: []const u8, options: Options) *TextInput {
const scrollBar = ScrollBar.init(undefined, scrollBarWidth, maxHeight - 2*border, 0);
const self = main.globalAllocator.create(TextInput);
self.* = TextInput{
Expand All @@ -64,7 +65,7 @@ pub fn init(pos: Vec2f, maxWidth: f32, maxHeight: f32, text: []const u8, callbac
.maxWidth = maxWidth,
.maxHeight = maxHeight,
.scrollBar = scrollBar,
.callbacks = callbacks,
.options = options,
};
self.currentString.appendSlice(text);
self.textSize = self.textBuffer.calculateLineBreaks(fontSize, maxWidth - 2*border - scrollBarWidth);
Expand All @@ -83,7 +84,7 @@ pub fn deinit(self: *const TextInput) void {
}

pub fn clear(self: *TextInput) void {
if (self.cursor != null) {
if (self.cursor != null and !self.options.disabled) {
self.cursor = 0;
self.selectionStart = null;
}
Expand Down Expand Up @@ -164,7 +165,7 @@ pub fn deselect(self: *TextInput) void {
}

fn reloadText(self: *TextInput) void {
self.callbacks.onUpdate.run();
self.options.onUpdate.run();
self.textBuffer.deinit();
self.textBuffer = TextBuffer.init(main.globalAllocator, self.currentString.items, .{}, true, .left);
self.textSize = self.textBuffer.calculateLineBreaks(fontSize, self.maxWidth - 2*border - scrollBarWidth);
Expand Down Expand Up @@ -293,7 +294,7 @@ pub fn down(self: *TextInput, mods: main.Window.Key.Modifiers) void {
self.selectionStart = null;
} else {
if (self.moveCursorVertically(1) == .same) {
self.callbacks.onDown.run();
self.options.onDown.run();
}
}
}
Expand All @@ -317,7 +318,7 @@ pub fn up(self: *TextInput, mods: main.Window.Key.Modifiers) void {
self.selectionStart = null;
} else {
if (self.moveCursorVertically(-1) == .same) {
self.callbacks.onUp.run();
self.options.onUp.run();
}
}
}
Expand Down Expand Up @@ -386,6 +387,7 @@ pub fn gotoEnd(self: *TextInput, mods: main.Window.Key.Modifiers) void {
}

fn deleteSelection(self: *TextInput) void {
if (self.options.disabled) return;
if (self.selectionStart) |selectionStart| {
const start = @min(selectionStart, self.cursor.?);
const end = @max(selectionStart, self.cursor.?);
Expand All @@ -398,7 +400,7 @@ fn deleteSelection(self: *TextInput) void {
}

pub fn deleteLeft(self: *TextInput, mods: main.Window.Key.Modifiers) void {
if (self.cursor == null) return;
if (self.cursor == null or self.options.disabled) return;
if (self.selectionStart == null) {
self.selectionStart = self.cursor;
self.moveCursorLeft(mods);
Expand All @@ -409,7 +411,7 @@ pub fn deleteLeft(self: *TextInput, mods: main.Window.Key.Modifiers) void {
}

pub fn deleteRight(self: *TextInput, mods: main.Window.Key.Modifiers) void {
if (self.cursor == null) return;
if (self.cursor == null or self.options.disabled) return;
if (self.selectionStart == null) {
self.selectionStart = self.cursor;
self.moveCursorRight(mods);
Expand All @@ -420,6 +422,7 @@ pub fn deleteRight(self: *TextInput, mods: main.Window.Key.Modifiers) void {
}

pub fn inputCharacter(self: *TextInput, character: u21) void {
if (self.options.disabled) return;
if (self.cursor) |*cursor| {
self.deleteSelection();
var buf: [4]u8 = undefined;
Expand Down Expand Up @@ -461,6 +464,7 @@ pub fn copy(self: *TextInput, mods: main.Window.Key.Modifiers) void {
}

pub fn paste(self: *TextInput, mods: main.Window.Key.Modifiers) void {
if (self.options.disabled) return;
if (mods.control) {
const string = main.Window.getClipboardString();
self.deleteSelection();
Expand All @@ -472,7 +476,7 @@ pub fn paste(self: *TextInput, mods: main.Window.Key.Modifiers) void {
}

pub fn cut(self: *TextInput, mods: main.Window.Key.Modifiers) void {
if (mods.control) {
if (mods.control and !self.options.disabled) {
self.copy(mods);
self.deleteSelection();
self.reloadText();
Expand All @@ -481,16 +485,17 @@ pub fn cut(self: *TextInput, mods: main.Window.Key.Modifiers) void {
}

pub fn newline(self: *TextInput, mods: main.Window.Key.Modifiers) void {
if (!mods.shift and self.callbacks.onNewline.inner != null) {
self.callbacks.onNewline.run();
if (!mods.shift and self.options.onNewline.inner != null and !self.options.disabled) {
self.options.onNewline.run();
return;
}
self.inputCharacter('\n');
self.ensureCursorVisibility();
}

fn ensureCursorVisibility(self: *TextInput) void {
self.showCusor = true;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unintended removal

self.showCursor = true;
if (self.options.disabled) return;
self.lastBlinkTime = main.timestamp();
if (self.textSize[1] > self.maxHeight - 2*border) {
var y: f32 = 0;
Expand Down Expand Up @@ -540,6 +545,8 @@ pub fn render(self: *TextInput, mousePosition: Vec2f) void {
self.scrollBar.pos = .{self.size[0] - self.scrollBar.size[0] - border, border};
self.scrollBar.render(mousePosition - self.pos);
}
const textColor = draw.setColor(if (self.options.disabled) 0xff808080 else 0xffffffff);
defer draw.restoreColor(textColor);
textBuffer.render(textPos[0], textPos[1], fontSize);
if (self.pressed) {
self.cursor = self.textBuffer.mousePosToIndex(mousePosition - textPos - self.pos, self.currentString.items.len);
Expand All @@ -555,12 +562,14 @@ pub fn render(self: *TextInput, mousePosition: Vec2f) void {
}

const currentTime = main.timestamp();
if (self.lastBlinkTime.durationTo(currentTime).nanoseconds > blinkDuration.nanoseconds) {
self.lastBlinkTime = currentTime;
self.showCusor = !self.showCusor;
if (!self.options.disabled) {
if (self.lastBlinkTime.durationTo(currentTime).nanoseconds > blinkDuration.nanoseconds) {
self.lastBlinkTime = currentTime;
self.showCursor = !self.showCursor;
}
}

if (self.showCusor) {
if (self.showCursor and !self.options.disabled) {
const oldColor = draw.setColor(0xff000000);
defer draw.restoreColor(oldColor);
const thickness = @min(@ceil(fontSize/8), 1);
Expand Down
Loading