mirror of
https://github.com/kepler155c/opus
synced 2025-10-17 16:57:39 +00:00
better text entry
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
local class = require('class')
|
||||
local entry = require('entry')
|
||||
local UI = require('ui')
|
||||
local Util = require('util')
|
||||
|
||||
local colors = _G.colors
|
||||
local os = _G.os
|
||||
local _rep = string.rep
|
||||
|
||||
UI.TextEntry = class(UI.Window)
|
||||
@@ -18,41 +18,31 @@ UI.TextEntry.defaults = {
|
||||
backgroundFocusColor = colors.black, --lightGray,
|
||||
height = 1,
|
||||
limit = 6,
|
||||
pos = 0,
|
||||
accelerators = {
|
||||
[ 'control-c' ] = 'copy',
|
||||
}
|
||||
}
|
||||
function UI.TextEntry:postInit()
|
||||
self.value = tostring(self.value)
|
||||
self.entry = entry({ limit = self.limit, offset = 2 })
|
||||
end
|
||||
|
||||
function UI.TextEntry:layout()
|
||||
UI.Window.layout(self)
|
||||
self.entry.width = self.width - 2
|
||||
end
|
||||
|
||||
function UI.TextEntry:setValue(value)
|
||||
self.value = value
|
||||
self.entry:unmark()
|
||||
self.entry.value = value
|
||||
self.entry:updateScroll()
|
||||
end
|
||||
|
||||
function UI.TextEntry:setPosition(pos)
|
||||
self.pos = pos
|
||||
end
|
||||
|
||||
function UI.TextEntry:updateScroll()
|
||||
if not self.scroll then
|
||||
self.scroll = 0
|
||||
end
|
||||
|
||||
if not self.pos then
|
||||
self.pos = #tostring(self.value)
|
||||
self.scroll = 0
|
||||
elseif self.pos > #tostring(self.value) then
|
||||
self.pos = #tostring(self.value)
|
||||
self.scroll = 0
|
||||
end
|
||||
|
||||
if self.pos - self.scroll > self.width - 2 then
|
||||
self.scroll = self.pos - (self.width - 2)
|
||||
elseif self.pos < self.scroll then
|
||||
self.scroll = self.pos
|
||||
end
|
||||
self.entry.pos = pos
|
||||
self.entry.value = self.value
|
||||
self.entry:updateScroll()
|
||||
end
|
||||
|
||||
function UI.TextEntry:draw()
|
||||
@@ -62,11 +52,10 @@ function UI.TextEntry:draw()
|
||||
bg = self.backgroundFocusColor
|
||||
end
|
||||
|
||||
self:updateScroll()
|
||||
local text = tostring(self.value)
|
||||
if #text > 0 then
|
||||
if self.scroll and self.scroll > 0 then
|
||||
text = text:sub(1 + self.scroll)
|
||||
if self.entry.scroll > 0 then
|
||||
text = text:sub(1 + self.entry.scroll)
|
||||
end
|
||||
if self.mask then
|
||||
text = _rep('*', #text)
|
||||
@@ -77,21 +66,32 @@ function UI.TextEntry:draw()
|
||||
end
|
||||
|
||||
self:write(1, 1, ' ' .. Util.widthify(text, self.width - 2) .. ' ', bg, tc)
|
||||
|
||||
if self.entry.mark.active then
|
||||
local tx = math.max(self.entry.mark.x - self.entry.scroll, 0)
|
||||
local tex = self.entry.mark.ex - self.entry.scroll
|
||||
|
||||
if tex > self.width - 2 then -- unsure about this
|
||||
tex = self.width - 2 - tx
|
||||
end
|
||||
|
||||
if tx ~= tex then
|
||||
self:write(tx + 2, 1, text:sub(tx + 1, tex), colors.gray, tc)
|
||||
end
|
||||
end
|
||||
if self.focused then
|
||||
self:setCursorPos(self.pos-self.scroll+2, 1)
|
||||
self:setCursorPos(self.entry.pos - self.entry.scroll + 2, 1)
|
||||
end
|
||||
end
|
||||
|
||||
function UI.TextEntry:reset()
|
||||
self.pos = 0
|
||||
self.value = ''
|
||||
self.entry:reset()
|
||||
self:draw()
|
||||
self:updateCursor()
|
||||
end
|
||||
|
||||
function UI.TextEntry:updateCursor()
|
||||
self:updateScroll()
|
||||
self:setCursorPos(self.pos-self.scroll+2, 1)
|
||||
self:setCursorPos(self.entry.pos - self.entry.scroll + 2, 1)
|
||||
end
|
||||
|
||||
function UI.TextEntry:focus()
|
||||
@@ -103,86 +103,20 @@ function UI.TextEntry:focus()
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
A few lines below from theoriginalbit
|
||||
http://www.computercraft.info/forums2/index.php?/topic/16070-read-and-limit-length-of-the-input-field/
|
||||
--]]
|
||||
function UI.TextEntry:eventHandler(event)
|
||||
if event.type == 'key' then
|
||||
local ch = event.key
|
||||
if ch == 'left' then
|
||||
if self.pos > 0 then
|
||||
self.pos = math.max(self.pos-1, 0)
|
||||
self:draw()
|
||||
end
|
||||
elseif ch == 'right' then
|
||||
local input = tostring(self.value)
|
||||
if self.pos < #input then
|
||||
self.pos = math.min(self.pos+1, #input)
|
||||
self:draw()
|
||||
end
|
||||
elseif ch == 'home' then
|
||||
self.pos = 0
|
||||
local text = self.value
|
||||
self.entry.value = text
|
||||
if event.ie and self.entry:process(event.ie) then
|
||||
if self.entry.textChanged then
|
||||
self.value = self.entry.value
|
||||
self:draw()
|
||||
elseif ch == 'end' then
|
||||
self.pos = #tostring(self.value)
|
||||
self:draw()
|
||||
elseif ch == 'backspace' then
|
||||
if self.pos > 0 then
|
||||
local input = tostring(self.value)
|
||||
self.value = input:sub(1, self.pos-1) .. input:sub(self.pos+1)
|
||||
self.pos = self.pos - 1
|
||||
self:draw()
|
||||
if text ~= self.value then
|
||||
self:emit({ type = 'text_change', text = self.value, element = self })
|
||||
end
|
||||
elseif ch == 'delete' then
|
||||
local input = tostring(self.value)
|
||||
if self.pos < #input then
|
||||
self.value = input:sub(1, self.pos) .. input:sub(self.pos+2)
|
||||
self:draw()
|
||||
self:emit({ type = 'text_change', text = self.value, element = self })
|
||||
end
|
||||
elseif #ch == 1 then
|
||||
local input = tostring(self.value)
|
||||
if #input < self.limit then
|
||||
self.value = input:sub(1, self.pos) .. ch .. input:sub(self.pos+1)
|
||||
self.pos = self.pos + 1
|
||||
self:draw()
|
||||
self:emit({ type = 'text_change', text = self.value, element = self })
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
return true
|
||||
|
||||
elseif event.type == 'copy' then
|
||||
os.queueEvent('clipboard_copy', self.value)
|
||||
|
||||
elseif event.type == 'paste' then
|
||||
local input = tostring(self.value)
|
||||
local text = event.text
|
||||
if #input + #text > self.limit then
|
||||
text = text:sub(1, self.limit-#input)
|
||||
end
|
||||
self.value = input:sub(1, self.pos) .. text .. input:sub(self.pos+1)
|
||||
self.pos = self.pos + #text
|
||||
self:draw()
|
||||
self:updateCursor()
|
||||
self:emit({ type = 'text_change', text = self.value, element = self })
|
||||
return true
|
||||
|
||||
elseif event.type == 'mouse_click' then
|
||||
if self.focused and event.x > 1 then
|
||||
self.pos = event.x + self.scroll - 2
|
||||
elseif self.entry.posChanged then
|
||||
self:updateCursor()
|
||||
return true
|
||||
end
|
||||
elseif event.type == 'mouse_rightclick' then
|
||||
local input = tostring(self.value)
|
||||
if #input > 0 then
|
||||
self:reset()
|
||||
self:emit({ type = 'text_change', text = self.value, element = self })
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
|
Reference in New Issue
Block a user