opus/sys/apis/entry.lua

152 lines
3.2 KiB
Lua

local class = require('class')
local os = _G.os
local Entry = class()
function Entry:init(args)
self.pos = 0
self.scroll = 0
self.value = ''
self.width = args.width
self.limit = 1024
end
function Entry:reset()
self.pos = 0
self.scroll = 0
self.value = ''
end
local function nextWord(line, cx)
local result = { line:find("(%w+)", cx) }
if #result > 1 and result[2] > cx then
return result[2] + 1
elseif #result > 0 and result[1] == cx then
result = { line:find("(%w+)", result[2] + 1) }
if #result > 0 then
return result[1]
end
end
end
function Entry:updateScroll()
if self.pos - self.scroll > self.width then
self.scroll = self.pos - (self.width)
elseif self.pos < self.scroll then
self.scroll = self.pos
end
end
function Entry:process(ie)
local updated = false
if ie.code == 'left' then
if self.pos > 0 then
self.pos = math.max(self.pos - 1, 0)
updated = true
end
elseif ie.code == 'right' then
local input = tostring(self.value)
if self.pos < #input then
self.pos = math.min(self.pos + 1, #input)
updated = true
end
elseif ie.code == 'home' then
if self.pos ~= 0 then
self.pos = 0
updated = true
end
elseif ie.code == 'end' then
if self.pos ~= #tostring(self.value) then
self.pos = #tostring(self.value)
updated = true
end
elseif ie.code == '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
updated = true
end
elseif ie.code == 'control-right' then
local nx = nextWord(self.value, self.pos + 1)
if nx then
self.pos = math.min(nx - 1, #self.value)
elseif self.pos < #self.value then
self.pos = #self.value
end
updated = true
elseif ie.code == 'control-left' then
if self.pos ~= 0 then
local lx = 1
while true do
local nx = nextWord(self.value, lx)
if not nx or nx >= self.pos then
break
end
lx = nx
end
if not lx then
self.pos = 0
else
self.pos = lx - 1
end
updated = true
end
elseif ie.code == '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.update = true
updated = true
end
elseif ie.code == 'char' then
local input = tostring(self.value)
if #input < self.limit then
self.value = input:sub(1, self.pos) .. ie.ch .. input:sub(self.pos + 1)
self.pos = self.pos + 1
self.update = true
updated = true
end
elseif ie.code == 'copy' then
os.queueEvent('clipboard_copy', self.value)
elseif ie.code == 'paste' then
local input = tostring(self.value)
if #input + #ie.text > self.limit then
ie.text = ie.text:sub(1, self.limit-#input)
end
self.value = input:sub(1, self.pos) .. ie.text .. input:sub(self.pos + 1)
self.pos = self.pos + #ie.text
updated = true
elseif ie.code == 'mouse_click' then
-- need starting x passed in instead of hardcoding 3
self.pos = math.max(0, math.min(ie.x - 3 + self.scroll, #self.value))
updated = true
elseif ie.code == 'mouse_rightclick' then
local input = tostring(self.value)
if #input > 0 then
self:reset()
updated = true
end
end
self:updateScroll()
return updated
end
return Entry