From 61ff055d60f579580cad99d135b0b14f1c5b4f95 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Mon, 26 Aug 2024 20:31:36 -0400 Subject: [PATCH] allow right alignment for numeric inputs --- graphics/core.lua | 37 +++++++++++++++++++------ graphics/elements/form/number_field.lua | 11 ++++++-- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/graphics/core.lua b/graphics/core.lua index 394cbb3..c07b281 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -123,15 +123,17 @@ end -- Interactive Field Manager ----@param e graphics_base ----@param max_len any ----@param fg_bg any ----@param dis_fg_bg any -function core.new_ifield(e, max_len, fg_bg, dis_fg_bg) +---@param e graphics_base element +---@param max_len any max value length +---@param fg_bg any enabled fg/bg +---@param dis_fg_bg any disabled fg/bg +---@param align_right any true to align content right while unfocused +function core.new_ifield(e, max_len, fg_bg, dis_fg_bg, align_right) local self = { frame_start = 1, visible_text = e.value, cursor_pos = string.len(e.value) + 1, + align_offset = 0, selected_all = false } @@ -186,7 +188,12 @@ function core.new_ifield(e, max_len, fg_bg, dis_fg_bg) e.w_write(string.rep(" ", e.frame.w)) e.w_set_cur(1, 1) - local function _write() + local function _write(align_r) + if align_r and string.len(self.visible_text) <=e.frame.w then + self.align_offset = (e.frame.w - string.len(self.visible_text)) + e.w_set_cur((e.frame.w - string.len(self.visible_text)) + 1, 1) + end + if self.censor then e.w_write(string.rep(self.censor, string.len(self.visible_text))) else @@ -226,15 +233,27 @@ function core.new_ifield(e, max_len, fg_bg, dis_fg_bg) self.selected_all = false -- write text without cursor - _write() + _write(align_right) end end - -- move cursor to x + -- get an x value to pass to move_cursor taking into account right alignment offset present when unfocused ---@param x integer + function public.get_cursor_align_shift(x) + return math.max(0, x - self.align_offset) + end + + -- move cursor to x + ---@param x integer x position or 0 to jump to the end function public.move_cursor(x) self.selected_all = false - self.cursor_pos = math.min(x, string.len(self.visible_text) + 1) + + if x <= 0 then + self.cursor_pos = string.len(self.visible_text) + 1 + else + self.cursor_pos = math.min(x, string.len(self.visible_text) + 1) + end + public.show() end diff --git a/graphics/elements/form/number_field.lua b/graphics/elements/form/number_field.lua index ef383ce..01a4dad 100644 --- a/graphics/elements/form/number_field.lua +++ b/graphics/elements/form/number_field.lua @@ -17,6 +17,7 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK ---@field max_frac_digits? integer maximum number of fractional digits, enforced on unfocus ---@field allow_decimal? boolean true to allow decimals ---@field allow_negative? boolean true to allow negative numbers +---@field align_right? boolean true to align right while unfocused ---@field dis_fg_bg? cpair foreground/background colors when disabled ---@field parent graphics_element ---@field id? string element id @@ -47,7 +48,7 @@ local function number_field(args) e.value = "" .. (args.default or 0) -- make an interactive field manager - local ifield = core.new_ifield(e, args.max_chars, args.fg_bg, args.dis_fg_bg) + local ifield = core.new_ifield(e, args.max_chars, args.fg_bg, args.dis_fg_bg, args.align_right) -- handle mouse interaction ---@param event mouse_interaction mouse event @@ -55,10 +56,16 @@ local function number_field(args) -- only handle if on an increment or decrement arrow if e.enabled and e.in_frame_bounds(event.current.x, event.current.y) then if core.events.was_clicked(event.type) then + local x = event.current.x + + if not e.is_focused() then + x = ifield.get_cursor_align_shift(x) + end + e.take_focus() if event.type == MOUSE_CLICK.UP then - ifield.move_cursor(event.current.x) + ifield.move_cursor(x) end elseif event.type == MOUSE_CLICK.DOUBLE_CLICK then ifield.select_all()