Update Program.lua
This commit is contained in:
@@ -1,84 +1,808 @@
|
||||
local processes = {}
|
||||
local process = {}
|
||||
local processId = 0
|
||||
local Object = require("Object")
|
||||
local tHex = require("tHex")
|
||||
local process = require("process")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
|
||||
local newPackage = dofile("rom/modules/main/cc/require.lua").make
|
||||
local sub = string.sub
|
||||
|
||||
function process:new(path, window, newEnv, ...)
|
||||
local args = {...}
|
||||
local newP = setmetatable({ path = path }, { __index = self })
|
||||
newP.window = window
|
||||
window.current = term.current
|
||||
window.redirect = term.redirect
|
||||
newP.processId = processId
|
||||
if(type(path)=="string")then
|
||||
newP.coroutine = coroutine.create(function()
|
||||
local pPath = shell.resolveProgram(path)
|
||||
local env = setmetatable(newEnv, {__index=_ENV})
|
||||
env.shell = shell
|
||||
env.basaltProgram=true
|
||||
env.require, env.package = newPackage(env, fs.getDir(pPath))
|
||||
if(fs.exists(pPath))then
|
||||
local file = fs.open(pPath, "r")
|
||||
local content = file.readAll()
|
||||
file.close()
|
||||
local program = load(content, path, "bt", env)
|
||||
if(program~=nil)then
|
||||
return program(table.unpack(args))
|
||||
return function(name, parent)
|
||||
local base = Object(name)
|
||||
local objectType = "Program"
|
||||
base:setZIndex(5)
|
||||
local object
|
||||
local cachedPath
|
||||
local enviroment = {}
|
||||
|
||||
local function createBasaltWindow(x, y, width, height, self)
|
||||
local xCursor, yCursor = 1, 1
|
||||
local bgColor, fgColor = colors.black, colors.white
|
||||
local cursorBlink = false
|
||||
local visible = false
|
||||
|
||||
local cacheT = {}
|
||||
local cacheBG = {}
|
||||
local cacheFG = {}
|
||||
|
||||
local tPalette = {}
|
||||
|
||||
local emptySpaceLine
|
||||
local emptyColorLines = {}
|
||||
|
||||
for i = 0, 15 do
|
||||
local c = 2 ^ i
|
||||
tPalette[c] = { parent:getBasaltInstance().getBaseTerm().getPaletteColour(c) }
|
||||
end
|
||||
|
||||
local function createEmptyLines()
|
||||
emptySpaceLine = (" "):rep(width)
|
||||
for n = 0, 15 do
|
||||
local nColor = 2 ^ n
|
||||
local sHex = tHex[nColor]
|
||||
emptyColorLines[nColor] = sHex:rep(width)
|
||||
end
|
||||
end
|
||||
end)
|
||||
elseif(type(path)=="function")then
|
||||
newP.coroutine = coroutine.create(function()
|
||||
path(table.unpack(args))
|
||||
end)
|
||||
else
|
||||
return
|
||||
end
|
||||
processes[processId] = newP
|
||||
processId = processId + 1
|
||||
return newP
|
||||
end
|
||||
|
||||
function process:resume(event, ...)
|
||||
local cur = term.current()
|
||||
term.redirect(self.window)
|
||||
if(self.filter~=nil)then
|
||||
if(event~=self.filter)then return end
|
||||
self.filter=nil
|
||||
end
|
||||
local ok, result = coroutine.resume(self.coroutine, event, ...)
|
||||
|
||||
if ok then
|
||||
self.filter = result
|
||||
else
|
||||
printError(result)
|
||||
end
|
||||
term.redirect(cur)
|
||||
return ok, result
|
||||
end
|
||||
|
||||
function process:isDead()
|
||||
if (self.coroutine ~= nil) then
|
||||
if (coroutine.status(self.coroutine) == "dead") then
|
||||
table.remove(processes, self.processId)
|
||||
return true
|
||||
local function recreateWindowArray()
|
||||
createEmptyLines()
|
||||
local emptyText = emptySpaceLine
|
||||
local emptyFG = emptyColorLines[colors.white]
|
||||
local emptyBG = emptyColorLines[colors.black]
|
||||
for n = 1, height do
|
||||
cacheT[n] = sub(cacheT[n] == nil and emptyText or cacheT[n] .. emptyText:sub(1, width - cacheT[n]:len()), 1, width)
|
||||
cacheFG[n] = sub(cacheFG[n] == nil and emptyFG or cacheFG[n] .. emptyFG:sub(1, width - cacheFG[n]:len()), 1, width)
|
||||
cacheBG[n] = sub(cacheBG[n] == nil and emptyBG or cacheBG[n] .. emptyBG:sub(1, width - cacheBG[n]:len()), 1, width)
|
||||
end
|
||||
base.updateDraw(base)
|
||||
end
|
||||
else
|
||||
return true
|
||||
recreateWindowArray()
|
||||
|
||||
local function updateCursor()
|
||||
if xCursor >= 1 and yCursor >= 1 and xCursor <= width and yCursor <= height then
|
||||
--parentTerminal.setCursorPos(xCursor + x - 1, yCursor + y - 1)
|
||||
else
|
||||
--parentTerminal.setCursorPos(0, 0)
|
||||
end
|
||||
--parentTerminal.setTextColor(fgColor)
|
||||
end
|
||||
|
||||
local function internalBlit(sText, sTextColor, sBackgroundColor)
|
||||
-- copy pasti strikes again (cc: window.lua)
|
||||
local nStart = xCursor
|
||||
local nEnd = nStart + #sText - 1
|
||||
if yCursor >= 1 and yCursor <= height then
|
||||
if nStart <= width and nEnd >= 1 then
|
||||
-- Modify line
|
||||
if nStart == 1 and nEnd == width then
|
||||
cacheT[yCursor] = sText
|
||||
cacheFG[yCursor] = sTextColor
|
||||
cacheBG[yCursor] = sBackgroundColor
|
||||
else
|
||||
local sClippedText, sClippedTextColor, sClippedBackgroundColor
|
||||
if nStart < 1 then
|
||||
local nClipStart = 1 - nStart + 1
|
||||
local nClipEnd = width - nStart + 1
|
||||
sClippedText = sub(sText, nClipStart, nClipEnd)
|
||||
sClippedTextColor = sub(sTextColor, nClipStart, nClipEnd)
|
||||
sClippedBackgroundColor = sub(sBackgroundColor, nClipStart, nClipEnd)
|
||||
elseif nEnd > width then
|
||||
local nClipEnd = width - nStart + 1
|
||||
sClippedText = sub(sText, 1, nClipEnd)
|
||||
sClippedTextColor = sub(sTextColor, 1, nClipEnd)
|
||||
sClippedBackgroundColor = sub(sBackgroundColor, 1, nClipEnd)
|
||||
else
|
||||
sClippedText = sText
|
||||
sClippedTextColor = sTextColor
|
||||
sClippedBackgroundColor = sBackgroundColor
|
||||
end
|
||||
|
||||
local sOldText = cacheT[yCursor]
|
||||
local sOldTextColor = cacheFG[yCursor]
|
||||
local sOldBackgroundColor = cacheBG[yCursor]
|
||||
local sNewText, sNewTextColor, sNewBackgroundColor
|
||||
if nStart > 1 then
|
||||
local nOldEnd = nStart - 1
|
||||
sNewText = sub(sOldText, 1, nOldEnd) .. sClippedText
|
||||
sNewTextColor = sub(sOldTextColor, 1, nOldEnd) .. sClippedTextColor
|
||||
sNewBackgroundColor = sub(sOldBackgroundColor, 1, nOldEnd) .. sClippedBackgroundColor
|
||||
else
|
||||
sNewText = sClippedText
|
||||
sNewTextColor = sClippedTextColor
|
||||
sNewBackgroundColor = sClippedBackgroundColor
|
||||
end
|
||||
if nEnd < width then
|
||||
local nOldStart = nEnd + 1
|
||||
sNewText = sNewText .. sub(sOldText, nOldStart, width)
|
||||
sNewTextColor = sNewTextColor .. sub(sOldTextColor, nOldStart, width)
|
||||
sNewBackgroundColor = sNewBackgroundColor .. sub(sOldBackgroundColor, nOldStart, width)
|
||||
end
|
||||
|
||||
cacheT[yCursor] = sNewText
|
||||
cacheFG[yCursor] = sNewTextColor
|
||||
cacheBG[yCursor] = sNewBackgroundColor
|
||||
end
|
||||
object:updateDraw()
|
||||
end
|
||||
xCursor = nEnd + 1
|
||||
if (visible) then
|
||||
updateCursor()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function setText(_x, _y, text)
|
||||
if (text ~= nil) then
|
||||
local gText = cacheT[_y]
|
||||
if (gText ~= nil) then
|
||||
cacheT[_y] = sub(gText:sub(1, _x - 1) .. text .. gText:sub(_x + (text:len()), width), 1, width)
|
||||
end
|
||||
end
|
||||
object:updateDraw()
|
||||
end
|
||||
|
||||
local function setBG(_x, _y, colorStr)
|
||||
if (colorStr ~= nil) then
|
||||
local gBG = cacheBG[_y]
|
||||
if (gBG ~= nil) then
|
||||
cacheBG[_y] = sub(gBG:sub(1, _x - 1) .. colorStr .. gBG:sub(_x + (colorStr:len()), width), 1, width)
|
||||
end
|
||||
end
|
||||
object:updateDraw()
|
||||
end
|
||||
|
||||
local function setFG(_x, _y, colorStr)
|
||||
if (colorStr ~= nil) then
|
||||
local gFG = cacheFG[_y]
|
||||
if (gFG ~= nil) then
|
||||
cacheFG[_y] = sub(gFG:sub(1, _x - 1) .. colorStr .. gFG:sub(_x + (colorStr:len()), width), 1, width)
|
||||
end
|
||||
end
|
||||
object:updateDraw()
|
||||
end
|
||||
|
||||
local setTextColor = function(color)
|
||||
if type(color) ~= "number" then
|
||||
error("bad argument #1 (expected number, got " .. type(color) .. ")", 2)
|
||||
elseif tHex[color] == nil then
|
||||
error("Invalid color (got " .. color .. ")", 2)
|
||||
end
|
||||
fgColor = color
|
||||
end
|
||||
|
||||
local setBackgroundColor = function(color)
|
||||
if type(color) ~= "number" then
|
||||
error("bad argument #1 (expected number, got " .. type(color) .. ")", 2)
|
||||
elseif tHex[color] == nil then
|
||||
error("Invalid color (got " .. color .. ")", 2)
|
||||
end
|
||||
bgColor = color
|
||||
end
|
||||
|
||||
local setPaletteColor = function(colour, r, g, b)
|
||||
-- have to work on
|
||||
if type(colour) ~= "number" then
|
||||
error("bad argument #1 (expected number, got " .. type(colour) .. ")", 2)
|
||||
end
|
||||
|
||||
if tHex[colour] == nil then
|
||||
error("Invalid color (got " .. colour .. ")", 2)
|
||||
end
|
||||
|
||||
local tCol
|
||||
if type(r) == "number" and g == nil and b == nil then
|
||||
tCol = { colours.rgb8(r) }
|
||||
tPalette[colour] = tCol
|
||||
else
|
||||
if type(r) ~= "number" then
|
||||
error("bad argument #2 (expected number, got " .. type(r) .. ")", 2)
|
||||
end
|
||||
if type(g) ~= "number" then
|
||||
error("bad argument #3 (expected number, got " .. type(g) .. ")", 2)
|
||||
end
|
||||
if type(b) ~= "number" then
|
||||
error("bad argument #4 (expected number, got " .. type(b) .. ")", 2)
|
||||
end
|
||||
|
||||
tCol = tPalette[colour]
|
||||
tCol[1] = r
|
||||
tCol[2] = g
|
||||
tCol[3] = b
|
||||
end
|
||||
end
|
||||
|
||||
local getPaletteColor = function(colour)
|
||||
if type(colour) ~= "number" then
|
||||
error("bad argument #1 (expected number, got " .. type(colour) .. ")", 2)
|
||||
end
|
||||
if tHex[colour] == nil then
|
||||
error("Invalid color (got " .. colour .. ")", 2)
|
||||
end
|
||||
local tCol = tPalette[colour]
|
||||
return tCol[1], tCol[2], tCol[3]
|
||||
end
|
||||
|
||||
local basaltwindow = {
|
||||
setCursorPos = function(_x, _y)
|
||||
if type(_x) ~= "number" then
|
||||
error("bad argument #1 (expected number, got " .. type(_x) .. ")", 2)
|
||||
end
|
||||
if type(_y) ~= "number" then
|
||||
error("bad argument #2 (expected number, got " .. type(_y) .. ")", 2)
|
||||
end
|
||||
xCursor = math.floor(_x)
|
||||
yCursor = math.floor(_y)
|
||||
if (visible) then
|
||||
updateCursor()
|
||||
end
|
||||
end;
|
||||
|
||||
getCursorPos = function()
|
||||
return xCursor, yCursor
|
||||
end;
|
||||
|
||||
setCursorBlink = function(blink)
|
||||
if type(blink) ~= "boolean" then
|
||||
error("bad argument #1 (expected boolean, got " .. type(blink) .. ")", 2)
|
||||
end
|
||||
cursorBlink = blink
|
||||
end;
|
||||
|
||||
getCursorBlink = function()
|
||||
return cursorBlink
|
||||
end;
|
||||
|
||||
|
||||
getPaletteColor = getPaletteColor,
|
||||
getPaletteColour = getPaletteColor,
|
||||
|
||||
setBackgroundColor = setBackgroundColor,
|
||||
setBackgroundColour = setBackgroundColor,
|
||||
|
||||
setTextColor = setTextColor,
|
||||
setTextColour = setTextColor,
|
||||
|
||||
setPaletteColor = setPaletteColor,
|
||||
setPaletteColour = setPaletteColor,
|
||||
|
||||
getBackgroundColor = function()
|
||||
return bgColor
|
||||
end;
|
||||
getBackgroundColour = function()
|
||||
return bgColor
|
||||
end;
|
||||
|
||||
getSize = function()
|
||||
return width, height
|
||||
end;
|
||||
|
||||
getTextColor = function()
|
||||
return fgColor
|
||||
end;
|
||||
getTextColour = function()
|
||||
return fgColor
|
||||
end;
|
||||
|
||||
basalt_resize = function(_width, _height)
|
||||
width, height = _width, _height
|
||||
recreateWindowArray()
|
||||
end;
|
||||
|
||||
basalt_reposition = function(_x, _y)
|
||||
x, y = _x, _y
|
||||
end;
|
||||
|
||||
basalt_setVisible = function(vis)
|
||||
visible = vis
|
||||
end;
|
||||
|
||||
drawBackgroundBox = function(_x, _y, _width, _height, bgCol)
|
||||
for n = 1, _height do
|
||||
setBG(_x, _y + (n - 1), tHex[bgCol]:rep(_width))
|
||||
end
|
||||
end;
|
||||
drawForegroundBox = function(_x, _y, _width, _height, fgCol)
|
||||
for n = 1, _height do
|
||||
setFG(_x, _y + (n - 1), tHex[fgCol]:rep(_width))
|
||||
end
|
||||
end;
|
||||
drawTextBox = function(_x, _y, _width, _height, symbol)
|
||||
for n = 1, _height do
|
||||
setText(_x, _y + (n - 1), symbol:rep(_width))
|
||||
end
|
||||
end;
|
||||
|
||||
writeText = function(_x, _y, text, bgCol, fgCol)
|
||||
bgCol = bgCol or bgColor
|
||||
fgCol = fgCol or fgColor
|
||||
setText(x, _y, text)
|
||||
setBG(_x, _y, tHex[bgCol]:rep(text:len()))
|
||||
setFG(_x, _y, tHex[fgCol]:rep(text:len()))
|
||||
end;
|
||||
|
||||
basalt_update = function()
|
||||
if (parent ~= nil) then
|
||||
for n = 1, height do
|
||||
parent:setText(x, y + (n - 1), cacheT[n])
|
||||
parent:setBG(x, y + (n - 1), cacheBG[n])
|
||||
parent:setFG(x, y + (n - 1), cacheFG[n])
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
scroll = function(offset)
|
||||
if type(offset) ~= "number" then
|
||||
error("bad argument #1 (expected number, got " .. type(offset) .. ")", 2)
|
||||
end
|
||||
if offset ~= 0 then
|
||||
local sEmptyText = emptySpaceLine
|
||||
local sEmptyTextColor = emptyColorLines[fgColor]
|
||||
local sEmptyBackgroundColor = emptyColorLines[bgColor]
|
||||
for newY = 1, height do
|
||||
local y = newY + offset
|
||||
if y >= 1 and y <= height then
|
||||
cacheT[newY] = cacheT[y]
|
||||
cacheBG[newY] = cacheBG[y]
|
||||
cacheFG[newY] = cacheFG[y]
|
||||
else
|
||||
cacheT[newY] = sEmptyText
|
||||
cacheFG[newY] = sEmptyTextColor
|
||||
cacheBG[newY] = sEmptyBackgroundColor
|
||||
end
|
||||
end
|
||||
end
|
||||
if (visible) then
|
||||
updateCursor()
|
||||
end
|
||||
end;
|
||||
|
||||
|
||||
isColor = function()
|
||||
return parent:getBasaltInstance().getBaseTerm().isColor()
|
||||
end;
|
||||
|
||||
isColour = function()
|
||||
return parent:getBasaltInstance().getBaseTerm().isColor()
|
||||
end;
|
||||
|
||||
write = function(text)
|
||||
text = tostring(text)
|
||||
if (visible) then
|
||||
internalBlit(text, tHex[fgColor]:rep(text:len()), tHex[bgColor]:rep(text:len()))
|
||||
end
|
||||
end;
|
||||
|
||||
clearLine = function()
|
||||
if (visible) then
|
||||
setText(1, yCursor, (" "):rep(width))
|
||||
setBG(1, yCursor, tHex[bgColor]:rep(width))
|
||||
setFG(1, yCursor, tHex[fgColor]:rep(width))
|
||||
end
|
||||
if (visible) then
|
||||
updateCursor()
|
||||
end
|
||||
end;
|
||||
|
||||
clear = function()
|
||||
for n = 1, height do
|
||||
setText(1, n, (" "):rep(width))
|
||||
setBG(1, n, tHex[bgColor]:rep(width))
|
||||
setFG(1, n, tHex[fgColor]:rep(width))
|
||||
end
|
||||
if (visible) then
|
||||
updateCursor()
|
||||
end
|
||||
end;
|
||||
|
||||
blit = function(text, fgcol, bgcol)
|
||||
if type(text) ~= "string" then
|
||||
error("bad argument #1 (expected string, got " .. type(text) .. ")", 2)
|
||||
end
|
||||
if type(fgcol) ~= "string" then
|
||||
error("bad argument #2 (expected string, got " .. type(fgcol) .. ")", 2)
|
||||
end
|
||||
if type(bgcol) ~= "string" then
|
||||
error("bad argument #3 (expected string, got " .. type(bgcol) .. ")", 2)
|
||||
end
|
||||
if #fgcol ~= #text or #bgcol ~= #text then
|
||||
error("Arguments must be the same length", 2)
|
||||
end
|
||||
if (visible) then
|
||||
internalBlit(text, fgcol, bgcol)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
}
|
||||
|
||||
return basaltwindow
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function process:getStatus()
|
||||
if (self.coroutine ~= nil) then
|
||||
return coroutine.status(self.coroutine)
|
||||
base.width = 30
|
||||
base.height = 12
|
||||
local pWindow = createBasaltWindow(1, 1, base.width, base.height)
|
||||
local curProcess
|
||||
local paused = false
|
||||
local queuedEvent = {}
|
||||
|
||||
local function updateCursor(self)
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
|
||||
self.parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function process:start()
|
||||
coroutine.resume(self.coroutine)
|
||||
end
|
||||
local function resumeProcess(self, event, ...)
|
||||
local ok, result = curProcess:resume(event, ...)
|
||||
if (ok==false)and(result~=nil)and(result~="Terminated")then
|
||||
local val = self:sendEvent("program_error", result)
|
||||
if(val~=false)then
|
||||
error("Basalt Program - "..result)
|
||||
end
|
||||
end
|
||||
|
||||
if(curProcess:getStatus()=="dead")then
|
||||
self:sendEvent("program_done")
|
||||
end
|
||||
end
|
||||
|
||||
return process
|
||||
local function mouseEvent(self, event, p1, x, y)
|
||||
if (curProcess == nil) then
|
||||
return false
|
||||
end
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true))
|
||||
resumeProcess(self, event, p1, x-absX+1, y-absY+1)
|
||||
updateCursor(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function keyEvent(self, event, key, isHolding)
|
||||
if (curProcess == nil) then
|
||||
return false
|
||||
end
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
if (self.draw) then
|
||||
resumeProcess(self, event, key, isHolding)
|
||||
updateCursor(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
show = function(self)
|
||||
base.show(self)
|
||||
pWindow.setBackgroundColor(self.bgColor)
|
||||
pWindow.setTextColor(self.fgColor)
|
||||
pWindow.basalt_setVisible(true)
|
||||
return self
|
||||
end;
|
||||
|
||||
hide = function(self)
|
||||
base.hide(self)
|
||||
pWindow.basalt_setVisible(false)
|
||||
return self
|
||||
end;
|
||||
|
||||
setPosition = function(self, x, y, rel)
|
||||
base.setPosition(self, x, y, rel)
|
||||
pWindow.basalt_reposition(self:getAnchorPosition())
|
||||
return self
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("path", data)~=nil)then cachedPath = xmlValue("path", data) end
|
||||
if(xmlValue("execute", data)~=nil)then if(xmlValue("execute", data))then if(cachedPath~=nil)then self:execute(cachedPath) end end end
|
||||
end,
|
||||
|
||||
getBasaltWindow = function()
|
||||
return pWindow
|
||||
end;
|
||||
|
||||
getBasaltProcess = function()
|
||||
return curProcess
|
||||
end;
|
||||
|
||||
setSize = function(self, width, height, rel)
|
||||
base.setSize(self, width, height, rel)
|
||||
pWindow.basalt_resize(self:getWidth(), self:getHeight())
|
||||
return self
|
||||
end;
|
||||
|
||||
getStatus = function(self)
|
||||
if (curProcess ~= nil) then
|
||||
return curProcess:getStatus()
|
||||
end
|
||||
return "inactive"
|
||||
end;
|
||||
|
||||
setEnviroment = function(self, env)
|
||||
enviroment = env or {}
|
||||
return self
|
||||
end,
|
||||
|
||||
execute = function(self, path, ...)
|
||||
cachedPath = path or cachedPath
|
||||
curProcess = process:new(cachedPath, pWindow, enviroment, ...)
|
||||
pWindow.setBackgroundColor(colors.black)
|
||||
pWindow.setTextColor(colors.white)
|
||||
pWindow.clear()
|
||||
pWindow.setCursorPos(1, 1)
|
||||
pWindow.setBackgroundColor(self.bgColor)
|
||||
pWindow.setTextColor(self.fgColor)
|
||||
pWindow.basalt_setVisible(true)
|
||||
|
||||
resumeProcess(self)
|
||||
paused = false
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
self.parent:addEvent("key", self)
|
||||
self.parent:addEvent("key_up", self)
|
||||
self.parent:addEvent("char", self)
|
||||
self.parent:addEvent("other_event", self)
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
stop = function(self)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
resumeProcess(self, "terminate")
|
||||
if (curProcess:isDead()) then
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.parent:removeEvents(self)
|
||||
return self
|
||||
end;
|
||||
|
||||
pause = function(self, p)
|
||||
paused = p or (not paused)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
self:injectEvents(queuedEvent)
|
||||
queuedEvent = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
isPaused = function(self)
|
||||
return paused
|
||||
end;
|
||||
|
||||
injectEvent = function(self, event, p1, p2, p3, p4, ign)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if (paused == false) or (ign) then
|
||||
resumeProcess(self, event, p1, p2, p3, p4)
|
||||
else
|
||||
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
getQueuedEvents = function(self)
|
||||
return queuedEvent
|
||||
end;
|
||||
|
||||
updateQueuedEvents = function(self, events)
|
||||
queuedEvent = events or queuedEvent
|
||||
return self
|
||||
end;
|
||||
|
||||
injectEvents = function(self, events)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
for _, value in pairs(events) do
|
||||
resumeProcess(self, value.event, table.unpack(value.args))
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if (base.mouseHandler(self, button, x, y)) then
|
||||
mouseEvent(self, "mouse_click", button, x, y)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
mouseUpHandler = function(self, button, x, y)
|
||||
if (base.mouseUpHandler(self, button, x, y)) then
|
||||
mouseEvent(self, "mouse_up", button, x, y)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if (base.scrollHandler(self, dir, x, y)) then
|
||||
mouseEvent(self, "mouse_scroll", dir, x, y)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
dragHandler = function(self, button, x, y)
|
||||
if (base.dragHandler(self, button, x, y)) then
|
||||
mouseEvent(self, "mouse_drag", button, x, y)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
keyHandler = function(self, key, isHolding)
|
||||
if(base.keyHandler(self, key, isHolding))then
|
||||
keyEvent(self, "key", key, isHolding)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
keyUpHandler = function(self, key)
|
||||
if(base.keyUpHandler(self, key))then
|
||||
keyEvent(self, "key_up", key)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
charHandler = function(self, char)
|
||||
if(base.charHandler(self, char))then
|
||||
keyEvent(self, "char", char)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
getFocusHandler = function(self)
|
||||
base.getFocusHandler(self)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
if (self.parent ~= nil) then
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
|
||||
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
loseFocusHandler = function(self)
|
||||
base.loseFocusHandler(self)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
customEventHandler = function(self, event, ...)
|
||||
base.customEventHandler(self, event, ...)
|
||||
if (curProcess == nil) then
|
||||
return
|
||||
end
|
||||
if(event=="basalt_resize")then
|
||||
local w, h = pWindow.getSize()
|
||||
local pW, pH = self:getSize()
|
||||
if(w~=pW)or(h~=pH)then
|
||||
pWindow.basalt_resize(pW, pH)
|
||||
if not (curProcess:isDead()) then
|
||||
resumeProcess(self, "term_resize")
|
||||
end
|
||||
end
|
||||
pWindow.basalt_reposition(self:getAnchorPosition())
|
||||
|
||||
end
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, p1, p2, p3, p4)
|
||||
base.eventHandler(self, event, p1, p2, p3, p4)
|
||||
if (curProcess == nil) then
|
||||
return
|
||||
end
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
if(event ~= "terminate") then
|
||||
resumeProcess(self, event, p1, p2, p3, p4)
|
||||
end
|
||||
if (self:isFocused()) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
if (self.parent ~= nil) then
|
||||
local w,h = self:getSize()
|
||||
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
|
||||
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
|
||||
if (event == "terminate") then
|
||||
resumeProcess(self, event)
|
||||
self.parent:setCursor(false)
|
||||
return true
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
local w,h = self:getSize()
|
||||
pWindow.basalt_reposition(obx, oby)
|
||||
pWindow.basalt_update()
|
||||
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
|
||||
self.parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
onError = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("program_error", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("other_event", self)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onDone = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("program_done", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("other_event", self)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ProgramBG")
|
||||
end
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user