diff --git a/src/SCRIPTS/ELRS/ui/lcd/text_edit.lua b/src/SCRIPTS/ELRS/ui/lcd/text_edit.lua index 444c8f1..759e178 100644 --- a/src/SCRIPTS/ELRS/ui/lcd/text_edit.lua +++ b/src/SCRIPTS/ELRS/ui/lcd/text_edit.lua @@ -7,8 +7,9 @@ -- draw_functions.cpp:178), so editing a string in a tool feels exactly -- -- like editing a model name: the cursor starts on the first char, -- -- rotary cycles that char through the name charset (clamped at the -- --- ends, case preserved), ENTER advances the cursor, ENTER on the last -- --- cell or long ENTER on a space commits, and long ENTER on a letter -- +-- ends, case preserved), ENTER advances the cursor, PAGE keys move it -- +-- back and forth within the value, ENTER on the last cell or long -- +-- ENTER on a space commits, and long ENTER on a letter -- -- toggles its case. EXIT also commits -- edits are applied to the -- -- value as they are made, never reverted. Trailing spaces are stripped -- -- on commit; deletion is overwriting with spaces. -- @@ -63,18 +64,34 @@ end function TextEdit:start() self.editing = true self.cur = 1 + self.long = nil end ---- Replace the char under the cursor, padding with spaces when the --- cursor sits past the end of the value. -function TextEdit:_setChar(c) +--- The value padded with spaces up to the cursor. +function TextEdit:_padded() local v = self.value while #v < self.cur - 1 do v = v .. " " end + return v +end + +--- Replace the char under the cursor. +function TextEdit:_setChar(c) + local v = self:_padded() self.value = string.sub(v, 1, self.cur - 1) .. c .. string.sub(v, self.cur + 1) end +--- Swap the case of the char under the cursor. +function TextEdit:_toggleCase() + local c = self:_charAt(self.cur) + if isUpper(c) then + self:_setChar(string.char(string.byte(c) + 32)) + elseif isLower(c) then + self:_setChar(string.char(string.byte(c) - 32)) + end +end + function TextEdit:_charAt(pos) local c = string.sub(self.value, pos, pos) if c == "" then @@ -98,7 +115,28 @@ end function TextEdit:handleEvent(event) local c = self:_charAt(self.cur) - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_PREV then + -- ENTER still breaks after a long press, and Lua cannot killEvents() it, + -- so the long action runs on that break and swallows it + local long = self.long + if event == EVT_VIRTUAL_ENTER_LONG then + self.long = true + return + elseif event == EVT_VIRTUAL_ENTER then + self.long = nil + end + + if + event == EVT_VIRTUAL_EXIT + or (event == EVT_VIRTUAL_ENTER and long and c == " ") + or (event == EVT_VIRTUAL_ENTER and not long and self.cur >= self.maxLen) + then + self:_commit() + return true + end + + if event == EVT_VIRTUAL_ENTER and long then + self:_toggleCase() + elseif event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_PREV then local idx = charIdx(c) if event == EVT_VIRTUAL_NEXT then idx = math.min(idx + 1, #CHARS) @@ -110,38 +148,15 @@ function TextEdit:handleEvent(event) nc = string.char(string.byte(nc) - 32) end self:_setChar(nc) - return nil - end - - if event == EVT_VIRTUAL_ENTER then - if self.cur < self.maxLen then + elseif event == EVT_VIRTUAL_ENTER then + self.cur = self.cur + 1 + elseif event == EVT_VIRTUAL_NEXT_PAGE then + if self.cur <= #self.value and self.cur < self.maxLen then self.cur = self.cur + 1 - else - self:_commit() - return true - end - return nil - end - - if event == EVT_VIRTUAL_ENTER_LONG then - killEvents(event) - if c == " " then - self:_commit() - return true - elseif isUpper(c) then - self:_setChar(string.char(string.byte(c) + 32)) - elseif isLower(c) then - self:_setChar(string.char(string.byte(c) - 32)) end - return nil + elseif event == EVT_VIRTUAL_PREV_PAGE then + self.cur = math.max(self.cur - 1, 1) end - - if event == EVT_VIRTUAL_EXIT then - self:_commit() - return true - end - - return nil end --- Draw the value at (x, y). attr is the row's base attribute (INVERS on @@ -164,12 +179,13 @@ function TextEdit:draw(x, y, attr) if self.visible and self.cur > self.visible then first = self.cur - self.visible + 1 end - local prefix = string.sub(self.value, first, self.cur - 1) + local v = self:_padded() + local prefix = string.sub(v, first, self.cur - 1) local suffix = "" if self.visible then - suffix = string.sub(self.value, self.cur + 1, first + self.visible - 1) + suffix = string.sub(v, self.cur + 1, first + self.visible - 1) else - suffix = string.sub(self.value, self.cur + 1) + suffix = string.sub(v, self.cur + 1) end lcd.drawText(x, y, prefix)