diff --git a/src/gui/components/TextInput.zig b/src/gui/components/TextInput.zig index 10a2eaab00..93054cec9e 100644 --- a/src/gui/components/TextInput.zig +++ b/src/gui/components/TextInput.zig @@ -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"); @@ -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{ @@ -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); @@ -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; } @@ -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); @@ -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(); } } } @@ -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(); } } } @@ -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.?); @@ -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); @@ -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); @@ -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; @@ -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(); @@ -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(); @@ -481,8 +485,8 @@ 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'); @@ -490,7 +494,8 @@ pub fn newline(self: *TextInput, mods: main.Window.Key.Modifiers) void { } fn ensureCursorVisibility(self: *TextInput) void { - self.showCusor = true; + self.showCursor = true; + if (self.options.disabled) return; self.lastBlinkTime = main.timestamp(); if (self.textSize[1] > self.maxHeight - 2*border) { var y: f32 = 0; @@ -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); @@ -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);