774 lines
31 KiB
Lua
774 lines
31 KiB
Lua
local tHex = require("tHex")
|
|
|
|
local rep,find,gmatch,sub,len = string.rep,string.find,string.gmatch,string.sub,string.len
|
|
|
|
return function(name, basalt)
|
|
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
|
local objectType = "Textfield"
|
|
local hIndex, wIndex, textX, textY = 1, 1, 1, 1
|
|
|
|
local lines = { "" }
|
|
local bgLines = { "" }
|
|
local fgLines = { "" }
|
|
local keyWords = { }
|
|
local rules = { }
|
|
|
|
local startSelX,endSelX,startSelY,endSelY
|
|
|
|
local selectionBG,selectionFG = colors.lightBlue,colors.black
|
|
|
|
base:setSize(30, 12)
|
|
base:setZIndex(5)
|
|
|
|
local function isSelected()
|
|
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function getSelectionCoordinates()
|
|
local sx, ex, sy, ey = startSelX, endSelX, startSelY, endSelY
|
|
if isSelected() then
|
|
if startSelX < endSelX and startSelY <= endSelY then
|
|
sx = startSelX
|
|
ex = endSelX
|
|
if startSelY < endSelY then
|
|
sy = startSelY
|
|
ey = endSelY
|
|
else
|
|
sy = endSelY
|
|
ey = startSelY
|
|
end
|
|
elseif startSelX > endSelX and startSelY >= endSelY then
|
|
sx = endSelX
|
|
ex = startSelX
|
|
if startSelY > endSelY then
|
|
sy = endSelY
|
|
ey = startSelY
|
|
else
|
|
sy = startSelY
|
|
ey = endSelY
|
|
end
|
|
elseif startSelY > endSelY then
|
|
sx = endSelX
|
|
ex = startSelX
|
|
sy = endSelY
|
|
ey = startSelY
|
|
end
|
|
return sx, ex, sy, ey
|
|
end
|
|
end
|
|
|
|
local function removeSelection(self)
|
|
local sx, ex, sy, ey = getSelectionCoordinates()
|
|
local startLine = lines[sy]
|
|
local endLine = lines[ey]
|
|
lines[sy] = startLine:sub(1, sx - 1) .. endLine:sub(ex + 1, endLine:len())
|
|
bgLines[sy] = bgLines[sy]:sub(1, sx - 1) .. bgLines[ey]:sub(ex + 1, bgLines[ey]:len())
|
|
fgLines[sy] = fgLines[sy]:sub(1, sx - 1) .. fgLines[ey]:sub(ex + 1, fgLines[ey]:len())
|
|
|
|
for i = ey, sy + 1, -1 do
|
|
if i ~= sy then
|
|
table.remove(lines, i)
|
|
table.remove(bgLines, i)
|
|
table.remove(fgLines, i)
|
|
end
|
|
end
|
|
|
|
textX, textY = sx, sy
|
|
startSelX, endSelX, startSelY, endSelY = nil, nil, nil, nil
|
|
return self
|
|
end
|
|
|
|
local function stringGetPositions(str, word)
|
|
local pos = {}
|
|
if(str:len()>0)then
|
|
for w in gmatch(str, word)do
|
|
local s, e = find(str, w)
|
|
if(s~=nil)and(e~=nil)then
|
|
table.insert(pos,s)
|
|
table.insert(pos,e)
|
|
local startL = sub(str, 1, (s-1))
|
|
local endL = sub(str, e+1, str:len())
|
|
str = startL..(":"):rep(w:len())..endL
|
|
end
|
|
end
|
|
end
|
|
return pos
|
|
end
|
|
|
|
local function updateColors(self, l)
|
|
l = l or textY
|
|
local fgLine = tHex[self:getForeground()]:rep(fgLines[l]:len())
|
|
local bgLine = tHex[self:getBackground()]:rep(bgLines[l]:len())
|
|
for k,v in pairs(rules)do
|
|
local pos = stringGetPositions(lines[l], v[1])
|
|
if(#pos>0)then
|
|
for x=1,#pos/2 do
|
|
local xP = x*2 - 1
|
|
if(v[2]~=nil)then
|
|
fgLine = fgLine:sub(1, pos[xP]-1)..tHex[v[2]]:rep(pos[xP+1]-(pos[xP]-1))..fgLine:sub(pos[xP+1]+1, fgLine:len())
|
|
end
|
|
if(v[3]~=nil)then
|
|
bgLine = bgLine:sub(1, pos[xP]-1)..tHex[v[3]]:rep(pos[xP+1]-(pos[xP]-1))..bgLine:sub(pos[xP+1]+1, bgLine:len())
|
|
end
|
|
end
|
|
end
|
|
end
|
|
for k,v in pairs(keyWords)do
|
|
for _,b in pairs(v)do
|
|
local pos = stringGetPositions(lines[l], b)
|
|
if(#pos>0)then
|
|
for x=1,#pos/2 do
|
|
local xP = x*2 - 1
|
|
fgLine = fgLine:sub(1, pos[xP]-1)..tHex[k]:rep(pos[xP+1]-(pos[xP]-1))..fgLine:sub(pos[xP+1]+1, fgLine:len())
|
|
end
|
|
end
|
|
end
|
|
end
|
|
fgLines[l] = fgLine
|
|
bgLines[l] = bgLine
|
|
self:updateDraw()
|
|
end
|
|
|
|
local function updateAllColors(self)
|
|
for n=1,#lines do
|
|
updateColors(self, n)
|
|
end
|
|
end
|
|
|
|
local object = {
|
|
getType = function(self)
|
|
return objectType
|
|
end;
|
|
|
|
setBackground = function(self, bg)
|
|
base.setBackground(self, bg)
|
|
updateAllColors(self)
|
|
return self
|
|
end,
|
|
|
|
setForeground = function(self, fg)
|
|
base.setForeground(self, fg)
|
|
updateAllColors(self)
|
|
return self
|
|
end,
|
|
|
|
setSelection = function(self, fg, bg)
|
|
selectionFG = fg or selectionFG
|
|
selectionBG = bg or selectionBG
|
|
return self
|
|
end,
|
|
|
|
setSelectionFG = function(self, fg)
|
|
return self:setSelection(fg, nil)
|
|
end,
|
|
|
|
setSelectionBG = function(self, bg)
|
|
return self:setSelection(nil, bg)
|
|
end,
|
|
|
|
getSelection = function(self)
|
|
return selectionFG, selectionBG
|
|
end,
|
|
|
|
getSelectionFG = function(self)
|
|
return selectionFG
|
|
end,
|
|
|
|
getSelectionBG = function(self)
|
|
return selectionBG
|
|
end,
|
|
|
|
getLines = function(self)
|
|
return lines
|
|
end,
|
|
|
|
getLine = function(self, index)
|
|
return lines[index]
|
|
end,
|
|
|
|
editLine = function(self, index, text)
|
|
lines[index] = text or lines[index]
|
|
updateColors(self, index)
|
|
self:updateDraw()
|
|
return self
|
|
end,
|
|
|
|
clear = function(self)
|
|
lines = {""}
|
|
bgLines = {""}
|
|
fgLines = {""}
|
|
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
|
|
hIndex, wIndex, textX, textY = 1, 1, 1, 1
|
|
self:updateDraw()
|
|
return self
|
|
end,
|
|
|
|
addLine = function(self, text, index)
|
|
if(text~=nil)then
|
|
local bgColor = self:getBackground()
|
|
local fgColor = self:getForeground()
|
|
if(#lines==1)and(lines[1]=="")then
|
|
lines[1] = text
|
|
bgLines[1] = tHex[bgColor]:rep(text:len())
|
|
fgLines[1] = tHex[fgColor]:rep(text:len())
|
|
updateColors(self, 1)
|
|
return self
|
|
end
|
|
if (index ~= nil) then
|
|
table.insert(lines, index, text)
|
|
table.insert(bgLines, index, tHex[bgColor]:rep(text:len()))
|
|
table.insert(fgLines, index, tHex[fgColor]:rep(text:len()))
|
|
else
|
|
table.insert(lines, text)
|
|
table.insert(bgLines, tHex[bgColor]:rep(text:len()))
|
|
table.insert(fgLines, tHex[fgColor]:rep(text:len()))
|
|
end
|
|
end
|
|
updateColors(self, index or #lines)
|
|
self:updateDraw()
|
|
return self
|
|
end;
|
|
|
|
addKeywords = function(self, color, tab)
|
|
if(keyWords[color]==nil)then
|
|
keyWords[color] = {}
|
|
end
|
|
for k,v in pairs(tab)do
|
|
table.insert(keyWords[color], v)
|
|
end
|
|
self:updateDraw()
|
|
return self
|
|
end;
|
|
|
|
addRule = function(self, rule, fg, bg)
|
|
table.insert(rules, {rule, fg, bg})
|
|
self:updateDraw()
|
|
return self
|
|
end;
|
|
|
|
editRule = function(self, rule, fg, bg)
|
|
for k,v in pairs(rules)do
|
|
if(v[1]==rule)then
|
|
rules[k][2] = fg
|
|
rules[k][3] = bg
|
|
end
|
|
end
|
|
self:updateDraw()
|
|
return self
|
|
end;
|
|
|
|
removeRule = function(self, rule)
|
|
for k,v in pairs(rules)do
|
|
if(v[1]==rule)then
|
|
table.remove(rules, k)
|
|
end
|
|
end
|
|
self:updateDraw()
|
|
return self
|
|
end,
|
|
|
|
setKeywords = function(self, color, tab)
|
|
keyWords[color] = tab
|
|
self:updateDraw()
|
|
return self
|
|
end,
|
|
|
|
removeLine = function(self, index)
|
|
if(#lines>1)then
|
|
table.remove(lines, index or #lines)
|
|
table.remove(bgLines, index or #bgLines)
|
|
table.remove(fgLines, index or #fgLines)
|
|
else
|
|
lines = {""}
|
|
bgLines = {""}
|
|
fgLines = {""}
|
|
end
|
|
self:updateDraw()
|
|
return self
|
|
end,
|
|
|
|
getTextCursor = function(self)
|
|
return textX, textY
|
|
end,
|
|
|
|
getOffset = function(self)
|
|
return wIndex, hIndex
|
|
end,
|
|
|
|
setOffset = function(self, xOff, yOff)
|
|
wIndex = xOff or wIndex
|
|
hIndex = yOff or hIndex
|
|
self:updateDraw()
|
|
return self
|
|
end,
|
|
|
|
getXOffset = function(self)
|
|
return wIndex
|
|
end,
|
|
|
|
setXOffset = function(self, xOff)
|
|
return self:setOffset(xOff, nil)
|
|
end,
|
|
|
|
getYOffset = function(self)
|
|
return hIndex
|
|
end,
|
|
|
|
setYOffset = function(self, yOff)
|
|
return self:setOffset(nil, yOff)
|
|
end,
|
|
|
|
getFocusHandler = function(self)
|
|
base.getFocusHandler(self)
|
|
local obx, oby = self:getPosition()
|
|
self:getParent():setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self:getForeground())
|
|
end,
|
|
|
|
loseFocusHandler = function(self)
|
|
base.loseFocusHandler(self)
|
|
self:getParent():setCursor(false)
|
|
end,
|
|
|
|
keyHandler = function(self, key)
|
|
if (base.keyHandler(self, key)) then
|
|
local parent = self:getParent()
|
|
local obx, oby = self:getPosition()
|
|
local w,h = self:getSize()
|
|
if (key == keys.backspace) then
|
|
-- on backspace
|
|
if(isSelected())then
|
|
removeSelection(self)
|
|
else
|
|
if (lines[textY] == "") then
|
|
if (textY > 1) then
|
|
table.remove(lines, textY)
|
|
table.remove(fgLines, textY)
|
|
table.remove(bgLines, textY)
|
|
textX = lines[textY - 1]:len() + 1
|
|
wIndex = textX - w + 1
|
|
if (wIndex < 1) then
|
|
wIndex = 1
|
|
end
|
|
textY = textY - 1
|
|
end
|
|
elseif (textX <= 1) then
|
|
if (textY > 1) then
|
|
textX = lines[textY - 1]:len() + 1
|
|
wIndex = textX - w + 1
|
|
if (wIndex < 1) then
|
|
wIndex = 1
|
|
end
|
|
lines[textY - 1] = lines[textY - 1] .. lines[textY]
|
|
fgLines[textY - 1] = fgLines[textY - 1] .. fgLines[textY]
|
|
bgLines[textY - 1] = bgLines[textY - 1] .. bgLines[textY]
|
|
table.remove(lines, textY)
|
|
table.remove(fgLines, textY)
|
|
table.remove(bgLines, textY)
|
|
textY = textY - 1
|
|
end
|
|
else
|
|
lines[textY] = lines[textY]:sub(1, textX - 2) .. lines[textY]:sub(textX, lines[textY]:len())
|
|
fgLines[textY] = fgLines[textY]:sub(1, textX - 2) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
|
|
bgLines[textY] = bgLines[textY]:sub(1, textX - 2) .. bgLines[textY]:sub(textX, bgLines[textY]:len())
|
|
if (textX > 1) then
|
|
textX = textX - 1
|
|
end
|
|
if (wIndex > 1) then
|
|
if (textX < wIndex) then
|
|
wIndex = wIndex - 1
|
|
end
|
|
end
|
|
end
|
|
if (textY < hIndex) then
|
|
hIndex = hIndex - 1
|
|
end
|
|
end
|
|
updateColors(self)
|
|
self:setValue("")
|
|
elseif (key == keys.delete) then
|
|
-- on delete
|
|
if(isSelected())then
|
|
removeSelection(self)
|
|
else
|
|
if (textX > lines[textY]:len()) then
|
|
if (lines[textY + 1] ~= nil) then
|
|
lines[textY] = lines[textY] .. lines[textY + 1]
|
|
table.remove(lines, textY + 1)
|
|
table.remove(bgLines, textY + 1)
|
|
table.remove(fgLines, textY + 1)
|
|
end
|
|
else
|
|
lines[textY] = lines[textY]:sub(1, textX - 1) .. lines[textY]:sub(textX + 1, lines[textY]:len())
|
|
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. fgLines[textY]:sub(textX + 1, fgLines[textY]:len())
|
|
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. bgLines[textY]:sub(textX + 1, bgLines[textY]:len())
|
|
end
|
|
end
|
|
updateColors(self)
|
|
elseif (key == keys.enter) then
|
|
if(isSelected())then
|
|
removeSelection(self)
|
|
end
|
|
-- on enter
|
|
table.insert(lines, textY + 1, lines[textY]:sub(textX, lines[textY]:len()))
|
|
table.insert(fgLines, textY + 1, fgLines[textY]:sub(textX, fgLines[textY]:len()))
|
|
table.insert(bgLines, textY + 1, bgLines[textY]:sub(textX, bgLines[textY]:len()))
|
|
lines[textY] = lines[textY]:sub(1, textX - 1)
|
|
fgLines[textY] = fgLines[textY]:sub(1, textX - 1)
|
|
bgLines[textY] = bgLines[textY]:sub(1, textX - 1)
|
|
textY = textY + 1
|
|
textX = 1
|
|
wIndex = 1
|
|
if (textY - hIndex >= h) then
|
|
hIndex = hIndex + 1
|
|
end
|
|
self:setValue("")
|
|
elseif (key == keys.up) then
|
|
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
|
|
-- arrow up
|
|
if (textY > 1) then
|
|
textY = textY - 1
|
|
if (textX > lines[textY]:len() + 1) then
|
|
textX = lines[textY]:len() + 1
|
|
end
|
|
if (wIndex > 1) then
|
|
if (textX < wIndex) then
|
|
wIndex = textX - w + 1
|
|
if (wIndex < 1) then
|
|
wIndex = 1
|
|
end
|
|
end
|
|
end
|
|
if (hIndex > 1) then
|
|
if (textY < hIndex) then
|
|
hIndex = hIndex - 1
|
|
end
|
|
end
|
|
end
|
|
elseif (key == keys.down) then
|
|
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
|
|
-- arrow down
|
|
if (textY < #lines) then
|
|
textY = textY + 1
|
|
if (textX > lines[textY]:len() + 1) then
|
|
textX = lines[textY]:len() + 1
|
|
end
|
|
if (wIndex > 1) then
|
|
if (textX < wIndex) then
|
|
wIndex = textX - w + 1
|
|
if (wIndex < 1) then
|
|
wIndex = 1
|
|
end
|
|
end
|
|
end
|
|
if (textY >= hIndex + h) then
|
|
hIndex = hIndex + 1
|
|
end
|
|
end
|
|
elseif (key == keys.right) then
|
|
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
|
|
-- arrow right
|
|
textX = textX + 1
|
|
if (textY < #lines) then
|
|
if (textX > lines[textY]:len() + 1) then
|
|
textX = 1
|
|
textY = textY + 1
|
|
end
|
|
elseif (textX > lines[textY]:len()) then
|
|
textX = lines[textY]:len() + 1
|
|
end
|
|
if (textX < 1) then
|
|
textX = 1
|
|
end
|
|
if (textX < wIndex) or (textX >= w + wIndex) then
|
|
wIndex = textX - w + 1
|
|
end
|
|
if (wIndex < 1) then
|
|
wIndex = 1
|
|
end
|
|
|
|
elseif (key == keys.left) then
|
|
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
|
|
-- arrow left
|
|
textX = textX - 1
|
|
if (textX >= 1) then
|
|
if (textX < wIndex) or (textX >= w + wIndex) then
|
|
wIndex = textX
|
|
end
|
|
end
|
|
if (textY > 1) then
|
|
if (textX < 1) then
|
|
textY = textY - 1
|
|
textX = lines[textY]:len() + 1
|
|
wIndex = textX - w + 1
|
|
end
|
|
end
|
|
if (textX < 1) then
|
|
textX = 1
|
|
end
|
|
if (wIndex < 1) then
|
|
wIndex = 1
|
|
end
|
|
elseif(key == keys.tab)then
|
|
if(textX % 3 == 0 )then
|
|
lines[textY] = lines[textY]:sub(1, textX - 1) .. " " .. lines[textY]:sub(textX, lines[textY]:len())
|
|
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self:getForeground()] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
|
|
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self:getBackground()] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
|
|
textX = textX + 1
|
|
end
|
|
while textX % 3 ~= 0 do
|
|
lines[textY] = lines[textY]:sub(1, textX - 1) .. " " .. lines[textY]:sub(textX, lines[textY]:len())
|
|
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self:getForeground()] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
|
|
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self:getBackground()] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
|
|
textX = textX + 1
|
|
end
|
|
end
|
|
|
|
if not((obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h)) then
|
|
wIndex = math.max(1, lines[textY]:len()-w+1)
|
|
hIndex = math.max(1, textY - h + 1)
|
|
end
|
|
|
|
local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1)
|
|
if (cursorX > self:getX() + w - 1) then
|
|
cursorX = self:getX() + w - 1
|
|
end
|
|
local cursorY = (textY - hIndex < h and textY - hIndex or textY - hIndex - 1)
|
|
if (cursorX < 1) then
|
|
cursorX = 0
|
|
end
|
|
parent:setCursor(true, obx + cursorX, oby + cursorY, self:getForeground())
|
|
self:updateDraw()
|
|
return true
|
|
end
|
|
end,
|
|
|
|
charHandler = function(self, char)
|
|
if(base.charHandler(self, char))then
|
|
local parent = self:getParent()
|
|
local obx, oby = self:getPosition()
|
|
local w,h = self:getSize()
|
|
if(isSelected())then
|
|
removeSelection(self)
|
|
end
|
|
lines[textY] = lines[textY]:sub(1, textX - 1) .. char .. lines[textY]:sub(textX, lines[textY]:len())
|
|
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self:getForeground()] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
|
|
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self:getBackground()] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
|
|
textX = textX + 1
|
|
if (textX >= w + wIndex) then
|
|
wIndex = wIndex + 1
|
|
end
|
|
updateColors(self)
|
|
self:setValue("")
|
|
|
|
if not((obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h)) then
|
|
wIndex = math.max(1, lines[textY]:len()-w+1)
|
|
hIndex = math.max(1, textY - h + 1)
|
|
end
|
|
|
|
local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1)
|
|
if (cursorX > self:getX() + w - 1) then
|
|
cursorX = self:getX() + w - 1
|
|
end
|
|
local cursorY = (textY - hIndex < h and textY - hIndex or textY - hIndex - 1)
|
|
if (cursorX < 1) then
|
|
cursorX = 0
|
|
end
|
|
parent:setCursor(true, obx + cursorX, oby + cursorY, self:getForeground())
|
|
self:updateDraw()
|
|
return true
|
|
end
|
|
end,
|
|
|
|
dragHandler = function(self, button, x, y)
|
|
if (base.dragHandler(self, button, x, y)) then
|
|
local parent = self:getParent()
|
|
local obx, oby = self:getAbsolutePosition()
|
|
local ox, oy = self:getPosition()
|
|
local w,h = self:getSize()
|
|
if (lines[y - oby + hIndex] ~= nil) then
|
|
if(x - obx + wIndex > 0)and(x - obx + wIndex <= w)then
|
|
textX = x - obx + wIndex
|
|
textY = y - oby + hIndex
|
|
|
|
if textX > lines[textY]:len() then
|
|
textX = lines[textY]:len() + 1
|
|
end
|
|
endSelX = textX
|
|
endSelY = textY
|
|
|
|
if textX < wIndex then
|
|
wIndex = textX - 1
|
|
if wIndex < 1 then
|
|
wIndex = 1
|
|
end
|
|
end
|
|
parent:setCursor(not isSelected(), ox + textX - wIndex, oy + textY - hIndex, self:getForeground())
|
|
self:updateDraw()
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
end,
|
|
|
|
scrollHandler = function(self, dir, x, y)
|
|
if (base.scrollHandler(self, dir, x, y)) then
|
|
local parent = self:getParent()
|
|
local obx, oby = self:getAbsolutePosition()
|
|
local anchx, anchy = self:getPosition()
|
|
local w,h = self:getSize()
|
|
hIndex = hIndex + dir
|
|
if (hIndex > #lines - (h - 1)) then
|
|
hIndex = #lines - (h - 1)
|
|
end
|
|
|
|
if (hIndex < 1) then
|
|
hIndex = 1
|
|
end
|
|
|
|
if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (anchy + textY - hIndex >= anchy and anchy + textY - hIndex < anchy + h) then
|
|
parent:setCursor(not isSelected(), anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
|
|
else
|
|
parent:setCursor(false)
|
|
end
|
|
self:updateDraw()
|
|
return true
|
|
end
|
|
end,
|
|
|
|
mouseHandler = function(self, button, x, y)
|
|
if (base.mouseHandler(self, button, x, y)) then
|
|
local parent = self:getParent()
|
|
local obx, oby = self:getAbsolutePosition()
|
|
local anchx, anchy = self:getPosition()
|
|
if (lines[y - oby + hIndex] ~= nil) then
|
|
textX = x - obx + wIndex
|
|
textY = y - oby + hIndex
|
|
endSelX = nil
|
|
endSelY = nil
|
|
startSelX = textX
|
|
startSelY = textY
|
|
if (textX > lines[textY]:len()) then
|
|
textX = lines[textY]:len() + 1
|
|
startSelX = textX
|
|
end
|
|
if (textX < wIndex) then
|
|
wIndex = textX - 1
|
|
if (wIndex < 1) then
|
|
wIndex = 1
|
|
end
|
|
end
|
|
self:updateDraw()
|
|
end
|
|
parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
|
|
return true
|
|
end
|
|
end,
|
|
|
|
mouseUpHandler = function(self, button, x, y)
|
|
if (base.mouseUpHandler(self, button, x, y)) then
|
|
local obx, oby = self:getAbsolutePosition()
|
|
if (lines[y - oby + hIndex] ~= nil) then
|
|
endSelX = x - obx + wIndex
|
|
endSelY = y - oby + hIndex
|
|
if (endSelX > lines[endSelY]:len()) then
|
|
endSelX = lines[endSelY]:len() + 1
|
|
end
|
|
if(startSelX==endSelX)and(startSelY==endSelY)then
|
|
startSelX, endSelX, startSelY, endSelY = nil, nil, nil, nil
|
|
end
|
|
self:updateDraw()
|
|
end
|
|
return true
|
|
end
|
|
end,
|
|
|
|
eventHandler = function(self, event, paste, ...)
|
|
base.eventHandler(self, event, paste, ...)
|
|
if(event=="paste")then
|
|
if(self:isFocused())then
|
|
local parent = self:getParent()
|
|
local fgColor, bgColor = self:getForeground(), self:getBackground()
|
|
local w, h = self:getSize()
|
|
lines[textY] = lines[textY]:sub(1, textX - 1) .. paste .. lines[textY]:sub(textX, lines[textY]:len())
|
|
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[fgColor]:rep(paste:len()) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
|
|
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[bgColor]:rep(paste:len()) .. bgLines[textY]:sub(textX, bgLines[textY]:len())
|
|
textX = textX + paste:len()
|
|
if (textX >= w + wIndex) then
|
|
wIndex = (textX+1)-w
|
|
end
|
|
local anchx, anchy = self:getPosition()
|
|
parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, fgColor)
|
|
updateColors(self)
|
|
self:updateDraw()
|
|
end
|
|
end
|
|
end,
|
|
|
|
draw = function(self)
|
|
base.draw(self)
|
|
self:addDraw("textfield", function()
|
|
local w, h = self:getSize()
|
|
local bgColor = tHex[self:getBackground()]
|
|
local fgColor = tHex[self:getForeground()]
|
|
|
|
for n = 1, h do
|
|
local text = ""
|
|
local bg = ""
|
|
local fg = ""
|
|
if lines[n + hIndex - 1] then
|
|
text = lines[n + hIndex - 1]
|
|
fg = fgLines[n + hIndex - 1]
|
|
bg = bgLines[n + hIndex - 1]
|
|
end
|
|
|
|
text = sub(text, wIndex, w + wIndex - 1)
|
|
bg = rep(bgColor, w)
|
|
fg = rep(fgColor, w)
|
|
|
|
self:addText(1, n, text)
|
|
self:addBG(1, n, bg)
|
|
self:addFG(1, n, fg)
|
|
self:addBlit(1, n, text, fg, bg)
|
|
end
|
|
|
|
if startSelX and endSelX and startSelY and endSelY then
|
|
local sx, ex, sy, ey = getSelectionCoordinates()
|
|
for n = sy, ey do
|
|
local line = #lines[n]
|
|
local xOffset = 0
|
|
if n == sy and n == ey then
|
|
xOffset = sx - 1 - (wIndex - 1)
|
|
line = line - (sx - 1 - (wIndex - 1)) - (line - ex + (wIndex - 1))
|
|
elseif n == ey then
|
|
line = line - (line - ex + (wIndex - 1))
|
|
elseif n == sy then
|
|
line = line - (sx - 1)
|
|
xOffset = sx - 1 - (wIndex - 1)
|
|
end
|
|
|
|
local visible_line_length = math.min(line, w - xOffset)
|
|
|
|
self:addBG(1 + xOffset, n, rep(tHex[selectionBG], visible_line_length))
|
|
self:addFG(1 + xOffset, n, rep(tHex[selectionFG], visible_line_length))
|
|
end
|
|
end
|
|
end)
|
|
end,
|
|
|
|
load = function(self)
|
|
self:listenEvent("mouse_click")
|
|
self:listenEvent("mouse_up")
|
|
self:listenEvent("mouse_scroll")
|
|
self:listenEvent("mouse_drag")
|
|
self:listenEvent("key")
|
|
self:listenEvent("char")
|
|
self:listenEvent("other_event")
|
|
end,
|
|
}
|
|
|
|
object.__index = object
|
|
return setmetatable(object, base)
|
|
end |