Merge branch 'Pyroxenium:master' into erb3-path-7
1281
Basalt/Frame.lua
1071
Basalt/Object.lua
@@ -6,12 +6,13 @@ if not(packed)then
|
||||
|
||||
local main = format:gsub("path", curDir)
|
||||
local objFolder = format:gsub("path", curDir.."/objects")
|
||||
local plugFolder = format:gsub("path", curDir.."/plugins")
|
||||
local libFolder = format:gsub("path", curDir.."/libraries")
|
||||
|
||||
|
||||
package.path = main..objFolder..libFolder..defaultPath
|
||||
package.path = main..objFolder..plugFolder..libFolder..defaultPath
|
||||
end
|
||||
local Basalt = require("main")
|
||||
package.path = defaultPath
|
||||
|
||||
return Basalt
|
||||
return Basalt
|
||||
@@ -1,4 +1,6 @@
|
||||
local tHex = require("tHex")
|
||||
local utils = require("utils")
|
||||
local split = utils.splitString
|
||||
local sub,rep = string.sub,string.rep
|
||||
|
||||
return function(drawTerm)
|
||||
@@ -9,13 +11,9 @@ return function(drawTerm)
|
||||
local cacheBG = {}
|
||||
local cacheFG = {}
|
||||
|
||||
local _cacheT = {}
|
||||
local _cacheBG = {}
|
||||
local _cacheFG = {}
|
||||
|
||||
local emptySpaceLine
|
||||
local emptyColorLines = {}
|
||||
|
||||
|
||||
local function createEmptyLines()
|
||||
emptySpaceLine = rep(" ", width)
|
||||
for n = 0, 15 do
|
||||
@@ -40,137 +38,137 @@ return function(drawTerm)
|
||||
end
|
||||
recreateWindowArray()
|
||||
|
||||
local function setText(x, y, text)
|
||||
if (y >= 1) and (y <= height) then
|
||||
if (x + text:len() > 0) and (x <= width) then
|
||||
local oldCache = cacheT[y]
|
||||
local newCache
|
||||
local nEnd = x + #text - 1
|
||||
|
||||
if (x < 1) then
|
||||
local startN = 1 - x + 1
|
||||
local endN = width - x + 1
|
||||
text = sub(text, startN, endN)
|
||||
elseif (nEnd > width) then
|
||||
local endN = width - x + 1
|
||||
text = sub(text, 1, endN)
|
||||
local function blit(x, y, t, fg, bg)
|
||||
if #t == #fg and #t == #bg then
|
||||
if y >= 1 and y <= height then
|
||||
if x + #t > 0 and x <= width then
|
||||
local newCacheT, newCacheFG, newCacheBG
|
||||
local oldCacheT, oldCacheFG, oldCacheBG = cacheT[y], cacheFG[y], cacheBG[y]
|
||||
local startN, endN = 1, #t
|
||||
|
||||
if x < 1 then
|
||||
startN = 1 - x + 1
|
||||
endN = width - x + 1
|
||||
elseif x + #t > width then
|
||||
endN = width - x + 1
|
||||
end
|
||||
|
||||
newCacheT = sub(oldCacheT, 1, x - 1) .. sub(t, startN, endN)
|
||||
newCacheFG = sub(oldCacheFG, 1, x - 1) .. sub(fg, startN, endN)
|
||||
newCacheBG = sub(oldCacheBG, 1, x - 1) .. sub(bg, startN, endN)
|
||||
|
||||
if x + #t <= width then
|
||||
newCacheT = newCacheT .. sub(oldCacheT, x + #t, width)
|
||||
newCacheFG = newCacheFG .. sub(oldCacheFG, x + #t, width)
|
||||
newCacheBG = newCacheBG .. sub(oldCacheBG, x + #t, width)
|
||||
end
|
||||
|
||||
cacheT[y], cacheFG[y], cacheBG[y] = newCacheT,newCacheFG,newCacheBG
|
||||
end
|
||||
|
||||
if (x > 1) then
|
||||
local endN = x - 1
|
||||
newCache = sub(oldCache, 1, endN) .. text
|
||||
else
|
||||
newCache = text
|
||||
end
|
||||
if nEnd < width then
|
||||
newCache = newCache .. sub(oldCache, nEnd + 1, width)
|
||||
end
|
||||
cacheT[y] = newCache
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function setBG(x, y, colorStr)
|
||||
if (y >= 1) and (y <= height) then
|
||||
if (x + colorStr:len() > 0) and (x <= width) then
|
||||
local oldCache = cacheBG[y]
|
||||
local newCache
|
||||
local nEnd = x + #colorStr - 1
|
||||
local function setText(x, y, t)
|
||||
if y >= 1 and y <= height then
|
||||
if x + #t > 0 and x <= width then
|
||||
local newCacheT
|
||||
local oldCacheT = cacheT[y]
|
||||
local startN, endN = 1, #t
|
||||
|
||||
if (x < 1) then
|
||||
colorStr = sub(colorStr, 1 - x + 1, width - x + 1)
|
||||
elseif (nEnd > width) then
|
||||
colorStr = sub(colorStr, 1, width - x + 1)
|
||||
if x < 1 then
|
||||
startN = 1 - x + 1
|
||||
endN = width - x + 1
|
||||
elseif x + #t > width then
|
||||
endN = width - x + 1
|
||||
end
|
||||
|
||||
if (x > 1) then
|
||||
newCache = sub(oldCache, 1, x - 1) .. colorStr
|
||||
else
|
||||
newCache = colorStr
|
||||
newCacheT = sub(oldCacheT, 1, x - 1) .. sub(t, startN, endN)
|
||||
|
||||
if x + #t <= width then
|
||||
newCacheT = newCacheT .. sub(oldCacheT, x + #t, width)
|
||||
end
|
||||
if nEnd < width then
|
||||
newCache = newCache .. sub(oldCache, nEnd + 1, width)
|
||||
end
|
||||
cacheBG[y] = newCache
|
||||
|
||||
cacheT[y] = newCacheT
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function setBG(x, y, bg)
|
||||
if y >= 1 and y <= height then
|
||||
if x + #bg > 0 and x <= width then
|
||||
local newCacheBG
|
||||
local oldCacheBG = cacheBG[y]
|
||||
local startN, endN = 1, #bg
|
||||
|
||||
if x < 1 then
|
||||
startN = 1 - x + 1
|
||||
endN = width - x + 1
|
||||
elseif x + #bg > width then
|
||||
endN = width - x + 1
|
||||
end
|
||||
|
||||
newCacheBG = sub(oldCacheBG, 1, x - 1) .. sub(bg, startN, endN)
|
||||
|
||||
if x + #bg <= width then
|
||||
newCacheBG = newCacheBG .. sub(oldCacheBG, x + #bg, width)
|
||||
end
|
||||
|
||||
cacheBG[y] = newCacheBG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function setFG(x, y, fg)
|
||||
if y >= 1 and y <= height then
|
||||
if x + #fg > 0 and x <= width then
|
||||
local newCacheFG
|
||||
local oldCacheFG = cacheFG[y]
|
||||
local startN, endN = 1, #fg
|
||||
|
||||
if x < 1 then
|
||||
startN = 1 - x + 1
|
||||
endN = width - x + 1
|
||||
elseif x + #fg > width then
|
||||
endN = width - x + 1
|
||||
end
|
||||
|
||||
newCacheFG = sub(oldCacheFG, 1, x - 1) .. sub(fg, startN, endN)
|
||||
|
||||
if x + #fg <= width then
|
||||
newCacheFG = newCacheFG .. sub(oldCacheFG, x + #fg, width)
|
||||
end
|
||||
|
||||
cacheFG[y] = newCacheFG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
local function setText(x, y, text)
|
||||
if (y >= 1) and (y <= height) then
|
||||
local emptyLine = rep(" ", #text)
|
||||
blit(x, y, text, emptyLine, emptyLine)
|
||||
end
|
||||
end
|
||||
|
||||
local function setFG(x, y, colorStr)
|
||||
if (y >= 1) and (y <= height) then
|
||||
if (x + colorStr:len() > 0) and (x <= width) then
|
||||
local oldCache = cacheFG[y]
|
||||
local newCache
|
||||
local nEnd = x + #colorStr - 1
|
||||
|
||||
if (x < 1) then
|
||||
local startN = 1 - x + 1
|
||||
local endN = width - x + 1
|
||||
colorStr = sub(colorStr, startN, endN)
|
||||
elseif (nEnd > width) then
|
||||
local endN = width - x + 1
|
||||
colorStr = sub(colorStr, 1, endN)
|
||||
end
|
||||
|
||||
if (x > 1) then
|
||||
local endN = x - 1
|
||||
newCache = sub(oldCache, 1, endN) .. colorStr
|
||||
else
|
||||
newCache = colorStr
|
||||
end
|
||||
if nEnd < width then
|
||||
newCache = newCache .. sub(oldCache, nEnd + 1, width)
|
||||
end
|
||||
cacheFG[y] = newCache
|
||||
end
|
||||
local w = #colorStr
|
||||
local emptyLine = rep(" ", w)
|
||||
local text = sub(cacheT[y], x, w)
|
||||
blit(x, y, text, colorStr, emptyLine)
|
||||
end
|
||||
end
|
||||
|
||||
local function blit(x, y, t, fg, bg)
|
||||
if(#t == #fg)or(#t == #bg)then
|
||||
if (y >= 1) and (y <= height) then
|
||||
if (x + t:len() > 0) and (x <= width) then
|
||||
local oldCacheT = cacheT[y]
|
||||
local oldCacheFG = cacheFG[y]
|
||||
local oldCacheBG = cacheBG[y]
|
||||
local newCacheT, newCacheFG, newCacheBG
|
||||
local nEnd = x + #t - 1
|
||||
|
||||
if (x < 1) then
|
||||
local startN = 1 - x + 1
|
||||
local endN = width - x + 1
|
||||
t = sub(t, startN, endN)
|
||||
fg = sub(fg, startN, endN)
|
||||
bg = sub(bg, startN, endN)
|
||||
elseif (nEnd > width) then
|
||||
local endN = width - x + 1
|
||||
t = sub(t, 1, endN)
|
||||
fg = sub(fg, 1, endN)
|
||||
bg = sub(bg, 1, endN)
|
||||
end
|
||||
|
||||
if (x > 1) then
|
||||
local endN = x - 1
|
||||
newCacheT = sub(oldCacheT, 1, endN) .. t
|
||||
newCacheFG = sub(oldCacheFG, 1, endN) .. fg
|
||||
newCacheBG = sub(oldCacheBG, 1, endN) .. bg
|
||||
else
|
||||
newCacheT = t
|
||||
newCacheFG = fg
|
||||
newCacheBG = bg
|
||||
end
|
||||
if nEnd < width then
|
||||
newCacheT = newCacheT .. sub(oldCacheT, nEnd + 1, width)
|
||||
newCacheFG = newCacheFG .. sub(oldCacheFG, nEnd + 1, width)
|
||||
newCacheBG = newCacheBG .. sub(oldCacheBG, nEnd + 1, width)
|
||||
end
|
||||
cacheT[y] = newCacheT
|
||||
cacheFG[y] = newCacheFG
|
||||
cacheBG[y] = newCacheBG
|
||||
end
|
||||
end
|
||||
local function setBG(x, y, colorStr)
|
||||
if (y >= 1) and (y <= height) then
|
||||
local w = #colorStr
|
||||
local emptyLine = rep(" ", w)
|
||||
local text = sub(cacheT[y], x, w)
|
||||
blit(x, y, text, emptyLine, colorStr)
|
||||
end
|
||||
end
|
||||
end]]
|
||||
|
||||
local drawHelper = {
|
||||
setSize = function(w, h)
|
||||
@@ -181,13 +179,14 @@ return function(drawTerm)
|
||||
setMirror = function(mirror)
|
||||
mirrorTerm = mirror
|
||||
end,
|
||||
|
||||
setBG = function(x, y, colorStr)
|
||||
setBG(x, y, colorStr)
|
||||
end;
|
||||
end,
|
||||
|
||||
setText = function(x, y, text)
|
||||
setText(x, y, text)
|
||||
end;
|
||||
end,
|
||||
|
||||
setFG = function(x, y, colorStr)
|
||||
setFG(x, y, colorStr)
|
||||
@@ -198,31 +197,23 @@ return function(drawTerm)
|
||||
end,
|
||||
|
||||
drawBackgroundBox = function(x, y, width, height, bgCol)
|
||||
local colorStr = rep(tHex[bgCol], width)
|
||||
for n = 1, height do
|
||||
setBG(x, y + (n - 1), rep(tHex[bgCol], width))
|
||||
setBG(x, y + (n - 1), colorStr)
|
||||
end
|
||||
end;
|
||||
end,
|
||||
drawForegroundBox = function(x, y, width, height, fgCol)
|
||||
local colorStr = rep(tHex[fgCol], width)
|
||||
for n = 1, height do
|
||||
setFG(x, y + (n - 1) ,rep(tHex[fgCol], width))
|
||||
setFG(x, y + (n - 1), colorStr)
|
||||
end
|
||||
end;
|
||||
end,
|
||||
drawTextBox = function(x, y, width, height, symbol)
|
||||
local textStr = rep(symbol, width)
|
||||
for n = 1, height do
|
||||
setText(x, y + (n - 1), rep(symbol, width))
|
||||
setText(x, y + (n - 1), textStr)
|
||||
end
|
||||
end;
|
||||
writeText = function(x, y, text, bgCol, fgCol)
|
||||
if(text~=nil)then
|
||||
setText(x, y, text)
|
||||
if(bgCol~=nil)and(bgCol~=false)then
|
||||
setBG(x, y, rep(tHex[bgCol], text:len()))
|
||||
end
|
||||
if(fgCol~=nil)and(fgCol~=false)then
|
||||
setFG(x, y, rep(tHex[fgCol], text:len()))
|
||||
end
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
update = function()
|
||||
local xC, yC = terminal.getCursorPos()
|
||||
@@ -249,11 +240,11 @@ return function(drawTerm)
|
||||
mirrorTerm.setCursorPos(xC, yC)
|
||||
end
|
||||
|
||||
end;
|
||||
end,
|
||||
|
||||
setTerm = function(newTerm)
|
||||
terminal = newTerm;
|
||||
end;
|
||||
terminal = newTerm
|
||||
end,
|
||||
}
|
||||
return drawHelper
|
||||
end
|
||||
@@ -1,21 +1,41 @@
|
||||
return function()
|
||||
local events = {}
|
||||
local index = {}
|
||||
|
||||
local event = {
|
||||
registerEvent = function(self, _event, func)
|
||||
if (events[_event] == nil) then
|
||||
events[_event] = {}
|
||||
index[_event] = 1
|
||||
end
|
||||
events[_event][index[_event]] = func
|
||||
index[_event] = index[_event] + 1
|
||||
return index[_event] - 1
|
||||
end;
|
||||
table.insert(events[_event], func)
|
||||
end,
|
||||
|
||||
removeEvent = function(self, _event, index)
|
||||
events[_event][index[_event]] = nil
|
||||
end;
|
||||
end,
|
||||
|
||||
hasEvent = function(self, _event)
|
||||
return events[_event]~=nil
|
||||
end,
|
||||
|
||||
getEventCount = function(self, _event)
|
||||
return events[_event]~=nil and #events[_event] or 0
|
||||
end,
|
||||
|
||||
getEvents = function(self)
|
||||
local t = {}
|
||||
for k,v in pairs(events)do
|
||||
table.insert(t, k)
|
||||
end
|
||||
return t
|
||||
end,
|
||||
|
||||
clearEvent = function(self, _event)
|
||||
events[_event] = nil
|
||||
end,
|
||||
|
||||
clear = function(self, _event)
|
||||
events = {}
|
||||
end,
|
||||
|
||||
sendEvent = function(self, _event, ...)
|
||||
local returnValue
|
||||
@@ -28,7 +48,7 @@ return function()
|
||||
end
|
||||
end
|
||||
return returnValue
|
||||
end;
|
||||
end,
|
||||
}
|
||||
event.__index = event
|
||||
return event
|
||||
|
||||
@@ -10,7 +10,7 @@ local mt = {
|
||||
if(text==nil)then return end
|
||||
local dirStr = logDir~="" and logDir.."/"..logFileName or logFileName
|
||||
local handle = fs.open(dirStr, fs.exists(dirStr) and "a" or "w")
|
||||
handle.writeLine("[Basalt]["..(typ and typ or defaultLogType).."]: "..tostring(text))
|
||||
handle.writeLine("[Basalt]["..os.date("%Y-%m-%d %H:%M:%S").."]["..(typ and typ or defaultLogType).."]: "..tostring(text))
|
||||
handle.close()
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -80,9 +80,11 @@ local function frame(base, manager)
|
||||
end
|
||||
|
||||
if(base~=nil)then
|
||||
w = #base[1][1]
|
||||
h = #base
|
||||
setFrame(base)
|
||||
if(#base>0)then
|
||||
w = #base[1][1]
|
||||
h = #base
|
||||
setFrame(base)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
@@ -134,7 +136,11 @@ local function frame(base, manager)
|
||||
end,
|
||||
|
||||
getFrameData = function(key)
|
||||
return (key~= nil and data[key] or data)
|
||||
if(key~=nil)then
|
||||
return data[key]
|
||||
else
|
||||
return data
|
||||
end
|
||||
end,
|
||||
|
||||
blit = function(text, fgCol, bgCol, x, y)
|
||||
@@ -181,14 +187,22 @@ return function(img)
|
||||
local metadata = {creator="Bimg Library by NyoriE", date=os.date("!%Y-%m-%dT%TZ")}
|
||||
local width,height = 0, 0
|
||||
|
||||
if(img~=nil)then
|
||||
if(img[1][1][1]~=nil)then
|
||||
width,height = metadata.width or #img[1][1][1], metadata.height or #img[1]
|
||||
end
|
||||
end
|
||||
|
||||
local manager = {}
|
||||
|
||||
local function addFrame(id, data)
|
||||
id = id or #frames+1
|
||||
table.insert(frames, id, frame(data, manager))
|
||||
local f = frame(data, manager)
|
||||
table.insert(frames, id, f)
|
||||
if(data==nil)then
|
||||
frames[id].setSize(width, height)
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
local function removeFrame(id)
|
||||
@@ -283,7 +297,6 @@ return function(img)
|
||||
end,
|
||||
|
||||
addFrame = function(id)
|
||||
local f = frame()
|
||||
if(#frames<=1)then
|
||||
if(metadata.animated==nil)then
|
||||
metadata.animated = true
|
||||
@@ -292,21 +305,10 @@ return function(img)
|
||||
metadata.secondsPerFrame = 0.2
|
||||
end
|
||||
end
|
||||
addFrame(id)
|
||||
return f
|
||||
return addFrame(id)
|
||||
end,
|
||||
|
||||
removeFrame = function(id)
|
||||
removeFrame(id)
|
||||
if(#frames<=1)then
|
||||
if(metadata.animated==nil)then
|
||||
metadata.animated = true
|
||||
end
|
||||
if(metadata.secondsPerFrame==nil)then
|
||||
metadata.secondsPerFrame = 0.2
|
||||
end
|
||||
end
|
||||
end,
|
||||
removeFrame = removeFrame,
|
||||
|
||||
moveFrame = moveFrame,
|
||||
|
||||
@@ -317,7 +319,9 @@ return function(img)
|
||||
end,
|
||||
|
||||
getFrameData = function(id, key)
|
||||
return frames[id]~=nil and frames[id].getFrameData(key)
|
||||
if(frames[id]~=nil)then
|
||||
return frames[id].getFrameData(key)
|
||||
end
|
||||
end,
|
||||
|
||||
getSize = function()
|
||||
@@ -339,7 +343,11 @@ return function(img)
|
||||
end,
|
||||
|
||||
getMetadata = function(key)
|
||||
return key~=nil and metadata[key] or metadata
|
||||
if(key~=nil)then
|
||||
return metadata[key]
|
||||
else
|
||||
return metadata
|
||||
end
|
||||
end,
|
||||
|
||||
createBimg = function()
|
||||
@@ -361,18 +369,19 @@ return function(img)
|
||||
for k,v in pairs(img)do
|
||||
if(type(k)=="string")then
|
||||
metadata[k] = v
|
||||
else
|
||||
addFrame(k, v)
|
||||
end
|
||||
end
|
||||
if(metadata.width==nil)or(metadata.height==nil)then
|
||||
for k,v in pairs(frames)do
|
||||
local w, h = v.getSize()
|
||||
if(w>width)then w = width end
|
||||
if(h>height)then h = height end
|
||||
end
|
||||
width = metadata.width or #img[1][1][1]
|
||||
height = metadata.height or #img[1]
|
||||
manager.updateSize(width, height, true)
|
||||
end
|
||||
|
||||
for k,v in pairs(img)do
|
||||
if(type(k)=="number")then
|
||||
addFrame(k, v)
|
||||
end
|
||||
end
|
||||
else
|
||||
addFrame(1)
|
||||
end
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
local sub,floor,rep = string.sub,math.floor,string.rep
|
||||
local sub,floor = string.sub,math.floor
|
||||
|
||||
local function loadNFPAsBimg(path)
|
||||
local bimg = {{}}
|
||||
local nfp = fs.open(path, "r")
|
||||
if(nfp~=nil)then
|
||||
for line in nfp.readLine do
|
||||
table.insert(bimg[1], {rep(" ",#line), rep(" ",#line), line})
|
||||
end
|
||||
nfp.close()
|
||||
return bimg
|
||||
end
|
||||
return {[1]={{}, {}, paintutils.loadImage(path)}}, "bimg"
|
||||
end
|
||||
|
||||
local function loadNFP(path)
|
||||
return paintutils.loadImage(path), "nfp"
|
||||
end
|
||||
|
||||
local function loadBIMG(path)
|
||||
local f = fs.open(path, "rb")
|
||||
local function loadBIMG(path, binaryMode)
|
||||
local f = fs.open(path, binaryMode and "rb" or "r")
|
||||
if(f==nil)then error("Path - "..path.." doesn't exist!") end
|
||||
local content = textutils.unserialize(f.readAll())
|
||||
|
||||
f.close()
|
||||
if(content~=nil)then
|
||||
return content, "bimg"
|
||||
@@ -33,28 +27,24 @@ local function loadBBFAsBimg(path)
|
||||
|
||||
end
|
||||
|
||||
local function loadImage(path, f)
|
||||
if(f==nil)then
|
||||
if(path:find(".bimg"))then
|
||||
return loadBIMG(path)
|
||||
elseif(path:find(".bbf"))then
|
||||
return loadBBF(path)
|
||||
else
|
||||
return loadNFP(path)
|
||||
end
|
||||
local function loadImage(path, f, binaryMode)
|
||||
if(sub(path, -4) == ".bimg")then
|
||||
return loadBIMG(path, binaryMode)
|
||||
elseif(sub(path, -3) == ".bbf")then
|
||||
return loadBBF(path, binaryMode)
|
||||
else
|
||||
return loadNFP(path, binaryMode)
|
||||
end
|
||||
-- ...
|
||||
end
|
||||
|
||||
local function loadImageAsBimg(path, f)
|
||||
if(f==nil)then
|
||||
if(path:find(".bimg"))then
|
||||
return loadBIMG(path)
|
||||
elseif(path:find(".bbf"))then
|
||||
return loadBBFAsBimg(path)
|
||||
else
|
||||
return loadNFPAsBimg(path)
|
||||
end
|
||||
local function loadImageAsBimg(path)
|
||||
if(path:find(".bimg"))then
|
||||
return loadBIMG(path)
|
||||
elseif(path:find(".bbf"))then
|
||||
return loadBBFAsBimg(path)
|
||||
else
|
||||
return loadNFPAsBimg(path)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -94,4 +84,4 @@ return {
|
||||
resizeBIMG = resizeBIMG,
|
||||
loadImageAsBimg = loadImageAsBimg,
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
local function newNode(name)
|
||||
local node = {}
|
||||
node.___value = nil
|
||||
node.___name = name
|
||||
node.___children = {}
|
||||
node.___props = {}
|
||||
|
||||
function node:value() return self.___value end
|
||||
function node:setValue(val) self.___value = val end
|
||||
function node:name() return self.___name end
|
||||
function node:setName(name) self.___name = name end
|
||||
function node:children() return self.___children end
|
||||
function node:numChildren() return #self.___children end
|
||||
function node:addChild(child)
|
||||
if self[child:name()] ~= nil then
|
||||
if type(self[child:name()].name) == "function" then
|
||||
local tempTable = {}
|
||||
table.insert(tempTable, self[child:name()])
|
||||
self[child:name()] = tempTable
|
||||
end
|
||||
table.insert(self[child:name()], child)
|
||||
else
|
||||
self[child:name()] = child
|
||||
end
|
||||
table.insert(self.___children, child)
|
||||
end
|
||||
|
||||
function node:properties() return self.___props end
|
||||
function node:numProperties() return #self.___props end
|
||||
function node:addProperty(name, value)
|
||||
local lName = "@" .. name
|
||||
if self[lName] ~= nil then
|
||||
if type(self[lName]) == "string" then
|
||||
local tempTable = {}
|
||||
table.insert(tempTable, self[lName])
|
||||
self[lName] = tempTable
|
||||
end
|
||||
table.insert(self[lName], value)
|
||||
else
|
||||
self[lName] = value
|
||||
end
|
||||
table.insert(self.___props, { name = name, value = self[name] })
|
||||
end
|
||||
|
||||
return node
|
||||
end
|
||||
|
||||
local XmlParser = {};
|
||||
|
||||
function XmlParser:ToXmlString(value)
|
||||
value = string.gsub(value, "&", "&"); -- '&' -> "&"
|
||||
value = string.gsub(value, "<", "<"); -- '<' -> "<"
|
||||
value = string.gsub(value, ">", ">"); -- '>' -> ">"
|
||||
value = string.gsub(value, "\"", """); -- '"' -> """
|
||||
value = string.gsub(value, "([^%w%&%;%p%\t% ])",
|
||||
function(c)
|
||||
return string.format("&#x%X;", string.byte(c))
|
||||
end);
|
||||
return value;
|
||||
end
|
||||
|
||||
function XmlParser:FromXmlString(value)
|
||||
value = string.gsub(value, "&#x([%x]+)%;",
|
||||
function(h)
|
||||
return string.char(tonumber(h, 16))
|
||||
end);
|
||||
value = string.gsub(value, "&#([0-9]+)%;",
|
||||
function(h)
|
||||
return string.char(tonumber(h, 10))
|
||||
end);
|
||||
value = string.gsub(value, """, "\"");
|
||||
value = string.gsub(value, "'", "'");
|
||||
value = string.gsub(value, ">", ">");
|
||||
value = string.gsub(value, "<", "<");
|
||||
value = string.gsub(value, "&", "&");
|
||||
return value;
|
||||
end
|
||||
|
||||
function XmlParser:ParseArgs(node, s)
|
||||
string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a)
|
||||
node:addProperty(w, self:FromXmlString(a))
|
||||
end)
|
||||
end
|
||||
|
||||
function XmlParser:ParseXmlText(xmlText)
|
||||
local stack = {}
|
||||
local top = newNode()
|
||||
table.insert(stack, top)
|
||||
local ni, c, label, xarg, empty
|
||||
local i, j = 1, 1
|
||||
while true do
|
||||
ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w_:]+)(.-)(%/?)>", i)
|
||||
if not ni then break end
|
||||
local text = string.sub(xmlText, i, ni - 1);
|
||||
if not string.find(text, "^%s*$") then
|
||||
local lVal = (top:value() or "") .. self:FromXmlString(text)
|
||||
stack[#stack]:setValue(lVal)
|
||||
end
|
||||
if empty == "/" then -- empty element tag
|
||||
local lNode = newNode(label)
|
||||
self:ParseArgs(lNode, xarg)
|
||||
top:addChild(lNode)
|
||||
elseif c == "" then -- start tag
|
||||
local lNode = newNode(label)
|
||||
self:ParseArgs(lNode, xarg)
|
||||
table.insert(stack, lNode)
|
||||
top = lNode
|
||||
else -- end tag
|
||||
local toclose = table.remove(stack) -- remove top
|
||||
|
||||
top = stack[#stack]
|
||||
if #stack < 1 then
|
||||
error("XmlParser: nothing to close with " .. label)
|
||||
end
|
||||
if toclose:name() ~= label then
|
||||
error("XmlParser: trying to close " .. toclose.name .. " with " .. label)
|
||||
end
|
||||
top:addChild(toclose)
|
||||
end
|
||||
i = j + 1
|
||||
end
|
||||
local text = string.sub(xmlText, i);
|
||||
if #stack > 1 then
|
||||
error("XmlParser: unclosed " .. stack[#stack]:name())
|
||||
end
|
||||
return top
|
||||
end
|
||||
|
||||
function XmlParser:loadFile(xmlFilename, base)
|
||||
if not base then
|
||||
base = system.ResourceDirectory
|
||||
end
|
||||
|
||||
local path = system.pathForFile(xmlFilename, base)
|
||||
local hFile, err = io.open(path, "r");
|
||||
|
||||
if hFile and not err then
|
||||
local xmlText = hFile:read("*a"); -- read file content
|
||||
io.close(hFile);
|
||||
return self:ParseXmlText(xmlText), nil;
|
||||
else
|
||||
print(err)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
return XmlParser
|
||||
@@ -1,4 +0,0 @@
|
||||
return function(path)
|
||||
local exists, content = pcall(require, path)
|
||||
return exists and content or nil
|
||||
end
|
||||
@@ -17,6 +17,10 @@ function process:new(path, window, newEnv, ...)
|
||||
local env = setmetatable(newEnv, {__index=_ENV})
|
||||
env.shell = shell
|
||||
env.basaltProgram=true
|
||||
env.arg = {[0]=path, table.unpack(args)}
|
||||
if(pPath==nil)then
|
||||
error("The path "..path.." does not exist!")
|
||||
end
|
||||
env.require, env.package = newPackage(env, fs.getDir(pPath))
|
||||
if(fs.exists(pPath))then
|
||||
local file = fs.open(pPath, "r")
|
||||
@@ -24,7 +28,7 @@ function process:new(path, window, newEnv, ...)
|
||||
file.close()
|
||||
local program = load(content, path, "bt", env)
|
||||
if(program~=nil)then
|
||||
return program(table.unpack(args))
|
||||
return program()
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -81,4 +85,4 @@ function process:start()
|
||||
coroutine.resume(self.coroutine)
|
||||
end
|
||||
|
||||
return process
|
||||
return process
|
||||
@@ -1,18 +1,6 @@
|
||||
return { -- copy paste is a very important feature
|
||||
[colors.white] = "0",
|
||||
[colors.orange] = "1",
|
||||
[colors.magenta] = "2",
|
||||
[colors.lightBlue] = "3",
|
||||
[colors.yellow] = "4",
|
||||
[colors.lime] = "5",
|
||||
[colors.pink] = "6",
|
||||
[colors.gray] = "7",
|
||||
[colors.lightGray] = "8",
|
||||
[colors.cyan] = "9",
|
||||
[colors.purple] = "a",
|
||||
[colors.blue] = "b",
|
||||
[colors.brown] = "c",
|
||||
[colors.green] = "d",
|
||||
[colors.red] = "e",
|
||||
[colors.black] = "f",
|
||||
}
|
||||
local cols = {}
|
||||
|
||||
for i = 0, 15 do
|
||||
cols[2^i] = ("%x"):format(i)
|
||||
end
|
||||
return cols
|
||||
@@ -1,100 +1,227 @@
|
||||
local sub,find,reverse = string.sub,string.find,string.reverse
|
||||
local tHex = require("tHex")
|
||||
local sub,find,reverse,rep,insert,len = string.sub,string.find,string.reverse,string.rep,table.insert,string.len
|
||||
|
||||
local function splitString(str, delimiter)
|
||||
local result = {}
|
||||
if str == "" or delimiter == "" then
|
||||
return result
|
||||
end
|
||||
end
|
||||
local start = 1
|
||||
local delim_start, delim_end = find(str, delimiter, start)
|
||||
while delim_start do
|
||||
table.insert(result, sub(str, start, delim_start - 1))
|
||||
start = delim_end + 1
|
||||
delim_start, delim_end = find(str, delimiter, start)
|
||||
end
|
||||
table.insert(result, sub(str, start))
|
||||
while delim_start do
|
||||
insert(result, sub(str, start, delim_start - 1))
|
||||
start = delim_end + 1
|
||||
delim_start, delim_end = find(str, delimiter, start)
|
||||
end
|
||||
insert(result, sub(str, start))
|
||||
return result
|
||||
end
|
||||
|
||||
local relations = {[0] = {8, 4, 3, 6, 5}, {4, 14, 8, 7}, {6, 10, 8, 7}, {9, 11, 8, 0}, {1, 14, 8, 0}, {13, 12, 8, 0}, {2, 10, 8, 0}, {15, 8, 10, 11, 12, 14},
|
||||
{0, 7, 1, 9, 2, 13}, {3, 11, 8, 7}, {2, 6, 7, 15}, {9, 3, 7, 15}, {13, 5, 7, 15}, {5, 12, 8, 7}, {1, 4, 7, 15}, {7, 10, 11, 12, 14}}
|
||||
|
||||
local colourNum, exponents, colourChar = {}, {}, {}
|
||||
for i = 0, 15 do exponents[2^i] = i end
|
||||
do
|
||||
local hex = "0123456789abcdef"
|
||||
for i = 1, 16 do
|
||||
colourNum[hex:sub(i, i)] = i - 1
|
||||
colourNum[i - 1] = hex:sub(i, i)
|
||||
colourChar[hex:sub(i, i)] = 2 ^ (i - 1)
|
||||
colourChar[2 ^ (i - 1)] = hex:sub(i, i)
|
||||
|
||||
local thisRel = relations[i - 1]
|
||||
for i = 1, #thisRel do thisRel[i] = 2 ^ thisRel[i] end
|
||||
end
|
||||
local function removeTags(input)
|
||||
return input:gsub("{[^}]+}", "")
|
||||
end
|
||||
|
||||
local function getBestColourMatch(usage)
|
||||
local lastCol = relations[exponents[usage[#usage][1]]]
|
||||
|
||||
for j = 1, #lastCol do
|
||||
local thisRelation = lastCol[j]
|
||||
for i = 1, #usage - 1 do if usage[i][1] == thisRelation then return i end end
|
||||
end
|
||||
|
||||
return 1
|
||||
local function wrapText(str, width)
|
||||
str = removeTags(str)
|
||||
if(str=="")or(width==0)then
|
||||
return {""}
|
||||
end
|
||||
local uniqueLines = splitString(str, "\n")
|
||||
local result = {}
|
||||
for k, v in pairs(uniqueLines) do
|
||||
if #v == 0 then
|
||||
table.insert(result, "")
|
||||
else
|
||||
while #v > width do
|
||||
local last_space = width
|
||||
for i = width, 1, -1 do
|
||||
if sub(v, i, i) == " " then
|
||||
last_space = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if last_space == width then
|
||||
local line = sub(v, 1, last_space - 1) .. "-"
|
||||
table.insert(result, line)
|
||||
v = sub(v, last_space)
|
||||
else
|
||||
local line = sub(v, 1, last_space - 1)
|
||||
table.insert(result, line)
|
||||
v = sub(v, last_space + 1)
|
||||
end
|
||||
|
||||
if #v <= width then
|
||||
break
|
||||
end
|
||||
end
|
||||
if #v > 0 then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local function colsToChar(pattern, totals)
|
||||
if not totals then
|
||||
local newPattern = {}
|
||||
totals = {}
|
||||
for i = 1, 6 do
|
||||
local thisVal = pattern[i]
|
||||
local thisTot = totals[thisVal]
|
||||
totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal
|
||||
end
|
||||
pattern = newPattern
|
||||
end
|
||||
|
||||
local usage = {}
|
||||
for key, value in pairs(totals) do usage[#usage + 1] = {key, value} end
|
||||
|
||||
if #usage > 1 then
|
||||
-- Reduce the chunk to two colours:
|
||||
while #usage > 2 do
|
||||
table.sort(usage, function (a, b) return a[2] > b[2] end)
|
||||
local matchToInd, usageLen = getBestColourMatch(usage), #usage
|
||||
local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1]
|
||||
for i = 1, 6 do if pattern[i] == matchFrom then
|
||||
pattern[i] = matchTo
|
||||
usage[matchToInd][2] = usage[matchToInd][2] + 1
|
||||
end end
|
||||
usage[usageLen] = nil
|
||||
end
|
||||
--- Coonverts a string with special tags to a table with colors and text
|
||||
-- @param input The string to convert
|
||||
-- @return A table with the following structure: { {text = "Hello", color = colors.red}, {text = "World", color = colors.blue} }
|
||||
local function convertRichText(input)
|
||||
local parsedResult = {}
|
||||
local currentPosition = 1
|
||||
local rawPosition = 1
|
||||
|
||||
-- Convert to character. Adapted from oli414's function:
|
||||
-- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/
|
||||
local data = 128
|
||||
for i = 1, #pattern - 1 do if pattern[i] ~= pattern[6] then data = data + 2^(i-1) end end
|
||||
return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]]
|
||||
else
|
||||
-- Solid colour character:
|
||||
return "\128", colourChar[pattern[1]], colourChar[pattern[1]]
|
||||
end
|
||||
while currentPosition <= #input do
|
||||
local closestColor, closestBgColor
|
||||
local color, bgColor
|
||||
local colorEnd, bgColorEnd
|
||||
|
||||
for colorName, _ in pairs(colors) do
|
||||
local fgPattern = "{fg:" .. colorName.."}"
|
||||
local bgColorPattern = "{bg:" .. colorName.."}"
|
||||
local colorStart, colorEndCandidate = input:find(fgPattern, currentPosition)
|
||||
local bgColorStart, bgColorEndCandidate = input:find(bgColorPattern, currentPosition)
|
||||
|
||||
if colorStart and (not closestColor or colorStart < closestColor) then
|
||||
closestColor = colorStart
|
||||
color = colorName
|
||||
colorEnd = colorEndCandidate
|
||||
end
|
||||
|
||||
if bgColorStart and (not closestBgColor or bgColorStart < closestBgColor) then
|
||||
closestBgColor = bgColorStart
|
||||
bgColor = colorName
|
||||
bgColorEnd = bgColorEndCandidate
|
||||
end
|
||||
end
|
||||
|
||||
local nextPosition
|
||||
if closestColor and (not closestBgColor or closestColor < closestBgColor) then
|
||||
nextPosition = closestColor
|
||||
elseif closestBgColor then
|
||||
nextPosition = closestBgColor
|
||||
else
|
||||
nextPosition = #input + 1
|
||||
end
|
||||
|
||||
local text = input:sub(currentPosition, nextPosition - 1)
|
||||
if #text > 0 then
|
||||
table.insert(parsedResult, {
|
||||
color = nil,
|
||||
bgColor = nil,
|
||||
text = text,
|
||||
position = rawPosition
|
||||
})
|
||||
rawPosition = rawPosition + #text
|
||||
currentPosition = currentPosition + #text
|
||||
end
|
||||
|
||||
if closestColor and (not closestBgColor or closestColor < closestBgColor) then
|
||||
table.insert(parsedResult, {
|
||||
color = color,
|
||||
bgColor = nil,
|
||||
text = "",
|
||||
position = rawPosition,
|
||||
})
|
||||
currentPosition = colorEnd + 1
|
||||
elseif closestBgColor then
|
||||
table.insert(parsedResult, {
|
||||
color = nil,
|
||||
bgColor = bgColor,
|
||||
text = "",
|
||||
position = rawPosition,
|
||||
})
|
||||
currentPosition = bgColorEnd + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return parsedResult
|
||||
end
|
||||
|
||||
--- Wrapts text with special color tags, like {fg:red} or {bg:blue} to multiple lines
|
||||
--- @param text string Text to wrap
|
||||
--- @param width number Width of the line
|
||||
--- @return table Table of lines
|
||||
local function wrapRichText(text, width)
|
||||
local colorData = convertRichText(text)
|
||||
local formattedLines = {}
|
||||
local x, y = 1, 1
|
||||
local currentColor, currentBgColor
|
||||
|
||||
local function addFormattedEntry(entry)
|
||||
table.insert(formattedLines, {
|
||||
x = x,
|
||||
y = y,
|
||||
text = entry.text,
|
||||
color = entry.color or currentColor,
|
||||
bgColor = entry.bgColor or currentBgColor
|
||||
})
|
||||
end
|
||||
|
||||
for _, entry in ipairs(colorData) do
|
||||
if entry.color then
|
||||
currentColor = entry.color
|
||||
elseif entry.bgColor then
|
||||
currentBgColor = entry.bgColor
|
||||
else
|
||||
local words = splitString(entry.text, " ")
|
||||
|
||||
for i, word in ipairs(words) do
|
||||
local wordLength = #word
|
||||
|
||||
if i > 1 then
|
||||
if x + 1 + wordLength <= width then
|
||||
addFormattedEntry({ text = " " })
|
||||
x = x + 1
|
||||
else
|
||||
x = 1
|
||||
y = y + 1
|
||||
end
|
||||
end
|
||||
|
||||
while wordLength > 0 do
|
||||
local line = word:sub(1, width - x + 1)
|
||||
word = word:sub(width - x + 2)
|
||||
wordLength = #word
|
||||
|
||||
addFormattedEntry({ text = line })
|
||||
|
||||
if wordLength > 0 then
|
||||
x = 1
|
||||
y = y + 1
|
||||
else
|
||||
x = x + #line
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if x > width then
|
||||
x = 1
|
||||
y = y + 1
|
||||
end
|
||||
end
|
||||
|
||||
return formattedLines
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
getTextHorizontalAlign = function(text, width, textAlign, replaceChar)
|
||||
text = sub(text, 1, width)
|
||||
local offset = width - string.len(text)
|
||||
local offset = width - len(text)
|
||||
if (textAlign == "right") then
|
||||
text = string.rep(replaceChar or " ", offset) .. text
|
||||
text = rep(replaceChar or " ", offset) .. text
|
||||
elseif (textAlign == "center") then
|
||||
text = string.rep(replaceChar or " ", math.floor(offset / 2)) .. text .. string.rep(replaceChar or " ", math.floor(offset / 2))
|
||||
text = text .. (string.len(text) < width and (replaceChar or " ") or "")
|
||||
text = rep(replaceChar or " ", math.floor(offset / 2)) .. text .. rep(replaceChar or " ", math.floor(offset / 2))
|
||||
text = text .. (len(text) < width and (replaceChar or " ") or "")
|
||||
else
|
||||
text = text .. string.rep(replaceChar or " ", offset)
|
||||
text = text .. rep(replaceChar or " ", offset)
|
||||
end
|
||||
return text
|
||||
end,
|
||||
@@ -114,6 +241,14 @@ getTextVerticalAlign = function(h, textAlign)
|
||||
return offset
|
||||
end,
|
||||
|
||||
orderedTable = function(t)
|
||||
local newTable = {}
|
||||
for _, v in pairs(t) do
|
||||
newTable[#newTable+1] = v
|
||||
end
|
||||
return newTable
|
||||
end,
|
||||
|
||||
rpairs = function(t)
|
||||
return function(t, i)
|
||||
i = i - 1
|
||||
@@ -134,31 +269,11 @@ tableCount = function(t)
|
||||
end,
|
||||
|
||||
splitString = splitString,
|
||||
removeTags = removeTags,
|
||||
|
||||
createText = function(str, width)
|
||||
local uniqueLines = splitString(str, "\n")
|
||||
local result = {}
|
||||
for k,v in pairs(uniqueLines)do
|
||||
if(#v==0)then table.insert(result, "") end
|
||||
while #v > width do
|
||||
local last_space = find(reverse(sub(v, 1, width)), " ")
|
||||
if not last_space then
|
||||
last_space = width
|
||||
else
|
||||
last_space = width - last_space + 1
|
||||
end
|
||||
local line = sub(v, 1, last_space)
|
||||
table.insert(result, line)
|
||||
v = sub(v, last_space + 1)
|
||||
end
|
||||
if #v > 0 then
|
||||
table.insert(result, v)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end,
|
||||
wrapText = wrapText,
|
||||
|
||||
getValueFromXML = function(name, tab)
|
||||
xmlValue = function(name, tab)
|
||||
local var
|
||||
if(type(tab)~="table")then return end
|
||||
if(tab[name]~=nil)then
|
||||
@@ -180,51 +295,71 @@ getValueFromXML = function(name, tab)
|
||||
return var
|
||||
end,
|
||||
|
||||
numberFromString = function(str)
|
||||
return load("return " .. str)()
|
||||
end,
|
||||
convertRichText = convertRichText,
|
||||
|
||||
uuid = function()
|
||||
local random = math.random
|
||||
local function uuid()
|
||||
local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
||||
return string.gsub(template, '[xy]', function (c)
|
||||
local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
|
||||
return string.format('%x', v)
|
||||
end)
|
||||
--- Writes text with special color tags
|
||||
--- @param obj object The object to write to
|
||||
--- @param x number X-Position
|
||||
--- @param y number Y-Position
|
||||
--- @param text string The text to write
|
||||
writeRichText = function(obj, x, y, text)
|
||||
local richText = convertRichText(text)
|
||||
if(#richText==0)then
|
||||
obj:addText(x, y, text)
|
||||
return
|
||||
end
|
||||
|
||||
local defaultFG, defaultBG = obj:getForeground(), obj:getBackground()
|
||||
for _,v in pairs(richText)do
|
||||
obj:addText(x+v.position-1, y, v.text)
|
||||
if(v.color~=nil)then
|
||||
obj:addFG(x+v.position-1, y, tHex[colors[v.color] ]:rep(#v.text))
|
||||
defaultFG = colors[v.color]
|
||||
else
|
||||
obj:addFG(x+v.position-1, y, tHex[defaultFG]:rep(#v.text))
|
||||
end
|
||||
if(v.bgColor~=nil)then
|
||||
obj:addBG(x+v.position-1, y, tHex[colors[v.bgColor] ]:rep(#v.text))
|
||||
defaultBG = colors[v.bgColor]
|
||||
else
|
||||
if(defaultBG~=false)then
|
||||
obj:addBG(x+v.position-1, y, tHex[defaultBG]:rep(#v.text))
|
||||
end
|
||||
end
|
||||
end
|
||||
return uuid()
|
||||
end,
|
||||
|
||||
array = function(arraysize, hashsize)
|
||||
return load("return {" .. ("nil,"):rep(arraysize) .. ("[0]=nil,"):rep(hashsize) .. "}")()
|
||||
wrapRichText = wrapRichText,
|
||||
|
||||
--- Writes wrapped Text with special tags.
|
||||
--- @param obj object The object to write to
|
||||
--- @param x number X-Position
|
||||
--- @param y number Y-Position
|
||||
--- @param text string Text
|
||||
--- @param width number Width
|
||||
--- @param height number Height
|
||||
writeWrappedText = function(obj, x, y, text, width, height)
|
||||
local wrapped = wrapRichText(text, width)
|
||||
for _,v in pairs(wrapped)do
|
||||
if(v.y>height)then
|
||||
break
|
||||
end
|
||||
if(v.text~=nil)then
|
||||
obj:addText(x+v.x-1, y+v.y-1, v.text)
|
||||
end
|
||||
if(v.color~=nil)then
|
||||
obj:addFG(x+v.x-1, y+v.y-1, tHex[colors[v.color] ]:rep(#v.text))
|
||||
end
|
||||
if(v.bgColor~=nil)then
|
||||
obj:addBG(x+v.x-1, y+v.y-1, tHex[colors[v.bgColor] ]:rep(#v.text))
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
shrink = function(image, bgCol)
|
||||
local results, width, height, bgCol = {{}, {}, {}}, 0, #image + #image % 3, bgCol or colours.black
|
||||
for i = 1, #image do if #image[i] > width then width = #image[i] end end
|
||||
|
||||
for y = 0, height - 1, 3 do
|
||||
local cRow, tRow, bRow, counter = {}, {}, {}, 1
|
||||
|
||||
for x = 0, width - 1, 2 do
|
||||
-- Grab a 2x3 chunk:
|
||||
local pattern, totals = {}, {}
|
||||
|
||||
for yy = 1, 3 do for xx = 1, 2 do
|
||||
pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol
|
||||
totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1
|
||||
end end
|
||||
|
||||
cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals)
|
||||
counter = counter + 1
|
||||
end
|
||||
|
||||
results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow)
|
||||
end
|
||||
|
||||
results.width, results.height = #results[1][1], #results[1]
|
||||
|
||||
return results
|
||||
end,
|
||||
--- Returns a random UUID.
|
||||
--- @return string UUID.
|
||||
uuid = function()
|
||||
return string.gsub(string.format('%x-%x-%x-%x-%x', math.random(0, 0xffff), math.random(0, 0xffff), math.random(0, 0xffff), math.random(0, 0x0fff) + 0x4000, math.random(0, 0x3fff) + 0x8000), ' ', '0')
|
||||
end
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
local _OBJECTS = {}
|
||||
|
||||
if(packaged)then
|
||||
for k,v in pairs(getProject("objects"))do
|
||||
_OBJECTS[k] = v()
|
||||
@@ -13,7 +14,7 @@ if(dir==nil)then
|
||||
end
|
||||
|
||||
for _,v in pairs(fs.list(fs.combine(dir, "objects")))do
|
||||
if(v~="example.lua")then
|
||||
if(v~="example.lua")and not(v:find(".disabled"))then
|
||||
local name = v:gsub(".lua", "")
|
||||
_OBJECTS[name] = require(name)
|
||||
end
|
||||
|
||||
281
Basalt/main.lua
@@ -1,20 +1,21 @@
|
||||
local basaltEvent = require("basaltEvent")()
|
||||
local Frame = require("Frame")
|
||||
local theme = require("theme")
|
||||
local _OBJECTS = require("loadObjects")
|
||||
local pluginSystem = require("plugin")
|
||||
local utils = require("utils")
|
||||
local log = require("basaltLogs")
|
||||
local uuid = utils.uuid
|
||||
local createText = utils.createText
|
||||
local wrapText = utils.wrapText
|
||||
local count = utils.tableCount
|
||||
local moveThrottle = 300
|
||||
local dragThrottle = 50
|
||||
local dragThrottle = 0
|
||||
local renderingThrottle = 0
|
||||
|
||||
local baseTerm = term.current()
|
||||
local version = "1.6.4"
|
||||
local version = "1.7.0"
|
||||
|
||||
local projectDirectory = fs.getDir(table.pack(...)[2] or "")
|
||||
|
||||
local activeKey, frames, monFrames, monGroups, variables, schedules = {}, {}, {}, {}, {}, {}
|
||||
local activeKey, frames, monFrames, variables, schedules = {}, {}, {}, {}, {}
|
||||
local mainFrame, activeFrame, focusedObject, updaterActive
|
||||
|
||||
local basalt = {}
|
||||
@@ -42,39 +43,23 @@ local function stop()
|
||||
end
|
||||
end
|
||||
|
||||
local function basaltError(errMsg)
|
||||
baseTerm.clear()
|
||||
baseTerm.setBackgroundColor(colors.black)
|
||||
baseTerm.setTextColor(colors.red)
|
||||
local w,h = baseTerm.getSize()
|
||||
if(basalt.logging)then
|
||||
log(errMsg, "Error")
|
||||
end
|
||||
|
||||
local text = createText("Basalt error: "..errMsg, w)
|
||||
local yPos = 1
|
||||
for k,v in pairs(text)do
|
||||
baseTerm.setCursorPos(1,yPos)
|
||||
baseTerm.write(v)
|
||||
yPos = yPos + 1
|
||||
end
|
||||
baseTerm.setCursorPos(1,yPos+1)
|
||||
updaterActive = false
|
||||
end
|
||||
|
||||
local function schedule(f)
|
||||
assert(f~="function", "Schedule needs a function in order to work!")
|
||||
return function(...)
|
||||
local co = coroutine.create(f)
|
||||
local ok, result = coroutine.resume(co, ...)
|
||||
if(ok)then
|
||||
table.insert(schedules, {co, result})
|
||||
table.insert(schedules, co)
|
||||
else
|
||||
basaltError(result)
|
||||
basalt.basaltError(result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
basalt.log = function(...)
|
||||
log(...)
|
||||
end
|
||||
|
||||
local setVariable = function(name, var)
|
||||
variables[name] = var
|
||||
end
|
||||
@@ -83,14 +68,6 @@ local getVariable = function(name)
|
||||
return variables[name]
|
||||
end
|
||||
|
||||
local setTheme = function(_theme)
|
||||
theme = _theme
|
||||
end
|
||||
|
||||
local getTheme = function(name)
|
||||
return theme[name]
|
||||
end
|
||||
|
||||
local bInstance = {
|
||||
getDynamicValueEventSetting = function()
|
||||
return basalt.dynamicValueEvents
|
||||
@@ -102,7 +79,6 @@ local bInstance = {
|
||||
|
||||
setVariable = setVariable,
|
||||
getVariable = getVariable,
|
||||
getTheme = getTheme,
|
||||
|
||||
setMainFrame = function(mFrame)
|
||||
mainFrame = mFrame
|
||||
@@ -140,7 +116,7 @@ local bInstance = {
|
||||
end
|
||||
end,
|
||||
|
||||
getBaseTerm = function()
|
||||
getTerm = function()
|
||||
return baseTerm
|
||||
end,
|
||||
|
||||
@@ -148,32 +124,51 @@ local bInstance = {
|
||||
|
||||
stop = stop,
|
||||
newFrame = Frame,
|
||||
debug = basalt.debug,
|
||||
log = basalt.log,
|
||||
|
||||
getObjects = function()
|
||||
return _OBJECTS
|
||||
end,
|
||||
|
||||
getObject = function(id)
|
||||
return _OBJECTS[id]
|
||||
end,
|
||||
|
||||
getDirectory = function()
|
||||
return projectDirectory
|
||||
end
|
||||
}
|
||||
|
||||
local function handleSchedules(event, ...)
|
||||
local function defaultErrorHandler(errMsg)
|
||||
baseTerm.clear()
|
||||
baseTerm.setBackgroundColor(colors.black)
|
||||
baseTerm.setTextColor(colors.red)
|
||||
local w,h = baseTerm.getSize()
|
||||
if(basalt.logging)then
|
||||
log(errMsg, "Error")
|
||||
end
|
||||
|
||||
local text = wrapText("Basalt error: "..errMsg, w)
|
||||
local yPos = 1
|
||||
for k,v in pairs(text)do
|
||||
baseTerm.setCursorPos(1,yPos)
|
||||
baseTerm.write(v)
|
||||
yPos = yPos + 1
|
||||
end
|
||||
baseTerm.setCursorPos(1,yPos+1)
|
||||
updaterActive = false
|
||||
end
|
||||
|
||||
local function handleSchedules(event, p1, p2, p3, p4)
|
||||
if(#schedules>0)then
|
||||
local finished = {}
|
||||
for n=1,#schedules do
|
||||
if(schedules[n]~=nil)then
|
||||
if (coroutine.status(schedules[n][1]) == "suspended")then
|
||||
if(schedules[n][2]~=nil)then
|
||||
if(schedules[n][2]==event)then
|
||||
local ok, result = coroutine.resume(schedules[n][1], event, ...)
|
||||
schedules[n][2] = result
|
||||
if not(ok)then
|
||||
basaltError(result)
|
||||
end
|
||||
end
|
||||
else
|
||||
local ok, result = coroutine.resume(schedules[n][1], event, ...)
|
||||
schedules[n][2] = result
|
||||
if not(ok)then
|
||||
basaltError(result)
|
||||
end
|
||||
if (coroutine.status(schedules[n]) == "suspended")then
|
||||
local ok, result = coroutine.resume(schedules[n], event, p1, p2, p3, p4)
|
||||
if not(ok)then
|
||||
basalt.basaltError(result)
|
||||
end
|
||||
else
|
||||
table.insert(finished, n)
|
||||
@@ -189,17 +184,13 @@ end
|
||||
local function drawFrames()
|
||||
if(updaterActive==false)then return end
|
||||
if(mainFrame~=nil)then
|
||||
mainFrame:draw()
|
||||
mainFrame:render()
|
||||
mainFrame:updateTerm()
|
||||
end
|
||||
for _,v in pairs(monFrames)do
|
||||
v:draw()
|
||||
v:render()
|
||||
v:updateTerm()
|
||||
end
|
||||
for _,v in pairs(monGroups)do
|
||||
v[1]:draw()
|
||||
v[1]:updateTerm()
|
||||
end
|
||||
end
|
||||
|
||||
local stopped, moveX, moveY = nil, nil, nil
|
||||
@@ -236,6 +227,23 @@ local function mouseDragEvent(_, b, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local renderingTimer = nil
|
||||
local function renderingUpdateTimer()
|
||||
renderingTimer = nil
|
||||
drawFrames()
|
||||
end
|
||||
|
||||
local function renderingUpdateEvent(timer)
|
||||
if(renderingThrottle<50)then
|
||||
drawFrames()
|
||||
else
|
||||
if(renderingTimer==nil)then
|
||||
renderingTimer = os.startTimer(renderingThrottle/1000)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function basaltUpdateEvent(event, ...)
|
||||
local a = {...}
|
||||
if(basaltEvent:sendEvent("basaltEventCycle", event, ...)==false)then return end
|
||||
@@ -252,23 +260,19 @@ local function basaltUpdateEvent(event, ...)
|
||||
if(mouseEvent~=nil)then
|
||||
mouseEvent(mainFrame, ...)
|
||||
handleSchedules(event, ...)
|
||||
drawFrames()
|
||||
renderingUpdateEvent()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if(event == "monitor_touch") then
|
||||
if(monFrames[a[1]]~=nil)then
|
||||
monFrames[a[1]]:mouseHandler(1, a[2], a[3], true)
|
||||
activeFrame = monFrames[a[1]]
|
||||
end
|
||||
if(count(monGroups)>0)then
|
||||
for k,v in pairs(monGroups)do
|
||||
v[1]:mouseHandler(1, a[2], a[3], true, a[1])
|
||||
for k,v in pairs(monFrames)do
|
||||
if(v:mouseHandler(1, a[2], a[3], true, a[1]))then
|
||||
activeFrame = v
|
||||
end
|
||||
end
|
||||
handleSchedules(event, ...)
|
||||
drawFrames()
|
||||
renderingUpdateEvent()
|
||||
return
|
||||
end
|
||||
|
||||
@@ -287,7 +291,7 @@ local function basaltUpdateEvent(event, ...)
|
||||
end
|
||||
keyEvent(activeFrame, ...)
|
||||
handleSchedules(event, ...)
|
||||
drawFrames()
|
||||
renderingUpdateEvent()
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -296,25 +300,51 @@ local function basaltUpdateEvent(event, ...)
|
||||
moveHandlerTimer()
|
||||
elseif(event=="timer")and(a[1]==dragTimer)then
|
||||
dragHandlerTimer()
|
||||
elseif(event=="timer")and(a[1]==renderingTimer)then
|
||||
renderingUpdateTimer()
|
||||
else
|
||||
for k, v in pairs(frames) do
|
||||
v:eventHandler(event, ...)
|
||||
end
|
||||
for k, v in pairs(monFrames) do
|
||||
v:eventHandler(event, ...)
|
||||
end
|
||||
handleSchedules(event, ...)
|
||||
renderingUpdateEvent()
|
||||
end
|
||||
handleSchedules(event, ...)
|
||||
drawFrames()
|
||||
end
|
||||
|
||||
local function createFrame(name)
|
||||
for _, v in pairs(frames) do
|
||||
if (v:getName() == name) then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
local newFrame = _OBJECTS["BaseFrame"](name, bInstance)
|
||||
newFrame:init()
|
||||
newFrame:load()
|
||||
newFrame:draw()
|
||||
table.insert(frames, newFrame)
|
||||
if(mainFrame==nil)and(newFrame:getName()~="basaltDebuggingFrame")then
|
||||
newFrame:show()
|
||||
end
|
||||
return newFrame
|
||||
end
|
||||
|
||||
basalt = {
|
||||
basaltError = defaultErrorHandler,
|
||||
logging = false,
|
||||
dynamicValueEvents = false,
|
||||
setTheme = setTheme,
|
||||
getTheme = getTheme,
|
||||
drawFrames = drawFrames,
|
||||
log = log,
|
||||
getVersion = function()
|
||||
return version
|
||||
end,
|
||||
|
||||
memory = function()
|
||||
return math.floor(collectgarbage("count")+0.5).."KB"
|
||||
end,
|
||||
|
||||
setVariable = setVariable,
|
||||
getVariable = getVariable,
|
||||
|
||||
@@ -322,8 +352,12 @@ basalt = {
|
||||
baseTerm = _baseTerm
|
||||
end,
|
||||
|
||||
log = function(...)
|
||||
log(...)
|
||||
resetPalette = function()
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
--baseTerm.setPaletteColor(v, colors.packRGB(table.unpack(defaultColors[k])))
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
setMouseMoveThrottle = function(amount)
|
||||
@@ -339,6 +373,15 @@ basalt = {
|
||||
return false
|
||||
end,
|
||||
|
||||
setRenderingThrottle = function(amount)
|
||||
if(amount<=0)then
|
||||
renderingThrottle = 0
|
||||
else
|
||||
renderingTimer = nil
|
||||
renderingThrottle = amount
|
||||
end
|
||||
end,
|
||||
|
||||
setMouseDragThrottle = function(amount)
|
||||
if(amount<=0)then
|
||||
dragThrottle = 0
|
||||
@@ -357,18 +400,20 @@ basalt = {
|
||||
basaltUpdateEvent(os.pullEventRaw())
|
||||
end
|
||||
end
|
||||
local ok, err = xpcall(f, debug.traceback)
|
||||
if not(ok)then
|
||||
basaltError(err)
|
||||
return
|
||||
while updaterActive do
|
||||
local ok, err = xpcall(f, debug.traceback)
|
||||
if not(ok)then
|
||||
basalt.basaltError(err)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
update = function(event, ...)
|
||||
if (event ~= nil) then
|
||||
local ok, err = xpcall(basaltUpdateEvent, debug.traceback, event, ...)
|
||||
local args = {...}
|
||||
local ok, err = xpcall(function() basaltUpdateEvent(event, table.unpack(args)) end, debug.traceback)
|
||||
if not(ok)then
|
||||
basaltError(err)
|
||||
basalt.basaltError(err)
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -395,12 +440,16 @@ basalt = {
|
||||
end,
|
||||
|
||||
setActiveFrame = function(frame)
|
||||
if (frame:getType() == "Frame") then
|
||||
if (frame:getType() == "Container") then
|
||||
activeFrame = frame
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
getMainFrame = function()
|
||||
return mainFrame
|
||||
end,
|
||||
|
||||
onEvent = function(...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
@@ -412,19 +461,20 @@ basalt = {
|
||||
|
||||
schedule = schedule,
|
||||
|
||||
createFrame = function(name)
|
||||
name = name or uuid()
|
||||
addFrame = createFrame,
|
||||
createFrame = createFrame,
|
||||
|
||||
addMonitor = function(name)
|
||||
for _, v in pairs(frames) do
|
||||
if (v.name == name) then
|
||||
if (v:getName() == name) then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
local newFrame = Frame(name,nil,nil,bInstance)
|
||||
local newFrame = _OBJECTS["MonitorFrame"](name, bInstance)
|
||||
newFrame:init()
|
||||
table.insert(frames, newFrame)
|
||||
if(mainFrame==nil)and(newFrame:getName()~="basaltDebuggingFrame")then
|
||||
newFrame:show()
|
||||
end
|
||||
newFrame:load()
|
||||
newFrame:draw()
|
||||
table.insert(monFrames, newFrame)
|
||||
return newFrame
|
||||
end,
|
||||
|
||||
@@ -435,37 +485,26 @@ basalt = {
|
||||
setProjectDir = function(dir)
|
||||
projectDirectory = dir
|
||||
end,
|
||||
|
||||
debug = function(...)
|
||||
local args = { ... }
|
||||
if(mainFrame==nil)then print(...) return end
|
||||
if (mainFrame.name ~= "basaltDebuggingFrame") then
|
||||
if (mainFrame ~= basalt.debugFrame) then
|
||||
basalt.debugLabel:setParent(mainFrame)
|
||||
end
|
||||
end
|
||||
local str = ""
|
||||
for key, value in pairs(args) do
|
||||
str = str .. tostring(value) .. (#args ~= key and ", " or "")
|
||||
end
|
||||
basalt.debugLabel:setText("[Debug] " .. str)
|
||||
for k,v in pairs(createText(str, basalt.debugList:getWidth()))do
|
||||
basalt.debugList:addItem(v)
|
||||
end
|
||||
if (basalt.debugList:getItemCount() > 50) then
|
||||
basalt.debugList:removeItem(1)
|
||||
end
|
||||
basalt.debugList:setValue(basalt.debugList:getItem(basalt.debugList:getItemCount()))
|
||||
if(basalt.debugList.getItemCount() > basalt.debugList:getHeight())then
|
||||
basalt.debugList:setOffset(basalt.debugList:getItemCount() - basalt.debugList:getHeight())
|
||||
end
|
||||
basalt.debugLabel:show()
|
||||
end,
|
||||
}
|
||||
|
||||
basalt.debugFrame = basalt.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug", colors.black, colors.gray)
|
||||
basalt.debugFrame:addButton("back"):setAnchor("topRight"):setSize(1, 1):setText("\22"):onClick(function() if(basalt.oldFrame~=nil)then basalt.oldFrame:show() end end):setBackground(colors.red):show()
|
||||
basalt.debugList = basalt.debugFrame:addList("debugList"):setSize("parent.w - 2", "parent.h - 3"):setPosition(2, 3):setScrollable(true):show()
|
||||
basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() basalt.oldFrame = mainFrame basalt.debugFrame:show() end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottomLeft"):ignoreOffset():setZIndex(20):show()
|
||||
_OBJECTS = pluginSystem.addPlugins(_OBJECTS, bInstance)
|
||||
|
||||
local basaltPlugins = pluginSystem.get("basalt")
|
||||
if(basaltPlugins~=nil)then
|
||||
for k,v in pairs(basaltPlugins)do
|
||||
for a,b in pairs(v(basalt))do
|
||||
basalt[a] = b
|
||||
bInstance[a] = b
|
||||
end
|
||||
end
|
||||
end
|
||||
local basaltPlugins = pluginSystem.get("basaltInternal")
|
||||
if(basaltPlugins~=nil)then
|
||||
for k,v in pairs(basaltPlugins)do
|
||||
for a,b in pairs(v(basalt))do
|
||||
bInstance[a] = b
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return basalt
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
return function(path)
|
||||
local exists, content = pcall(require, path)
|
||||
return exists and content or nil
|
||||
end
|
||||
@@ -1,6 +1,3 @@
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local basaltEvent = require("basaltEvent")
|
||||
|
||||
local floor,sin,cos,pi,sqrt,pow = math.floor,math.sin,math.cos,math.pi,math.sqrt,math.pow
|
||||
|
||||
-- You can find the easing curves here https://easings.net
|
||||
@@ -222,7 +219,8 @@ local lerp = {
|
||||
|
||||
local activeAnimations = {}
|
||||
|
||||
return function(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Object")(name, basalt)
|
||||
local object = {}
|
||||
local objectType = "Animation"
|
||||
|
||||
@@ -234,8 +232,6 @@ return function(name)
|
||||
local index = 1
|
||||
local infinitePlay = false
|
||||
|
||||
local eventSystem = basaltEvent()
|
||||
|
||||
local nextWaitTimer = 0
|
||||
local lastFunc
|
||||
local loop=false
|
||||
@@ -306,7 +302,7 @@ return function(name)
|
||||
local obj = _OBJ
|
||||
local x,y
|
||||
local name = ""
|
||||
if(obj.parent~=nil)then name = obj.parent:getName() end
|
||||
if(obj:getParent()~=nil)then name = obj:getParent():getName() end
|
||||
name = name..obj:getName()
|
||||
addAnimationPart(t+0.05, function()
|
||||
if(typ~=nil)then
|
||||
@@ -340,14 +336,7 @@ return function(name)
|
||||
name = name,
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
getBaseFrame = function(self)
|
||||
if(self.parent~=nil)then
|
||||
return self.parent:getBaseFrame()
|
||||
end
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setMode = function(self, newMode)
|
||||
mode = newMode
|
||||
@@ -359,124 +348,6 @@ return function(name)
|
||||
return self
|
||||
end,
|
||||
|
||||
generateXMLEventFunction = function(self, func, val)
|
||||
local createF = function(str)
|
||||
if(str:sub(1,1)=="#")then
|
||||
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
|
||||
if(o~=nil)and(o.internalObjetCall~=nil)then
|
||||
func(self,function()o:internalObjetCall()end)
|
||||
end
|
||||
else
|
||||
func(self,self:getBaseFrame():getVariable(str))
|
||||
end
|
||||
end
|
||||
if(type(val)=="string")then
|
||||
createF(val)
|
||||
elseif(type(val)=="table")then
|
||||
for k,v in pairs(val)do
|
||||
createF(v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
loop = xmlValue("loop", data)==true and true or false
|
||||
if(xmlValue("object", data)~=nil)then
|
||||
local o = self:getBaseFrame():getDeepObject(xmlValue("object", data))
|
||||
if(o==nil)then
|
||||
o = self:getBaseFrame():getVariable(xmlValue("object", data))
|
||||
end
|
||||
if(o~=nil)then
|
||||
self:setObject(o)
|
||||
end
|
||||
end
|
||||
if(data["move"]~=nil)then
|
||||
local x = xmlValue("x", data["move"])
|
||||
local y = xmlValue("y", data["move"])
|
||||
local duration = xmlValue("duration", data["move"])
|
||||
local time = xmlValue("time", data["move"])
|
||||
self:move(x, y, duration, time)
|
||||
end
|
||||
if(data["size"]~=nil)then
|
||||
local w = xmlValue("width", data["size"])
|
||||
local h = xmlValue("height", data["size"])
|
||||
local duration = xmlValue("duration", data["size"])
|
||||
local time = xmlValue("time", data["size"])
|
||||
self:size(w, h, duration, time)
|
||||
end
|
||||
if(data["offset"]~=nil)then
|
||||
local x = xmlValue("x", data["offset"])
|
||||
local y = xmlValue("y", data["offset"])
|
||||
local duration = xmlValue("duration", data["offset"])
|
||||
local time = xmlValue("time", data["offset"])
|
||||
self:offset(x, y, duration, time)
|
||||
end
|
||||
if(data["textColor"]~=nil)then
|
||||
local duration = xmlValue("duration", data["textColor"])
|
||||
local timer = xmlValue("time", data["textColor"])
|
||||
local t = {}
|
||||
local tab = data["textColor"]["color"]
|
||||
if(tab~=nil)then
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
table.insert(t, colors[v:value()])
|
||||
end
|
||||
end
|
||||
if(duration~=nil)and(#t>0)then
|
||||
self:changeTextColor(duration, timer or 0, table.unpack(t))
|
||||
end
|
||||
end
|
||||
if(data["background"]~=nil)then
|
||||
local duration = xmlValue("duration", data["background"])
|
||||
local timer = xmlValue("time", data["background"])
|
||||
local t = {}
|
||||
local tab = data["background"]["color"]
|
||||
if(tab~=nil)then
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
table.insert(t, colors[v:value()])
|
||||
end
|
||||
end
|
||||
if(duration~=nil)and(#t>0)then
|
||||
self:changeBackground(duration, timer or 0, table.unpack(t))
|
||||
end
|
||||
end
|
||||
if(data["text"]~=nil)then
|
||||
local duration = xmlValue("duration", data["text"])
|
||||
local timer = xmlValue("time", data["text"])
|
||||
local t = {}
|
||||
local tab = data["text"]["text"]
|
||||
if(tab~=nil)then
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
table.insert(t, v:value())
|
||||
end
|
||||
end
|
||||
if(duration~=nil)and(#t>0)then
|
||||
self:changeText(duration, timer or 0, table.unpack(t))
|
||||
end
|
||||
end
|
||||
if(xmlValue("onDone", data)~=nil)then self:generateXMLEventFunction(self.onDone, xmlValue("onDone", data)) end
|
||||
if(xmlValue("onStart", data)~=nil)then self:generateXMLEventFunction(self.onDone, xmlValue("onStart", data)) end
|
||||
if(xmlValue("autoDestroy", data)~=nil)then
|
||||
if(xmlValue("autoDestroy", data))then
|
||||
autoDestroy = true
|
||||
end
|
||||
end
|
||||
mode = xmlValue("mode", data) or mode
|
||||
if(xmlValue("play", data)~=nil)then if(xmlValue("play", data))then self:play(loop) end end
|
||||
return self
|
||||
end,
|
||||
|
||||
getZIndex = function(self)
|
||||
return 1
|
||||
end;
|
||||
|
||||
getName = function(self)
|
||||
return self.name
|
||||
end;
|
||||
|
||||
setObject = function(self, obj)
|
||||
_OBJ = obj
|
||||
return self
|
||||
@@ -557,12 +428,12 @@ return function(name)
|
||||
end;
|
||||
|
||||
onDone = function(self, f)
|
||||
eventSystem:registerEvent("animation_done", f)
|
||||
self:registerEvent("animation_done", f)
|
||||
return self
|
||||
end,
|
||||
|
||||
onStart = function(self, f)
|
||||
eventSystem:registerEvent("animation_start", f)
|
||||
self:registerEvent("animation_start", f)
|
||||
return self
|
||||
end,
|
||||
|
||||
@@ -572,16 +443,16 @@ return function(name)
|
||||
end,
|
||||
|
||||
animationDoneHandler = function(self)
|
||||
eventSystem:sendEvent("animation_done", self)
|
||||
self.parent:removeEvent("other_event", self)
|
||||
self:sendEvent("animation_done", self)
|
||||
self:listenEvent("other_event", false)
|
||||
if(autoDestroy)then
|
||||
self.parent:removeObject(self)
|
||||
self:getParent():removeObject(self)
|
||||
self = nil
|
||||
end
|
||||
end;
|
||||
|
||||
animationStartHandler = function(self)
|
||||
eventSystem:sendEvent("animation_start", self)
|
||||
self:sendEvent("animation_start", self)
|
||||
end;
|
||||
|
||||
clear = function(self)
|
||||
@@ -609,7 +480,7 @@ return function(name)
|
||||
else
|
||||
self:animationDoneHandler()
|
||||
end
|
||||
self.parent:addEvent("other_event", self)
|
||||
self:listenEvent("other_event")
|
||||
return self
|
||||
end;
|
||||
|
||||
@@ -619,7 +490,7 @@ return function(name)
|
||||
infinitePlay = false
|
||||
end
|
||||
animationActive = false
|
||||
self.parent:removeEvent("other_event", self)
|
||||
self:listenEvent("other_event", false)
|
||||
return self
|
||||
end;
|
||||
|
||||
@@ -639,7 +510,7 @@ return function(name)
|
||||
end
|
||||
end;
|
||||
}
|
||||
object.__index = object
|
||||
|
||||
return object
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
215
Basalt/objects/BaseFrame.lua
Normal file
@@ -0,0 +1,215 @@
|
||||
local drawSystem = require("basaltDraw")
|
||||
local utils = require("utils")
|
||||
|
||||
local max,min,sub,rep = math.max,math.min,string.sub,string.rep
|
||||
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Container")(name, basalt)
|
||||
local objectType = "BaseFrame"
|
||||
|
||||
local xOffset, yOffset = 0, 0
|
||||
|
||||
local colorTheme = {}
|
||||
|
||||
local updateRender = true
|
||||
|
||||
local termObject = basalt.getTerm()
|
||||
local basaltDraw = drawSystem(termObject)
|
||||
|
||||
local xCursor, yCursor, cursorBlink, cursorColor = 1, 1, false, colors.white
|
||||
|
||||
local object = {
|
||||
getType = function()
|
||||
return objectType
|
||||
end,
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return xOffset, yOffset
|
||||
end,
|
||||
|
||||
setOffset = function(self, xOff, yOff)
|
||||
xOffset = xOff or xOffset
|
||||
yOffset = yOff or yOffset
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setPalette = function(self, col, ...)
|
||||
if(self==basalt.getActiveFrame())then
|
||||
if(type(col)=="string")then
|
||||
colorTheme[col] = ...
|
||||
termObject.setPaletteColor(type(col)=="number" and col or colors[col], ...)
|
||||
elseif(type(col)=="table")then
|
||||
for k,v in pairs(col)do
|
||||
colorTheme[k] = v
|
||||
if(type(v)=="number")then
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
|
||||
else
|
||||
local r,g,b = table.unpack(v)
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setSize = function(self, ...)
|
||||
base.setSize(self, ...)
|
||||
basaltDraw = drawSystem(termObject)
|
||||
return self
|
||||
end,
|
||||
|
||||
getSize = function()
|
||||
return termObject.getSize()
|
||||
end,
|
||||
|
||||
getWidth = function(self)
|
||||
return ({termObject.getSize()})[1]
|
||||
end,
|
||||
|
||||
getHeight = function(self)
|
||||
return ({termObject.getSize()})[2]
|
||||
end,
|
||||
|
||||
show = function(self)
|
||||
base.show(self)
|
||||
basalt.setActiveFrame(self)
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
termObject.setPaletteColor(v, colors.packRGB(term.nativePaletteColor((v))))
|
||||
end
|
||||
end
|
||||
for k,v in pairs(colorTheme)do
|
||||
if(type(v)=="number")then
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
|
||||
else
|
||||
local r,g,b = table.unpack(v)
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
|
||||
end
|
||||
end
|
||||
basalt.setMainFrame(self)
|
||||
return self
|
||||
end,
|
||||
|
||||
render = function(self)
|
||||
if(base.render~=nil)then
|
||||
if(self:isVisible())then
|
||||
if(updateRender)then
|
||||
base.render(self)
|
||||
local objects = self:getObjects()
|
||||
for _, obj in ipairs(objects) do
|
||||
if (obj.element.render ~= nil) then
|
||||
obj.element:render()
|
||||
end
|
||||
end
|
||||
updateRender = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
updateDraw = function(self)
|
||||
updateRender = true
|
||||
return self
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, ...)
|
||||
base.eventHandler(self, event, ...)
|
||||
if(event=="term_resize")then
|
||||
self:setSize(termObject.getSize())
|
||||
end
|
||||
end,
|
||||
|
||||
updateTerm = function(self)
|
||||
if(basaltDraw~=nil)then
|
||||
basaltDraw.update()
|
||||
end
|
||||
end,
|
||||
|
||||
setTerm = function(self, newTerm)
|
||||
termObject = newTerm
|
||||
if(newTerm==nil)then
|
||||
basaltDraw = nil
|
||||
else
|
||||
basaltDraw = drawSystem(termObject)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
getTerm = function()
|
||||
return termObject
|
||||
end,
|
||||
|
||||
blit = function (self, x, y, t, f, b)
|
||||
local obx, oby = self:getPosition()
|
||||
local w, h = self:getSize()
|
||||
if y >= 1 and y <= h then
|
||||
local t_visible = sub(t, max(1 - x + 1, 1), max(w - x + 1, 1))
|
||||
local f_visible = sub(f, max(1 - x + 1, 1), max(w - x + 1, 1))
|
||||
local b_visible = sub(b, max(1 - x + 1, 1), max(w - x + 1, 1))
|
||||
basaltDraw.blit(max(x + (obx - 1), obx), oby + y - 1, t_visible, f_visible, b_visible)
|
||||
end
|
||||
end,
|
||||
|
||||
setCursor = function(self, _blink, _xCursor, _yCursor, color)
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local xO, yO = self:getOffset()
|
||||
cursorBlink = _blink or false
|
||||
if (_xCursor ~= nil) then
|
||||
xCursor = obx + _xCursor - 1 - xO
|
||||
end
|
||||
if (_yCursor ~= nil) then
|
||||
yCursor = oby + _yCursor - 1 - yO
|
||||
end
|
||||
cursorColor = color or cursorColor
|
||||
if (cursorBlink) then
|
||||
termObject.setTextColor(cursorColor)
|
||||
termObject.setCursorPos(xCursor, yCursor)
|
||||
termObject.setCursorBlink(cursorBlink)
|
||||
else
|
||||
termObject.setCursorBlink(false)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
}
|
||||
|
||||
for k,v in pairs({mouse_click={"mouseHandler", true},mouse_up={"mouseUpHandler", false},mouse_drag={"dragHandler", false},mouse_scroll={"scrollHandler", true},mouse_hover={"hoverHandler", false}})do
|
||||
object[v[1]] = function(self, btn, x, y, ...)
|
||||
if(base[v[1]](self, btn, x, y, ...))then
|
||||
basalt.setActiveFrame(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs({"drawBackgroundBox", "drawForegroundBox", "drawTextBox"})do
|
||||
object[v] = function(self, x, y, width, height, symbol)
|
||||
local obx, oby = self:getPosition()
|
||||
local w, h = self:getSize()
|
||||
height = (y < 1 and (height + y > self:getHeight() and self:getHeight() or height + y - 1) or (height + y > self:getHeight() and self:getHeight() - y + 1 or height))
|
||||
width = (x < 1 and (width + x > self:getWidth() and self:getWidth() or width + x - 1) or (width + x > self:getWidth() and self:getWidth() - x + 1 or width))
|
||||
basaltDraw[v](max(x + (obx - 1), obx), max(y + (oby - 1), oby), width, height, symbol)
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs({"setBG", "setFG", "setText"}) do
|
||||
object[v] = function(self, x, y, str)
|
||||
local obx, oby = self:getPosition()
|
||||
local w, h = self:getSize()
|
||||
if (y >= 1) and (y <= h) then
|
||||
basaltDraw[v](max(x + (obx - 1), obx), oby + y - 1, sub(str, max(1 - x + 1, 1), max(w - x + 1,1)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,74 +1,65 @@
|
||||
local Object = require("Object")
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
return function(name, basalt)
|
||||
-- Button
|
||||
local base = Object(name)
|
||||
local base = basalt.getObject("VisualObject")(name, basalt)
|
||||
local objectType = "Button"
|
||||
local textHorizontalAlign = "center"
|
||||
local textVerticalAlign = "center"
|
||||
|
||||
local text = "Button"
|
||||
|
||||
base:setSize(12, 3)
|
||||
base:setZIndex(5)
|
||||
base:setValue("Button")
|
||||
base.width = 12
|
||||
base.height = 3
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ButtonBG")
|
||||
self.fgColor = self.parent:getTheme("ButtonText")
|
||||
end
|
||||
end,
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
setHorizontalAlign = function(self, pos)
|
||||
textHorizontalAlign = pos
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setVerticalAlign = function(self, pos)
|
||||
textVerticalAlign = pos
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setText = function(self, text)
|
||||
base:setValue(tostring(text))
|
||||
setText = function(self, newText)
|
||||
text = newText
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end
|
||||
if(xmlValue("horizontalAlign", data)~=nil)then textHorizontalAlign = xmlValue("horizontalAlign", data) end
|
||||
if(xmlValue("verticalAlign", data)~=nil)then textVerticalAlign = xmlValue("verticalAlign", data) end
|
||||
return self
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
|
||||
|
||||
for n = 1, h do
|
||||
if (n == verticalAlign) then
|
||||
local val = self:getValue()
|
||||
self.parent:setText(obx + (w/2-val:len()/2), oby + (n - 1), utils.getTextHorizontalAlign(val, val:len(), textHorizontalAlign))
|
||||
self.parent:setFG(obx + (w/2-val:len()/2), oby + (n - 1), utils.getTextHorizontalAlign(tHex[self.fgColor]:rep(val:len()), val:len(), textHorizontalAlign))
|
||||
end
|
||||
end
|
||||
base.draw(self)
|
||||
self:addDraw("button", function()
|
||||
local w,h = self:getSize()
|
||||
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
|
||||
local xOffset
|
||||
if(textHorizontalAlign=="center")then
|
||||
xOffset = math.floor((w - text:len()) / 2)
|
||||
elseif(textHorizontalAlign=="right")then
|
||||
xOffset = w - text:len()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
self:addText(xOffset + 1, verticalAlign, text)
|
||||
self:addFG(xOffset + 1, verticalAlign, tHex[self:getForeground() or colors.white]:rep(text:len()))
|
||||
end)
|
||||
end,
|
||||
}
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
40
Basalt/objects/ChangeableObject.lua
Normal file
@@ -0,0 +1,40 @@
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("VisualObject")(name, basalt)
|
||||
-- Base object
|
||||
local objectType = "ChangeableObject"
|
||||
|
||||
local value
|
||||
|
||||
local object = {
|
||||
setValue = function(self, _value, valueChangedHandler)
|
||||
if (value ~= _value) then
|
||||
value = _value
|
||||
self:updateDraw()
|
||||
if(valueChangedHandler~=false)then
|
||||
self:valueChangedHandler()
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
getValue = function(self)
|
||||
return value
|
||||
end,
|
||||
|
||||
onChange = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("value_changed", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
valueChangedHandler = function(self)
|
||||
self:sendEvent("value_changed", value)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,31 +1,53 @@
|
||||
local Object = require("Object")
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
return function(name, basalt)
|
||||
-- Checkbox
|
||||
local base = Object(name)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "Checkbox"
|
||||
|
||||
base:setZIndex(5)
|
||||
base:setValue(false)
|
||||
base.width = 1
|
||||
base.height = 1
|
||||
base:setSize(1, 1)
|
||||
|
||||
local symbol = "\42"
|
||||
local symbol,inactiveSymbol,text,textPos = "\42"," ","","right"
|
||||
|
||||
local object = {
|
||||
load = function(self)
|
||||
self:listenEvent("mouse_click", self)
|
||||
self:listenEvent("mouse_up", self)
|
||||
end,
|
||||
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
setSymbol = function(self, sym)
|
||||
symbol = sym
|
||||
setSymbol = function(self, sym, inactive)
|
||||
symbol = sym or symbol
|
||||
inactiveSymbol = inactive or inactiveSymbol
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getSymbol = function(self)
|
||||
return symbol, inactiveSymbol
|
||||
end,
|
||||
|
||||
setText = function(self, _text)
|
||||
text = _text
|
||||
return self
|
||||
end,
|
||||
|
||||
setTextPosition = function(self, pos)
|
||||
textPos = pos or textPos
|
||||
return self
|
||||
end,
|
||||
|
||||
setChecked = base.setValue,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if (base.mouseHandler(self, button, x, y)) then
|
||||
if(button == 1)then
|
||||
@@ -41,45 +63,26 @@ return function(name)
|
||||
return false
|
||||
end,
|
||||
|
||||
touchHandler = function(self, x, y)
|
||||
return self:mouseHandler(1, x, y)
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("checked", data)~=nil)then if(xmlValue("checked", data))then self:setValue(true) else self:setValue(false) end end
|
||||
return self
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
local verticalAlign = utils.getTextVerticalAlign(h, "center")
|
||||
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
|
||||
for n = 1, h do
|
||||
if (n == verticalAlign) then
|
||||
if (self:getValue() == true) then
|
||||
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(symbol, w, "center"), self.bgColor, self.fgColor)
|
||||
else
|
||||
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(" ", w, "center"), self.bgColor, self.fgColor)
|
||||
end
|
||||
end
|
||||
end
|
||||
base.draw(self)
|
||||
self:addDraw("checkbox", function()
|
||||
local obx, oby = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
local verticalAlign = utils.getTextVerticalAlign(h, "center")
|
||||
local bg,fg = self:getBackground(), self:getForeground()
|
||||
if (self:getValue()) then
|
||||
self:addBlit(1, verticalAlign, utils.getTextHorizontalAlign(symbol, w, "center"), tHex[fg], tHex[bg])
|
||||
else
|
||||
self:addBlit(1, verticalAlign, utils.getTextHorizontalAlign(inactiveSymbol, w, "center"), tHex[fg], tHex[bg])
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("CheckboxBG")
|
||||
self.fgColor = self.parent:getTheme("CheckboxText")
|
||||
end
|
||||
if(text~="")then
|
||||
local align = textPos=="left" and -text:len() or 3
|
||||
self:addText(align, verticalAlign, text)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
395
Basalt/objects/Container.lua
Normal file
@@ -0,0 +1,395 @@
|
||||
local utils = require("utils")
|
||||
local tableCount = utils.tableCount
|
||||
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("VisualObject")(name, basalt)
|
||||
local objectType = "Container"
|
||||
|
||||
local elements = {}
|
||||
|
||||
local events = {}
|
||||
|
||||
local container = {}
|
||||
|
||||
local focusedObject
|
||||
local sorted = true
|
||||
local objId, evId = 0, 0
|
||||
|
||||
local objSort = function(a, b)
|
||||
if a.zIndex == b.zIndex then
|
||||
return a.objId < b.objId
|
||||
else
|
||||
return a.zIndex < b.zIndex
|
||||
end
|
||||
end
|
||||
local evSort = function(a, b)
|
||||
if a.zIndex == b.zIndex then
|
||||
return a.evId > b.evId
|
||||
else
|
||||
return a.zIndex > b.zIndex
|
||||
end
|
||||
end
|
||||
|
||||
local function getObject(self, name)
|
||||
if(type(name)=="table")then name = name:getName() end
|
||||
for i, v in ipairs(elements) do
|
||||
if v.element:getName() == name then
|
||||
return v.element
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function getDeepObject(self, name)
|
||||
local o = getObject(name)
|
||||
if(o~=nil)then return o end
|
||||
for _, value in pairs(objects) do
|
||||
if (b:getType() == "Container") then
|
||||
local oF = b:getDeepObject(name)
|
||||
if(oF~=nil)then return oF end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function addObject(self, element, el2)
|
||||
if (getObject(element:getName()) ~= nil) then
|
||||
return
|
||||
end
|
||||
objId = objId + 1
|
||||
local zIndex = element:getZIndex()
|
||||
table.insert(elements, {element = element, zIndex = zIndex, objId = objId})
|
||||
sorted = false
|
||||
element:setParent(self, true)
|
||||
if(element.init~=nil)then element:init() end
|
||||
if(element.load~=nil)then element:load() end
|
||||
if(element.draw~=nil)then element:draw() end
|
||||
return element
|
||||
end
|
||||
|
||||
local function updateZIndex(self, element, newZ)
|
||||
objId = objId + 1
|
||||
evId = evId + 1
|
||||
for _,v in pairs(elements)do
|
||||
if(v.element==element)then
|
||||
v.zIndex = newZ
|
||||
v.objId = objId
|
||||
break
|
||||
end
|
||||
end
|
||||
for _,v in pairs(events)do
|
||||
for a,b in pairs(v)do
|
||||
if(b.element==element)then
|
||||
b.zIndex = newZ
|
||||
b.evId = evId
|
||||
end
|
||||
end
|
||||
end
|
||||
sorted = false
|
||||
self:updateDraw()
|
||||
end
|
||||
|
||||
local function removeObject(self, element)
|
||||
if(type(element)=="string")then element = getObject(element:getName()) end
|
||||
if(element==nil)then return end
|
||||
for i, v in ipairs(elements) do
|
||||
if v.element == element then
|
||||
table.remove(elements, i)
|
||||
return true
|
||||
end
|
||||
end
|
||||
sorted = false
|
||||
end
|
||||
|
||||
local function removeEvents(self, element)
|
||||
local parent = self:getParent()
|
||||
for a, b in pairs(events) do
|
||||
for c, d in pairs(b) do
|
||||
if(d.element == element)then
|
||||
table.remove(events[a], c)
|
||||
end
|
||||
end
|
||||
if(tableCount(events[a])<=0)then
|
||||
if(parent~=nil)then
|
||||
parent:removeEvent(a, self)
|
||||
end
|
||||
end
|
||||
end
|
||||
sorted = false
|
||||
end
|
||||
|
||||
local function getEvent(self, event, name)
|
||||
if(type(name)=="table")then name = name:getName() end
|
||||
if(events[event]~=nil)then
|
||||
for _, obj in pairs(events[event]) do
|
||||
if (obj.element:getName() == name) then
|
||||
return obj
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function addEvent(self, event, element)
|
||||
if (getEvent(self, event, element:getName()) ~= nil) then
|
||||
return
|
||||
end
|
||||
local zIndex = element:getZIndex()
|
||||
evId = evId + 1
|
||||
if(events[event]==nil)then events[event] = {} end
|
||||
table.insert(events[event], {element = element, zIndex = zIndex, evId = evId})
|
||||
sorted = false
|
||||
self:listenEvent(event)
|
||||
return element
|
||||
end
|
||||
|
||||
local function removeEvent(self, event, element)
|
||||
if(events[event]~=nil)then
|
||||
for a, b in pairs(events[event]) do
|
||||
if(b.element == element)then
|
||||
table.remove(events[event], a)
|
||||
end
|
||||
end
|
||||
if(tableCount(events[event])<=0)then
|
||||
self:listenEvent(event, false)
|
||||
end
|
||||
end
|
||||
sorted = false
|
||||
end
|
||||
|
||||
local function getObjects(self)
|
||||
self:sortElementOrder()
|
||||
return elements
|
||||
end
|
||||
|
||||
local function getEvents(self, event)
|
||||
return event~=nil and events[event] or events
|
||||
end
|
||||
|
||||
container = {
|
||||
getType = function()
|
||||
return objectType
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
setSize = function(self, ...)
|
||||
base.setSize(self, ...)
|
||||
self:customEventHandler("basalt_FrameResize")
|
||||
return self
|
||||
end,
|
||||
|
||||
setPosition = function(self, ...)
|
||||
base.setPosition(self, ...)
|
||||
self:customEventHandler("basalt_FrameReposition")
|
||||
return self
|
||||
end,
|
||||
|
||||
searchObjects = function(self, name)
|
||||
local t = {}
|
||||
for k,v in pairs(elements)do
|
||||
if(string.find(k:getName(), name))then
|
||||
table.insert(t, v)
|
||||
end
|
||||
end
|
||||
return t
|
||||
end,
|
||||
|
||||
getObjectsByType = function(self, t)
|
||||
local t = {}
|
||||
for k,v in pairs(elements)do
|
||||
if(v:isType(t))then
|
||||
table.insert(t, v)
|
||||
end
|
||||
end
|
||||
return t
|
||||
end,
|
||||
|
||||
setImportant = function(self, element)
|
||||
objId = objId + 1
|
||||
evId = evId + 1
|
||||
for a, b in pairs(events) do
|
||||
for c, d in pairs(b) do
|
||||
if(d.element == element)then
|
||||
d.evId = evId
|
||||
table.remove(events[a], c)
|
||||
table.insert(events[a], d)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
for i, v in ipairs(elements) do
|
||||
if v.element == element then
|
||||
v.objId = objId
|
||||
table.remove(elements, i)
|
||||
table.insert(elements, v)
|
||||
break
|
||||
end
|
||||
end
|
||||
if(self.updateDraw~=nil)then
|
||||
self:updateDraw()
|
||||
end
|
||||
sorted = false
|
||||
end,
|
||||
|
||||
sortElementOrder = function(self)
|
||||
if(sorted)then return end
|
||||
table.sort(elements, objSort)
|
||||
for a, b in pairs(events) do
|
||||
table.sort(events[a], evSort)
|
||||
end
|
||||
sorted = true
|
||||
end,
|
||||
|
||||
removeFocusedObject = function(self)
|
||||
if(focusedObject~=nil)then
|
||||
if(getObject(self, focusedObject)~=nil)then
|
||||
focusedObject:loseFocusHandler()
|
||||
end
|
||||
end
|
||||
focusedObject = nil
|
||||
return self
|
||||
end,
|
||||
|
||||
setFocusedObject = function(self, obj)
|
||||
if(focusedObject~=obj)then
|
||||
if(focusedObject~=nil)then
|
||||
if(getObject(self, focusedObject)~=nil)then
|
||||
focusedObject:loseFocusHandler()
|
||||
end
|
||||
end
|
||||
if(obj~=nil)then
|
||||
if(getObject(self, obj)~=nil)then
|
||||
obj:getFocusHandler()
|
||||
end
|
||||
end
|
||||
focusedObject = obj
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
getFocusedObject = function(self)
|
||||
return focusedObject
|
||||
end,
|
||||
|
||||
getObject = getObject,
|
||||
getObjects = getObjects,
|
||||
getDeepObject = getDeepObject,
|
||||
addObject = addObject,
|
||||
removeObject = removeObject,
|
||||
getEvents = getEvents,
|
||||
getEvent = getEvent,
|
||||
addEvent = addEvent,
|
||||
removeEvent = removeEvent,
|
||||
removeEvents = removeEvents,
|
||||
updateZIndex = updateZIndex,
|
||||
|
||||
listenEvent = function(self, event, active)
|
||||
base.listenEvent(self, event, active)
|
||||
if(events[event]==nil)then events[event] = {} end
|
||||
return self
|
||||
end,
|
||||
|
||||
customEventHandler = function(self, ...)
|
||||
base.customEventHandler(self, ...)
|
||||
for _, o in pairs(elements) do
|
||||
if (o.element.customEventHandler ~= nil) then
|
||||
o.element:customEventHandler(...)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
loseFocusHandler = function(self)
|
||||
base.loseFocusHandler(self)
|
||||
if(focusedObject~=nil)then focusedObject:loseFocusHandler() focusedObject = nil end
|
||||
end,
|
||||
|
||||
getBasalt = function(self)
|
||||
return basalt
|
||||
end,
|
||||
|
||||
setPalette = function(self, col, ...)
|
||||
local parent = self:getParent()
|
||||
parent:setPalette(col, ...)
|
||||
return self
|
||||
end,
|
||||
|
||||
eventHandler = function(self, ...)
|
||||
if(base.eventHandler~=nil)then
|
||||
base.eventHandler(self, ...)
|
||||
if(events["other_event"]~=nil)then
|
||||
self:sortElementOrder()
|
||||
for _, obj in ipairs(events["other_event"]) do
|
||||
if (obj.element.eventHandler ~= nil) then
|
||||
obj.element.eventHandler(obj.element, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
for k,v in pairs({mouse_click={"mouseHandler", true},mouse_up={"mouseUpHandler", false},mouse_drag={"dragHandler", false},mouse_scroll={"scrollHandler", true},mouse_hover={"hoverHandler", false}})do
|
||||
container[v[1]] = function(self, btn, x, y, ...)
|
||||
if(base[v[1]]~=nil)then
|
||||
if(base[v[1]](self, btn, x, y, ...))then
|
||||
if(events[k]~=nil)then
|
||||
self:sortElementOrder()
|
||||
for _, obj in ipairs(events[k]) do
|
||||
if (obj.element[v[1]] ~= nil) then
|
||||
local xO, yO = 0, 0
|
||||
if(self.getOffset~=nil)then
|
||||
xO, yO = self:getOffset()
|
||||
end
|
||||
if(obj.element.getIgnoreOffset~=nil)then
|
||||
if(obj.element.getIgnoreOffset())then
|
||||
xO, yO = 0, 0
|
||||
end
|
||||
end
|
||||
if (obj.element[v[1]](obj.element, btn, x+xO, y+yO, ...)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
if(v[2])then
|
||||
self:removeFocusedObject()
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs({key="keyHandler",key_up="keyUpHandler",char="charHandler"})do
|
||||
container[v] = function(self, ...)
|
||||
if(base[v]~=nil)then
|
||||
if(base[v](self, ...))then
|
||||
if(events[k]~=nil)then
|
||||
self:sortElementOrder()
|
||||
for _, obj in ipairs(events[k]) do
|
||||
if (obj.element[v] ~= nil) then
|
||||
if (obj.element[v](obj.element, ...)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(basalt.getObjects())do
|
||||
container["add"..k] = function(self, name)
|
||||
return addObject(self, v(name, basalt))
|
||||
end
|
||||
end
|
||||
|
||||
container.__index = container
|
||||
return setmetatable(container, base)
|
||||
end
|
||||
@@ -1,23 +1,20 @@
|
||||
local Object = require("Object")
|
||||
local utils = require("utils")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("List")(name, basalt)
|
||||
local objectType = "Dropdown"
|
||||
base.width = 12
|
||||
base.height = 1
|
||||
|
||||
base:setSize(12, 1)
|
||||
base:setZIndex(6)
|
||||
|
||||
local list = {}
|
||||
local itemSelectedBG
|
||||
local itemSelectedFG
|
||||
local selectionColorActive = true
|
||||
local align = "left"
|
||||
local yOffset = 0
|
||||
|
||||
local dropdownW = 16
|
||||
local dropdownH = 6
|
||||
local dropdownW = 0
|
||||
local dropdownH = 0
|
||||
local autoSize = true
|
||||
local closedSymbol = "\16"
|
||||
local openedSymbol = "\31"
|
||||
local isOpened = false
|
||||
@@ -25,97 +22,63 @@ return function(name)
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
|
||||
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
|
||||
if(xmlValue("dropdownWidth", data)~=nil)then dropdownW = xmlValue("dropdownWidth", data) end
|
||||
if(xmlValue("dropdownHeight", data)~=nil)then dropdownH = xmlValue("dropdownHeight", data) end
|
||||
if(xmlValue("offset", data)~=nil)then yOffset = xmlValue("offset", data) end
|
||||
if(data["item"]~=nil)then
|
||||
local tab = data["item"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
|
||||
end
|
||||
end
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
load = function(self)
|
||||
self:listenEvent("mouse_click", self)
|
||||
self:listenEvent("mouse_up", self)
|
||||
self:listenEvent("mouse_scroll", self)
|
||||
self:listenEvent("mouse_drag", self)
|
||||
end,
|
||||
|
||||
setOffset = function(self, yOff)
|
||||
yOffset = yOff
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return yOffset
|
||||
end;
|
||||
end,
|
||||
|
||||
addItem = function(self, text, bgCol, fgCol, ...)
|
||||
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
self:updateDraw()
|
||||
addItem = function(self, t, ...)
|
||||
base.addItem(self, t, ...)
|
||||
if(autoSize)then
|
||||
dropdownW = math.max(dropdownW, #t)
|
||||
dropdownH = dropdownH + 1
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
getAll = function(self)
|
||||
return list
|
||||
end;
|
||||
end,
|
||||
|
||||
removeItem = function(self, index)
|
||||
table.remove(list, index)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getItem = function(self, index)
|
||||
return list[index]
|
||||
end;
|
||||
|
||||
getItemIndex = function(self)
|
||||
local selected = self:getValue()
|
||||
for key, value in pairs(list) do
|
||||
if (value == selected) then
|
||||
return key
|
||||
base.removeItem(self, index)
|
||||
if(autoSize)then
|
||||
dropdownW = 0
|
||||
dropdownH = 0
|
||||
for n = 1, #list do
|
||||
dropdownW = math.max(dropdownW, #list[n].text)
|
||||
end
|
||||
dropdownH = #list
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
clear = function(self)
|
||||
list = {}
|
||||
self:setValue({}, false)
|
||||
isOpened = function(self)
|
||||
return isOpened
|
||||
end,
|
||||
|
||||
setOpened = function(self, open)
|
||||
isOpened = open
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getItemCount = function(self)
|
||||
return #list
|
||||
end;
|
||||
|
||||
editItem = function(self, index, text, bgCol, fgCol, ...)
|
||||
table.remove(list, index)
|
||||
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
selectItem = function(self, index)
|
||||
self:setValue(list[index] or {}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setSelectedItem = function(self, bgCol, fgCol, active)
|
||||
itemSelectedBG = bgCol or self.bgColor
|
||||
itemSelectedFG = fgCol or self.fgColor
|
||||
selectionColorActive = active~=nil and active
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setDropdownSize = function(self, width, height)
|
||||
dropdownW, dropdownH = width, height
|
||||
autoSize = false
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
@@ -124,18 +87,25 @@ return function(name)
|
||||
return dropdownW, dropdownH
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
mouseHandler = function(self, button, x, y, isMon)
|
||||
if (isOpened) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
if(button==1)then
|
||||
local list = self:getAll()
|
||||
if (#list > 0) then
|
||||
for n = 1, dropdownH do
|
||||
if (list[n + yOffset] ~= nil) then
|
||||
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
|
||||
self:setValue(list[n + yOffset])
|
||||
self:updateDraw()
|
||||
local val = self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", dir, x, y)
|
||||
local val = self:sendEvent("mouse_click", self, "mouse_click", dir, x, y)
|
||||
if(val==false)then return val end
|
||||
if(isMon)then
|
||||
basalt.schedule(function()
|
||||
sleep(0.1)
|
||||
self:mouseUpHandler(button, x, y)
|
||||
end)()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -143,8 +113,10 @@ return function(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
local base = base:getBase()
|
||||
if (base.mouseHandler(self, button, x, y)) then
|
||||
isOpened = (not isOpened)
|
||||
isOpened = not isOpened
|
||||
self:getParent():setImportant(self)
|
||||
self:updateDraw()
|
||||
return true
|
||||
else
|
||||
@@ -158,15 +130,16 @@ return function(name)
|
||||
|
||||
mouseUpHandler = function(self, button, x, y)
|
||||
if (isOpened) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
if(button==1)then
|
||||
local list = self:getAll()
|
||||
if (#list > 0) then
|
||||
for n = 1, dropdownH do
|
||||
if (list[n + yOffset] ~= nil) then
|
||||
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
|
||||
isOpened = false
|
||||
self:updateDraw()
|
||||
local val = self:getEventSystem():sendEvent("mouse_up", self, "mouse_up", dir, x, y)
|
||||
local val = self:sendEvent("mouse_up", self, "mouse_up", dir, x, y)
|
||||
if(val==false)then return val end
|
||||
return true
|
||||
end
|
||||
@@ -178,7 +151,20 @@ return function(name)
|
||||
end,
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if(isOpened)then
|
||||
local xPos, yPos = self:getAbsolutePosition()
|
||||
if(x >= xPos)and(x <= xPos + dropdownW)and(y >= yPos)and(y <= yPos + dropdownH)then
|
||||
self:setFocus()
|
||||
end
|
||||
end
|
||||
if (isOpened)and(self:isFocused()) then
|
||||
local xPos, yPos = self:getAbsolutePosition()
|
||||
if(x < xPos)or(x > xPos + dropdownW)or(y < yPos)or(y > yPos + dropdownH)then
|
||||
return false
|
||||
end
|
||||
if(#self:getAll() <= dropdownH)then return false end
|
||||
|
||||
local list = self:getAll()
|
||||
yOffset = yOffset + dir
|
||||
if (yOffset < 0) then
|
||||
yOffset = 0
|
||||
@@ -192,7 +178,7 @@ return function(name)
|
||||
yOffset = math.min(#list - 1, 0)
|
||||
end
|
||||
end
|
||||
local val = self:getEventSystem():sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y)
|
||||
local val = self:sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y)
|
||||
if(val==false)then return val end
|
||||
self:updateDraw()
|
||||
return true
|
||||
@@ -200,46 +186,41 @@ return function(name)
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
base.draw(self)
|
||||
self:setDrawState("list", false)
|
||||
self:addDraw("dropdown", function()
|
||||
local obx, oby = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
if (self.parent ~= nil) then
|
||||
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
|
||||
local val = self:getValue()
|
||||
local text = utils.getTextHorizontalAlign((val~=nil and val.text or ""), w, align):sub(1, w - 1) .. (isOpened and openedSymbol or closedSymbol)
|
||||
self.parent:writeText(obx, oby, text, self.bgColor, self.fgColor)
|
||||
local val = self:getValue()
|
||||
local list = self:getAll()
|
||||
local bgCol, fgCol = self:getBackground(), self:getForeground()
|
||||
local text = utils.getTextHorizontalAlign((val~=nil and val.text or ""), w, align):sub(1, w - 1) .. (isOpened and openedSymbol or closedSymbol)
|
||||
self:addBlit(1, 1, text, tHex[fgCol]:rep(#text), tHex[bgCol]:rep(#text))
|
||||
|
||||
if (isOpened) then
|
||||
for n = 1, dropdownH do
|
||||
if (list[n + yOffset] ~= nil) then
|
||||
if (list[n + yOffset] == val) then
|
||||
if (selectionColorActive) then
|
||||
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), itemSelectedBG, itemSelectedFG)
|
||||
else
|
||||
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
|
||||
end
|
||||
if (isOpened) then
|
||||
self:addTextBox(1, 2, dropdownW, dropdownH, " ")
|
||||
self:addBackgroundBox(1, 2, dropdownW, dropdownH, bgCol)
|
||||
self:addForegroundBox(1, 2, dropdownW, dropdownH, fgCol)
|
||||
for n = 1, dropdownH do
|
||||
if (list[n + yOffset] ~= nil) then
|
||||
local t =utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align)
|
||||
if (list[n + yOffset] == val) then
|
||||
if (selectionColorActive) then
|
||||
local itemSelectedBG, itemSelectedFG = self:getSelectionColor()
|
||||
self:addBlit(1, n+1, t, tHex[itemSelectedFG]:rep(#t), tHex[itemSelectedBG]:rep(#t))
|
||||
else
|
||||
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
|
||||
self:addBlit(1, n+1, t, tHex[list[n + yOffset].fgCol]:rep(#t), tHex[list[n + yOffset].bgCol]:rep(#t))
|
||||
end
|
||||
else
|
||||
self:addBlit(1, n+1, t, tHex[list[n + yOffset].fgCol]:rep(#t), tHex[list[n + yOffset].bgCol]:rep(#t))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("DropdownBG")
|
||||
self.fgColor = self.parent:getTheme("DropdownText")
|
||||
itemSelectedBG = self.parent:getTheme("SelectionBG")
|
||||
itemSelectedFG = self.parent:getTheme("SelectionText")
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
114
Basalt/objects/Flexbox.lua
Normal file
@@ -0,0 +1,114 @@
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Frame")(name, basalt)
|
||||
local objectType = "Flexbox"
|
||||
|
||||
local flexDirection = "row" -- "row" or "column"
|
||||
local justifyContent = "flex-start" -- "flex-start", "flex-end", "center", "space-between", "space-around"
|
||||
local alignItems = "flex-start" -- "flex-start", "flex-end", "center", "space-between", "space-around"
|
||||
local spacing = 1
|
||||
|
||||
local function getObjectOffAxisOffset(self, obj)
|
||||
local width, height = self:getSize()
|
||||
local objWidth, objHeight = obj.element:getSize()
|
||||
local availableSpace = flexDirection == "row" and height - objHeight or width - objWidth
|
||||
local offset = 1
|
||||
if alignItems == "center" then
|
||||
offset = 1 + availableSpace / 2
|
||||
elseif alignItems == "flex-end" then
|
||||
offset = 1 + availableSpace
|
||||
end
|
||||
return offset
|
||||
end
|
||||
|
||||
local function applyLayout(self)
|
||||
local objects = self:getObjects()
|
||||
local totalElements = #objects
|
||||
local width, height = self:getSize()
|
||||
|
||||
local mainAxisTotalChildSize = 0
|
||||
for _, obj in ipairs(objects) do
|
||||
local objWidth, objHeight = obj.element:getSize()
|
||||
if flexDirection == "row" then
|
||||
mainAxisTotalChildSize = mainAxisTotalChildSize + objWidth
|
||||
else
|
||||
mainAxisTotalChildSize = mainAxisTotalChildSize + objHeight
|
||||
end
|
||||
end
|
||||
local mainAxisAvailableSpace = (flexDirection == "row" and width or height) - mainAxisTotalChildSize - (spacing * (totalElements - 1))
|
||||
local justifyContentOffset = 1
|
||||
if justifyContent == "center" then
|
||||
justifyContentOffset = 1 + mainAxisAvailableSpace / 2
|
||||
elseif justifyContent == "flex-end" then
|
||||
justifyContentOffset = 1 + mainAxisvailableSpace
|
||||
end
|
||||
|
||||
for _, obj in ipairs(objects) do
|
||||
local alignItemsOffset = getObjectOffAxisOffset(self, obj)
|
||||
if flexDirection == "row" then
|
||||
obj.element:setPosition(justifyContentOffset, alignItemsOffset)
|
||||
local objWidth, _ = obj.element:getSize()
|
||||
justifyContentOffset = justifyContentOffset + objWidth + spacing
|
||||
else
|
||||
obj.element:setPosition(alignItemsOffset, math.floor(justifyContentOffset+0.5))
|
||||
local _, objHeight = obj.element:getSize()
|
||||
justifyContentOffset = justifyContentOffset + objHeight + spacing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local object = {
|
||||
getType = function()
|
||||
return objectType
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType == t or base.getBase(self).isType(t) or false
|
||||
end,
|
||||
|
||||
setSpacing = function(self, newSpacing)
|
||||
spacing = newSpacing
|
||||
applyLayout(self)
|
||||
return self
|
||||
end,
|
||||
|
||||
getSpacing = function(self)
|
||||
return spacing
|
||||
end,
|
||||
|
||||
setFlexDirection = function(self, direction)
|
||||
if direction == "row" or direction == "column" then
|
||||
flexDirection = direction
|
||||
applyLayout(self)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setJustifyContent = function(self, alignment)
|
||||
if alignment == "flex-start" or alignment == "flex-end" or alignment == "center" or alignment == "space-between" or alignment == "space-around" then
|
||||
justifyContent = alignment
|
||||
applyLayout(self)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setAlignItems = function(self, alignment)
|
||||
if alignment == "flex-start" or alignment == "flex-end" or alignment == "center" or alignment == "space-between" or alignment == "space-around" then
|
||||
alignItems = alignment
|
||||
applyLayout(self)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
}
|
||||
|
||||
for k,v in pairs(basalt.getObjects())do
|
||||
object["add"..k] = function(self, name)
|
||||
local obj = base["add"..k](self, name)
|
||||
applyLayout(base)
|
||||
return obj
|
||||
end
|
||||
end
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
117
Basalt/objects/Frame.lua
Normal file
@@ -0,0 +1,117 @@
|
||||
local utils = require("utils")
|
||||
|
||||
local max,min,sub,rep,len = math.max,math.min,string.sub,string.rep,string.len
|
||||
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Container")(name, basalt)
|
||||
local objectType = "Frame"
|
||||
local parent
|
||||
|
||||
local updateRender = true
|
||||
|
||||
local xOffset, yOffset = 0, 0
|
||||
|
||||
base:setSize(30, 10)
|
||||
base:setZIndex(10)
|
||||
|
||||
local object = {
|
||||
getType = function()
|
||||
return objectType
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return xOffset, yOffset
|
||||
end,
|
||||
|
||||
setOffset = function(self, xOff, yOff)
|
||||
xOffset = xOff or xOffset
|
||||
yOffset = yOff or yOffset
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setParent = function(self, p, ...)
|
||||
base.setParent(self, p, ...)
|
||||
parent = p
|
||||
return self
|
||||
end,
|
||||
|
||||
render = function(self)
|
||||
if(base.render~=nil)then
|
||||
if(self:isVisible())then
|
||||
base.render(self)
|
||||
local objects = self:getObjects()
|
||||
for _, obj in ipairs(objects) do
|
||||
if (obj.element.render ~= nil) then
|
||||
obj.element:render()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
updateDraw = function(self)
|
||||
if(parent~=nil)then
|
||||
parent:updateDraw()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
blit = function (self, x, y, t, f, b)
|
||||
local obx, oby = self:getPosition()
|
||||
local xO, yO = parent:getOffset()
|
||||
obx = obx - xO
|
||||
oby = oby - yO
|
||||
local w, h = self:getSize()
|
||||
if y >= 1 and y <= h then
|
||||
local t_visible = sub(t, max(1 - x + 1, 1), max(w - x + 1, 1))
|
||||
local f_visible = sub(f, max(1 - x + 1, 1), max(w - x + 1, 1))
|
||||
local b_visible = sub(b, max(1 - x + 1, 1), max(w - x + 1, 1))
|
||||
parent:blit(max(x + (obx - 1), obx), oby + y - 1, t_visible, f_visible, b_visible)
|
||||
end
|
||||
end,
|
||||
|
||||
setCursor = function(self, blink, x, y, color)
|
||||
local obx, oby = self:getPosition()
|
||||
local xO, yO = self:getOffset()
|
||||
parent:setCursor(blink or false, (x or 0)+obx-1 - xO, (y or 0)+oby-1 - yO, color or colors.white)
|
||||
return self
|
||||
end,
|
||||
}
|
||||
|
||||
for k,v in pairs({"drawBackgroundBox", "drawForegroundBox", "drawTextBox"})do
|
||||
object[v] = function(self, x, y, width, height, symbol)
|
||||
local obx, oby = self:getPosition()
|
||||
local xO, yO = parent:getOffset()
|
||||
obx = obx - xO
|
||||
oby = oby - yO
|
||||
height = (y < 1 and (height + y > self:getHeight() and self:getHeight() or height + y - 1) or (height + y > self:getHeight() and self:getHeight() - y + 1 or height))
|
||||
width = (x < 1 and (width + x > self:getWidth() and self:getWidth() or width + x - 1) or (width + x > self:getWidth() and self:getWidth() - x + 1 or width))
|
||||
parent[v](parent, max(x + (obx - 1), obx), max(y + (oby - 1), oby), width, height, symbol)
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs({"setBG", "setFG", "setText"})do
|
||||
object[v] = function(self, x, y, str)
|
||||
local obx, oby = self:getPosition()
|
||||
local xO, yO = parent:getOffset()
|
||||
obx = obx - xO
|
||||
oby = oby - yO
|
||||
local w, h = self:getSize()
|
||||
if (y >= 1) and (y <= h) then
|
||||
parent[v](parent, max(x + (obx - 1), obx), oby + y - 1, sub(str, max(1 - x + 1, 1), max(w - x + 1,1)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
159
Basalt/objects/Graph.lua
Normal file
@@ -0,0 +1,159 @@
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "Graph"
|
||||
|
||||
base:setZIndex(5)
|
||||
base:setSize(30, 10)
|
||||
|
||||
local graphData = {}
|
||||
local graphColor = colors.gray
|
||||
local graphSymbol = "\7"
|
||||
local graphSymbolCol = colors.black
|
||||
local maxValue = 100
|
||||
local minValue = 0
|
||||
local graphType = "line"
|
||||
local maxEntries = 10
|
||||
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end,
|
||||
|
||||
setGraphColor = function(self, color)
|
||||
graphColor = color or graphColor
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setGraphSymbol = function(self, symbol, symbolcolor)
|
||||
graphSymbol = symbol or graphSymbol
|
||||
graphSymbolCol = symbolcolor or graphSymbolCol
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getGraphSymbol = function(self)
|
||||
return graphSymbol, graphSymbolCol
|
||||
end,
|
||||
|
||||
addDataPoint = function(self, value)
|
||||
if value >= minValue and value <= maxValue then
|
||||
table.insert(graphData, value)
|
||||
self:updateDraw()
|
||||
end
|
||||
if(#graphData>100)then -- 100 is hard capped to prevent memory leaks
|
||||
table.remove(graphData,1)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setMaxValue = function(self, value)
|
||||
maxValue = value
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getMaxValue = function(self)
|
||||
return maxValue
|
||||
end,
|
||||
|
||||
setMinValue = function(self, value)
|
||||
minValue = value
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getMinValue = function(self)
|
||||
return minValue
|
||||
end,
|
||||
|
||||
setGraphType = function(self, graph_type)
|
||||
if graph_type == "scatter" or graph_type == "line" or graph_type == "bar" then
|
||||
graphType = graph_type
|
||||
self:updateDraw()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setMaxEntries = function(self, value)
|
||||
maxEntries = value
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getMaxEntries = function(self)
|
||||
return maxEntries
|
||||
end,
|
||||
|
||||
clear = function(self)
|
||||
graphData = {}
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("graph", function()
|
||||
local obx, oby = self:getPosition()
|
||||
local w, h = self:getSize()
|
||||
local bgCol, fgCol = self:getBackground(), self:getForeground()
|
||||
|
||||
local range = maxValue - minValue
|
||||
local prev_x, prev_y
|
||||
|
||||
local startIndex = #graphData - maxEntries + 1
|
||||
if startIndex < 1 then startIndex = 1 end
|
||||
|
||||
for i = startIndex, #graphData do
|
||||
local data = graphData[i]
|
||||
local x = math.floor(((w - 1) / (maxEntries - 1)) * (i - startIndex) + 1.5)
|
||||
local y = math.floor((h - 1) - ((h - 1) / range) * (data - minValue) + 1.5)
|
||||
|
||||
|
||||
if graphType == "scatter" then
|
||||
self:addBackgroundBox(x, y, 1, 1, graphColor)
|
||||
self:addForegroundBox(x, y, 1, 1, graphSymbolCol)
|
||||
self:addTextBox(x, y, 1, 1, graphSymbol)
|
||||
elseif graphType == "line" then
|
||||
if prev_x and prev_y then
|
||||
local dx = math.abs(x - prev_x)
|
||||
local dy = math.abs(y - prev_y)
|
||||
local sx = prev_x < x and 1 or -1
|
||||
local sy = prev_y < y and 1 or -1
|
||||
local err = dx - dy
|
||||
|
||||
while true do
|
||||
self:addBackgroundBox(prev_x, prev_y, 1, 1, graphColor)
|
||||
self:addForegroundBox(prev_x, prev_y, 1, 1, graphSymbolCol)
|
||||
self:addTextBox(prev_x, prev_y, 1, 1, graphSymbol)
|
||||
|
||||
if prev_x == x and prev_y == y then
|
||||
break
|
||||
end
|
||||
|
||||
local e2 = 2 * err
|
||||
|
||||
if e2 > -dy then
|
||||
err = err - dy
|
||||
prev_x = prev_x + sx
|
||||
end
|
||||
|
||||
if e2 < dx then
|
||||
err = err + dx
|
||||
prev_y = prev_y + sy
|
||||
end
|
||||
end
|
||||
end
|
||||
prev_x, prev_y = x, y
|
||||
elseif graphType == "bar" then
|
||||
self:addBackgroundBox(x - 1, y, 1, h - y, graphColor)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,214 +0,0 @@
|
||||
local Object = require("Object")
|
||||
local tHex = require("tHex")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local bimgLib = require("bimg")
|
||||
local images = require("images")
|
||||
|
||||
local sub,len,max,min = string.sub,string.len,math.max,math.min
|
||||
|
||||
return function(name)
|
||||
-- Graphic
|
||||
local base = Object(name)
|
||||
local objectType = "Graphic"
|
||||
local imgData = bimgLib()
|
||||
local bimgFrame = imgData.getFrameObject(1)
|
||||
local bimg
|
||||
local selectedFrame = 1
|
||||
base:setZIndex(5)
|
||||
|
||||
local xOffset, yOffset = 0, 0
|
||||
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setOffset = function(self, _x, _y, rel)
|
||||
if(rel)then
|
||||
xOffset = xOffset + _x or 0
|
||||
yOffset = yOffset + _y or 0
|
||||
else
|
||||
xOffset = _x or xOffset
|
||||
yOffset = _y or yOffset
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return xOffset,yOffset
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
|
||||
return self
|
||||
end,
|
||||
|
||||
selectFrame = function(self, id)
|
||||
if(imgData.getFrameObject(id)==nil)then
|
||||
imgData.addFrame(id)
|
||||
end
|
||||
bimgFrame = imgData.getFrameObject(id)
|
||||
bimg = bimgFrame.getImage(id)
|
||||
selectedFrame = id
|
||||
self:updateDraw()
|
||||
end,
|
||||
|
||||
addFrame = function(self, id)
|
||||
imgData.addFrame(id)
|
||||
return self
|
||||
end,
|
||||
|
||||
getFrameMetadata = function(self, id, key)
|
||||
return imgData.getFrameData(id, key)
|
||||
end,
|
||||
|
||||
setFrameMetadata = function(self, id, key, val)
|
||||
imgData.setFrameData(id, key, val)
|
||||
return self
|
||||
end,
|
||||
|
||||
getMetadata = function(self, key)
|
||||
return imgData.getMetadata(key)
|
||||
end,
|
||||
|
||||
setMetadata = function(self, key, value)
|
||||
return imgData.setMetadata(key, value)
|
||||
end,
|
||||
|
||||
getFrame = function(self, id)
|
||||
return imgData.getFrame(id)
|
||||
end,
|
||||
|
||||
getFrameObject = function(self, id)
|
||||
return imgData.getFrameObject(id)
|
||||
end,
|
||||
|
||||
removeFrame = function(self, id)
|
||||
imgData.removeFrame(id)
|
||||
return self
|
||||
end,
|
||||
|
||||
moveFrame = function(self, id, dir)
|
||||
imgData.moveFrame(id, dir)
|
||||
return self
|
||||
end,
|
||||
|
||||
getFrames = function(self)
|
||||
return imgData.getFrames()
|
||||
end,
|
||||
|
||||
getFrameCount = function(self)
|
||||
return #imgData.getFrames()
|
||||
end,
|
||||
|
||||
getSelectedFrame = function(self)
|
||||
return selectedFrame
|
||||
end,
|
||||
|
||||
blit = function(self, text, fg, bg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.blit(text, fg, bg, x, y)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setText = function(self, text, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.text(text, x, y)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setBg = function(self, bg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.bg(bg, x, y)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setFg = function(self, fg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.fg(fg, x, y)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getImageSize = function(self)
|
||||
return imgData.getSize()
|
||||
end,
|
||||
|
||||
setImageSize = function(self, w, h)
|
||||
imgData.setSize(w, h)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
resizeImage = function(self, w, h)
|
||||
local newBimg = images.resizeBIMG(imgData.createBimg(), w, h)
|
||||
imgData = bimgLib(newBimg)
|
||||
selectedFrame = 1
|
||||
bimgFrame = imgData.getFrameObject(1)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
loadImage = function(self, path)
|
||||
if(fs.exists(path))then
|
||||
local newBimg = images.loadBIMG(path)
|
||||
imgData = bimgLib(newBimg)
|
||||
selectedFrame = 1
|
||||
bimgFrame = imgData.getFrameObject(1)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
clear = function(self)
|
||||
imgData = bimgLib()
|
||||
bimg = nil
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getImage = function(self)
|
||||
return imgData.createBimg()
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if(bimg~=nil)then
|
||||
for k,v in pairs(bimg)do
|
||||
if(k<=h-yOffset)and(k+yOffset>=1)then
|
||||
self.parent:blit(obx+xOffset, oby+k-1+yOffset, v[1], v[2], v[3])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("GraphicBG")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,115 +1,212 @@
|
||||
local Object = require("Object")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local images = require("images")
|
||||
|
||||
local unpack,sub = table.unpack,string.sub
|
||||
return function(name)
|
||||
local bimg = require("bimg")
|
||||
local unpack,sub,max,min = table.unpack,string.sub,math.max,math.min
|
||||
return function(name, basalt)
|
||||
-- Image
|
||||
local base = Object(name)
|
||||
local base = basalt.getObject("VisualObject")(name, basalt)
|
||||
local objectType = "Image"
|
||||
base:setZIndex(2)
|
||||
|
||||
local bimgLibrary = bimg()
|
||||
local bimgFrame = bimgLibrary.getFrameObject(1)
|
||||
local originalImage
|
||||
local image
|
||||
local curFrame = 1
|
||||
local activeFrame = 1
|
||||
|
||||
local infinitePlay = false
|
||||
local animTimer
|
||||
local usePalette = false
|
||||
local autoSize = true
|
||||
|
||||
base.width = 24
|
||||
base.height = 8
|
||||
local xOffset, yOffset = 0, 0
|
||||
|
||||
base:setSize(24, 8)
|
||||
base:setZIndex(2)
|
||||
|
||||
local function getPalette(id)
|
||||
if(originalImage~=nil)then
|
||||
local p = {}
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
p[k] = {term.nativePaletteColor(v)}
|
||||
end
|
||||
local p = {}
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
p[k] = {term.nativePaletteColor(v)}
|
||||
end
|
||||
if(originalImage.palette~=nil)then
|
||||
for k,v in pairs(originalImage.palette)do
|
||||
p[k] = tonumber(v)
|
||||
end
|
||||
end
|
||||
local globalPalette = bimgLibrary.getMetadata("palette")
|
||||
if(globalPalette~=nil)then
|
||||
for k,v in pairs(globalPalette)do
|
||||
p[k] = tonumber(v)
|
||||
end
|
||||
if(originalImage[id]~=nil)and(originalImage[id].palette~=nil)then
|
||||
for k,v in pairs(originalImage[id].palette)do
|
||||
p[k] = tonumber(v)
|
||||
end
|
||||
end
|
||||
local localPalette = bimgLibrary.getFrameData("palette")
|
||||
basalt.log(localPalette)
|
||||
if(localPalette~=nil)then
|
||||
for k,v in pairs(localPalette)do
|
||||
p[k] = tonumber(v)
|
||||
end
|
||||
end
|
||||
return p
|
||||
end
|
||||
|
||||
local function checkAutoSize()
|
||||
if(autoSize)then
|
||||
if(bimgLibrary~=nil)then
|
||||
base:setSize(bimgLibrary.getSize())
|
||||
end
|
||||
return p
|
||||
end
|
||||
end
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ImageBG")
|
||||
end
|
||||
end,
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
loadImage = function(self, path, f)
|
||||
if not(fs.exists(path))then error("No valid path: "..path) end
|
||||
originalImage = images.loadImageAsBimg(path, f)
|
||||
curFrame = 1
|
||||
image = originalImage
|
||||
if(animTimer~=nil)then
|
||||
os.cancelTimer(animTimer)
|
||||
setOffset = function(self, _x, _y, rel)
|
||||
if(rel)then
|
||||
xOffset = xOffset + _x or 0
|
||||
yOffset = yOffset + _y or 0
|
||||
else
|
||||
xOffset = _x or xOffset
|
||||
yOffset = _y or yOffset
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setImage = function(self, data)
|
||||
originalImage = data
|
||||
image = originalImage
|
||||
curFrame = 1
|
||||
if(animTimer~=nil)then
|
||||
os.cancelTimer(animTimer)
|
||||
setSize = function(self, _x, _y)
|
||||
base:setSize(_x, _y)
|
||||
autoSize = false
|
||||
return self
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return xOffset, yOffset
|
||||
end,
|
||||
|
||||
selectFrame = function(self, id)
|
||||
if(bimgLibrary.getFrameObject(id)==nil)then
|
||||
bimgLibrary.addFrame(id)
|
||||
end
|
||||
bimgFrame = bimgLibrary.getFrameObject(id)
|
||||
image = bimgFrame.getImage(id)
|
||||
activeFrame = id
|
||||
self:updateDraw()
|
||||
end,
|
||||
|
||||
addFrame = function(self, id)
|
||||
bimgLibrary.addFrame(id)
|
||||
return self
|
||||
end,
|
||||
|
||||
getFrame = function(self, id)
|
||||
return bimgLibrary.getFrame(id)
|
||||
end,
|
||||
|
||||
getFrameObject = function(self, id)
|
||||
return bimgLibrary.getFrameObject(id)
|
||||
end,
|
||||
|
||||
removeFrame = function(self, id)
|
||||
bimgLibrary.removeFrame(id)
|
||||
return self
|
||||
end,
|
||||
|
||||
moveFrame = function(self, id, dir)
|
||||
bimgLibrary.moveFrame(id, dir)
|
||||
return self
|
||||
end,
|
||||
|
||||
getFrames = function(self)
|
||||
return bimgLibrary.getFrames()
|
||||
end,
|
||||
|
||||
getFrameCount = function(self)
|
||||
return #bimgLibrary.getFrames()
|
||||
end,
|
||||
|
||||
getActiveFrame = function(self)
|
||||
return activeFrame
|
||||
end,
|
||||
|
||||
loadImage = function(self, path)
|
||||
if(fs.exists(path))then
|
||||
local newBimg = images.loadBIMG(path)
|
||||
bimgLibrary = bimg(newBimg)
|
||||
activeFrame = 1
|
||||
bimgFrame = bimgLibrary.getFrameObject(1)
|
||||
originalImage = bimgLibrary.createBimg()
|
||||
image = bimgFrame.getImage()
|
||||
checkAutoSize()
|
||||
self:updateDraw()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setImage = function(self, t)
|
||||
if(type(t)=="table")then
|
||||
bimgLibrary = bimg(t)
|
||||
activeFrame = 1
|
||||
bimgFrame = bimgLibrary.getFrameObject(1)
|
||||
originalImage = bimgLibrary.createBimg()
|
||||
image = bimgFrame.getImage()
|
||||
checkAutoSize()
|
||||
self:updateDraw()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
clear = function(self)
|
||||
bimgLibrary = bimg()
|
||||
bimgFrame = bimgLibrary.getFrameObject(1)
|
||||
image = nil
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getImage = function(self)
|
||||
return bimgLibrary.createBimg()
|
||||
end,
|
||||
|
||||
getImageFrame = function(self, id)
|
||||
return bimgFrame.getImage(id)
|
||||
end,
|
||||
|
||||
usePalette = function(self, use)
|
||||
usePalette = use~=nil and use or true
|
||||
return self
|
||||
end,
|
||||
|
||||
play = function(self, inf)
|
||||
if(originalImage.animated)then
|
||||
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
|
||||
self.parent:addEvent("other_event", self)
|
||||
if(bimgLibrary.getMetadata("animated"))then
|
||||
local t = bimgLibrary.getMetadata("duration") or bimgLibrary.getMetadata("secondsPerFrame") or 0.2
|
||||
self:listenEvent("other_event")
|
||||
animTimer = os.startTimer(t)
|
||||
infinitePlay = inf or false
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
selectFrame = function(self, fr)
|
||||
if(originalImage[fr]~=nil)then
|
||||
curFrame = fr
|
||||
if(animTimer~=nil)then
|
||||
os.cancelTimer(animTimer)
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
stop = function(self)
|
||||
os.cancelTimer(animTimer)
|
||||
animTimer = nil
|
||||
infinitePlay = false
|
||||
return self
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, timerId, ...)
|
||||
base.eventHandler(self, event, timerId, ...)
|
||||
if(event=="timer")then
|
||||
if(timerId==animTimer)then
|
||||
if(originalImage[curFrame+1]~=nil)then
|
||||
curFrame = curFrame + 1
|
||||
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
|
||||
if(bimgLibrary.getFrame(activeFrame+1)~=nil)then
|
||||
activeFrame = activeFrame + 1
|
||||
self:selectFrame(activeFrame)
|
||||
local t = bimgLibrary.getFrameData(activeFrame, "duration") or bimgLibrary.getMetadata("secondsPerFrame") or 0.2
|
||||
animTimer = os.startTimer(t)
|
||||
else
|
||||
if(infinitePlay)then
|
||||
curFrame = 1
|
||||
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
|
||||
activeFrame = 1
|
||||
self:selectFrame(activeFrame)
|
||||
local t = bimgLibrary.getFrameData(activeFrame, "duration") or bimgLibrary.getMetadata("secondsPerFrame") or 0.2
|
||||
animTimer = os.startTimer(t)
|
||||
end
|
||||
end
|
||||
@@ -118,46 +215,117 @@ return function(name)
|
||||
end
|
||||
end,
|
||||
|
||||
setMetadata = function(self, key, value)
|
||||
bimgLibrary.setMetadata(key, value)
|
||||
return self
|
||||
end,
|
||||
|
||||
getMetadata = function(self, key)
|
||||
return originalImage[key]
|
||||
return bimgLibrary.getMetadata(key)
|
||||
end,
|
||||
|
||||
getImageSize = function(self)
|
||||
return originalImage.width, originalImage.height
|
||||
getFrameMetadata = function(self, id, key)
|
||||
return bimgLibrary.getFrameData(id, key)
|
||||
end,
|
||||
|
||||
resizeImage = function(self, w, h)
|
||||
image = images.resizeBIMG(originalImage, w, h)
|
||||
setFrameMetadata = function(self, id, key, value)
|
||||
bimgLibrary.setFrameData(id, key, value)
|
||||
return self
|
||||
end,
|
||||
|
||||
blit = function(self, text, fg, bg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.blit(text, fg, bg, x, y)
|
||||
image = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("path", data)~=nil)then self:loadImage(xmlValue("path", data)) end
|
||||
setText = function(self, text, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.text(text, x, y)
|
||||
image = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setBg = function(self, bg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.bg(bg, x, y)
|
||||
image = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setFg = function(self, fg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.fg(fg, x, y)
|
||||
image = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getImageSize = function(self)
|
||||
return bimgLibrary.getSize()
|
||||
end,
|
||||
|
||||
setImageSize = function(self, w, h)
|
||||
bimgLibrary.setSize(w, h)
|
||||
image = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
resizeImage = function(self, w, h)
|
||||
local newBimg = images.resizeBIMG(originalImage, w, h)
|
||||
bimgLibrary = bimg(newBimg)
|
||||
activeFrame = 1
|
||||
bimgFrame = bimgLibrary.getFrameObject(1)
|
||||
image = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (image ~= nil) then
|
||||
if(usePalette)then
|
||||
self:getBaseFrame():setThemeColor(getPalette(curFrame))
|
||||
end
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
for y,v in ipairs(image[curFrame])do
|
||||
local t, f, b = unpack(v)
|
||||
t = sub(t, 1,w)
|
||||
f = sub(f, 1,w)
|
||||
b = sub(b, 1,w)
|
||||
self.parent:blit(obx, oby+y-1, t, f, b)
|
||||
if(y==h)then break end
|
||||
base.draw(self)
|
||||
self:addDraw("image", function()
|
||||
local w,h = self:getSize()
|
||||
local x, y = self:getPosition()
|
||||
local wParent, hParent = self:getParent():getSize()
|
||||
local parentXOffset, parentYOffset = self:getParent():getOffset()
|
||||
|
||||
if(x - parentXOffset > wParent)or(y - parentYOffset > hParent)or(x - parentXOffset + w < 1)or(y - parentYOffset + h < 1)then
|
||||
return
|
||||
end
|
||||
|
||||
if(usePalette)then
|
||||
self:getParent():setPalette(getPalette(activeFrame))
|
||||
end
|
||||
|
||||
if(image~=nil)then
|
||||
for k,v in pairs(image)do
|
||||
if(k+yOffset<=h)and(k+yOffset>=1)then
|
||||
local t,f,b = v[1],v[2],v[3]
|
||||
|
||||
local startIdx = max(1 - xOffset, 1)
|
||||
local endIdx = min(w - xOffset, #t)
|
||||
|
||||
t = sub(t, startIdx, endIdx)
|
||||
f = sub(f, startIdx, endIdx)
|
||||
b = sub(b, startIdx, endIdx)
|
||||
|
||||
self:addBlit(max(1 + xOffset, 1), k + yOffset, t, f, b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,46 +1,46 @@
|
||||
local Object = require("Object")
|
||||
local utils = require("utils")
|
||||
local log = require("basaltLogs")
|
||||
local xmlValue = utils.getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
return function(name, basalt)
|
||||
-- Input
|
||||
local base = Object(name)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "Input"
|
||||
|
||||
local inputType = "text"
|
||||
local inputLimit = 0
|
||||
base:setZIndex(5)
|
||||
base:setValue("")
|
||||
base.width = 10
|
||||
base.height = 1
|
||||
base:setSize(12, 1)
|
||||
|
||||
local textX = 1
|
||||
local wIndex = 1
|
||||
|
||||
local defaultText = ""
|
||||
local defaultBGCol
|
||||
local defaultFGCol
|
||||
local defaultBGCol = colors.black
|
||||
local defaultFGCol = colors.lightGray
|
||||
local showingText = defaultText
|
||||
local internalValueChange = false
|
||||
|
||||
local object = {
|
||||
load = function(self)
|
||||
self:listenEvent("mouse_click")
|
||||
self:listenEvent("key")
|
||||
self:listenEvent("char")
|
||||
self:listenEvent("other_event")
|
||||
self:listenEvent("mouse_drag")
|
||||
end,
|
||||
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setInputType = function(self, iType)
|
||||
if (iType == "password") or (iType == "number") or (iType == "text") then
|
||||
inputType = iType
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
setDefaultText = function(self, text, fCol, bCol)
|
||||
defaultText = text
|
||||
defaultBGCol = bCol or defaultBGCol
|
||||
defaultFGCol = fCol or defaultFGCol
|
||||
defaultBGCol = bCol or defaultBGCol
|
||||
if (self:isFocused()) then
|
||||
showingText = ""
|
||||
else
|
||||
@@ -48,11 +48,41 @@ return function(name)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getDefaultText = function(self)
|
||||
return defaultText, defaultFGCol, defaultBGCol
|
||||
end,
|
||||
|
||||
setOffset = function(self, x)
|
||||
wIndex = x
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return wIndex
|
||||
end,
|
||||
|
||||
setTextOffset = function(self, x)
|
||||
textX = x
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getTextOffset = function(self)
|
||||
return textX
|
||||
end,
|
||||
|
||||
setInputType = function(self, t)
|
||||
inputType = t
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getInputType = function(self)
|
||||
return inputType
|
||||
end;
|
||||
end,
|
||||
|
||||
setValue = function(self, val)
|
||||
base.setValue(self, tostring(val))
|
||||
@@ -60,105 +90,84 @@ return function(name)
|
||||
textX = tostring(val):len() + 1
|
||||
wIndex = math.max(1, textX-self:getWidth()+1)
|
||||
if(self:isFocused())then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor)
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getPosition()
|
||||
parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self:getForeground())
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getValue = function(self)
|
||||
local val = base.getValue(self)
|
||||
return inputType == "number" and tonumber(val) or val
|
||||
end;
|
||||
end,
|
||||
|
||||
setInputLimit = function(self, limit)
|
||||
inputLimit = tonumber(limit) or inputLimit
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getInputLimit = function(self)
|
||||
return inputLimit
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
local dBG,dFG
|
||||
if(xmlValue("defaultBG", data)~=nil)then dBG = xmlValue("defaultBG", data) end
|
||||
if(xmlValue("defaultFG", data)~=nil)then dFG = xmlValue("defaultFG", data) end
|
||||
if(xmlValue("default", data)~=nil)then self:setDefaultText(xmlValue("default", data), dFG~=nil and colors[dFG], dBG~=nil and colors[dBG]) end
|
||||
if(xmlValue("limit", data)~=nil)then self:setInputLimit(xmlValue("limit", data)) end
|
||||
if(xmlValue("type", data)~=nil)then self:setInputType(xmlValue("type", data)) end
|
||||
return self
|
||||
end,
|
||||
|
||||
getFocusHandler = function(self)
|
||||
base.getFocusHandler(self)
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local parent = self:getParent()
|
||||
if (parent ~= nil) then
|
||||
local obx, oby = self:getPosition()
|
||||
showingText = ""
|
||||
if(defaultText~="")then
|
||||
self:updateDraw()
|
||||
end
|
||||
self.parent:setCursor(true, obx + textX - wIndex, oby+math.max(math.ceil(self:getHeight()/2-1, 1)), self.fgColor)
|
||||
parent:setCursor(true, obx + textX - wIndex, oby+math.max(math.ceil(self:getHeight()/2-1, 1)), self:getForeground())
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
loseFocusHandler = function(self)
|
||||
base.loseFocusHandler(self)
|
||||
if (self.parent ~= nil) then
|
||||
showingText = defaultText
|
||||
if(defaultText~="")then
|
||||
self:updateDraw()
|
||||
end
|
||||
self.parent:setCursor(false)
|
||||
local parent = self:getParent()
|
||||
showingText = defaultText
|
||||
if(defaultText~="")then
|
||||
self:updateDraw()
|
||||
end
|
||||
end;
|
||||
parent:setCursor(false)
|
||||
end,
|
||||
|
||||
keyHandler = function(self, key)
|
||||
if (base.keyHandler(self, key)) then
|
||||
local w,h = self:getSize()
|
||||
local parent = self:getParent()
|
||||
internalValueChange = true
|
||||
if (key == keys.backspace) then
|
||||
-- on backspace
|
||||
local text = tostring(base.getValue())
|
||||
if (textX > 1) then
|
||||
self:setValue(text:sub(1, textX - 2) .. text:sub(textX, text:len()))
|
||||
if (textX > 1) then
|
||||
textX = textX - 1
|
||||
end
|
||||
if (wIndex > 1) then
|
||||
if (textX < wIndex) then
|
||||
wIndex = wIndex - 1
|
||||
end
|
||||
textX = math.max(textX - 1, 1)
|
||||
if (textX < wIndex) then
|
||||
wIndex = math.max(wIndex - 1, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
if (key == keys.enter) then
|
||||
-- on enter
|
||||
if (self.parent ~= nil) then
|
||||
--self.parent:removeFocusedObject(self)
|
||||
end
|
||||
parent:removeFocusedObject(self)
|
||||
end
|
||||
if (key == keys.right) then
|
||||
-- right arrow
|
||||
local tLength = tostring(base.getValue()):len()
|
||||
textX = textX + 1
|
||||
|
||||
if (textX > tLength) then
|
||||
textX = tLength + 1
|
||||
end
|
||||
if (textX < 1) then
|
||||
textX = 1
|
||||
end
|
||||
textX = math.max(textX, 1)
|
||||
if (textX < wIndex) or (textX >= w + wIndex) then
|
||||
wIndex = textX - w + 1
|
||||
end
|
||||
if (wIndex < 1) then
|
||||
wIndex = 1
|
||||
end
|
||||
wIndex = math.max(wIndex, 1)
|
||||
end
|
||||
|
||||
if (key == keys.left) then
|
||||
@@ -169,29 +178,16 @@ return function(name)
|
||||
wIndex = textX
|
||||
end
|
||||
end
|
||||
if (textX < 1) then
|
||||
textX = 1
|
||||
end
|
||||
if (wIndex < 1) then
|
||||
wIndex = 1
|
||||
end
|
||||
textX = math.max(textX, 1)
|
||||
wIndex = math.max(wIndex, 1)
|
||||
end
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local obx, oby = self:getPosition()
|
||||
local val = tostring(base.getValue())
|
||||
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
|
||||
|
||||
local inpX = self:getX()
|
||||
if (cursorX > inpX + w - 1) then
|
||||
cursorX = inpX + w - 1
|
||||
end
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
|
||||
end
|
||||
|
||||
self:updateDraw()
|
||||
internalValueChange = false
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
charHandler = function(self, char)
|
||||
@@ -220,27 +216,19 @@ return function(name)
|
||||
wIndex = wIndex + 1
|
||||
end
|
||||
end
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local obx, oby = self:getPosition()
|
||||
local val = tostring(base.getValue())
|
||||
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
|
||||
|
||||
local x = self:getX()
|
||||
if (cursorX > x + w - 1) then
|
||||
cursorX = x + w - 1
|
||||
end
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
|
||||
end
|
||||
internalValueChange = false
|
||||
self:updateDraw()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if(base.mouseHandler(self, button, x, y))then
|
||||
local ax, ay = self:getAnchorPosition()
|
||||
local parent = self:getParent()
|
||||
local ax, ay = self:getPosition()
|
||||
local obx, oby = self:getAbsolutePosition(ax, ay)
|
||||
local w, h = self:getSize()
|
||||
textX = x - obx + wIndex
|
||||
@@ -254,7 +242,7 @@ return function(name)
|
||||
wIndex = 1
|
||||
end
|
||||
end
|
||||
self.parent:setCursor(true, ax + textX - wIndex, ay+math.max(math.ceil(h/2-1, 1)), self.fgColor)
|
||||
parent:setCursor(true, ax + textX - wIndex, ay+math.max(math.ceil(h/2-1, 1)), self:getForeground())
|
||||
return true
|
||||
end
|
||||
end,
|
||||
@@ -266,108 +254,51 @@ return function(name)
|
||||
return true
|
||||
end
|
||||
end
|
||||
self.parent:removeFocusedObject()
|
||||
end
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, paste, ...)
|
||||
base.eventHandler(self, event, paste, ...)
|
||||
if(event=="paste")then
|
||||
if(self:isFocused())then
|
||||
local text = base.getValue()
|
||||
local w, h = self:getSize()
|
||||
internalValueChange = true
|
||||
if (inputType == "number") then
|
||||
local cache = text
|
||||
if (paste == ".") or (tonumber(paste) ~= nil) then
|
||||
self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len()))
|
||||
textX = textX + paste:len()
|
||||
end
|
||||
if (tonumber(base.getValue()) == nil) then
|
||||
self:setValue(cache)
|
||||
end
|
||||
else
|
||||
self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len()))
|
||||
textX = textX + paste:len()
|
||||
end
|
||||
if (textX >= w + wIndex) then
|
||||
wIndex = (textX+1)-w
|
||||
end
|
||||
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local val = tostring(base.getValue())
|
||||
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
|
||||
|
||||
local x = self:getX()
|
||||
if (cursorX > x + w - 1) then
|
||||
cursorX = x + w - 1
|
||||
end
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
|
||||
end
|
||||
self:updateDraw()
|
||||
internalValueChange = false
|
||||
end
|
||||
local parent = self:getParent()
|
||||
parent:removeFocusedObject()
|
||||
end
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
local verticalAlign = utils.getTextVerticalAlign(h, "center")
|
||||
|
||||
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
|
||||
for n = 1, h do
|
||||
if (n == verticalAlign) then
|
||||
local val = tostring(base.getValue())
|
||||
local bCol = self.bgColor
|
||||
local fCol = self.fgColor
|
||||
local text
|
||||
if (val:len() <= 0) then
|
||||
text = showingText
|
||||
bCol = defaultBGCol or bCol
|
||||
fCol = defaultFGCol or fCol
|
||||
end
|
||||
|
||||
text = showingText
|
||||
if (val ~= "") then
|
||||
text = val
|
||||
end
|
||||
text = text:sub(wIndex, w + wIndex - 1)
|
||||
local space = w - text:len()
|
||||
if (space < 0) then
|
||||
space = 0
|
||||
end
|
||||
if (inputType == "password") and (val ~= "") then
|
||||
text = string.rep("*", text:len())
|
||||
end
|
||||
text = text .. string.rep(self.bgSymbol, space)
|
||||
self.parent:writeText(obx, oby + (n - 1), text, bCol, fCol)
|
||||
end
|
||||
end
|
||||
if(self:isFocused())then
|
||||
self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor)
|
||||
end
|
||||
base.draw(self)
|
||||
self:addDraw("input", function()
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
|
||||
|
||||
local val = tostring(base.getValue())
|
||||
local bCol = self:getBackground()
|
||||
local fCol = self:getForeground()
|
||||
local text
|
||||
if (val:len() <= 0) then
|
||||
text = showingText
|
||||
bCol = defaultBGCol or bCol
|
||||
fCol = defaultFGCol or fCol
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("key", self)
|
||||
self.parent:addEvent("char", self)
|
||||
self.parent:addEvent("other_event", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
end
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("InputBG")
|
||||
self.fgColor = self.parent:getTheme("InputText")
|
||||
end
|
||||
text = showingText
|
||||
if (val ~= "") then
|
||||
text = val
|
||||
end
|
||||
text = text:sub(wIndex, w + wIndex - 1)
|
||||
local space = w - text:len()
|
||||
if (space < 0) then
|
||||
space = 0
|
||||
end
|
||||
if (inputType == "password") and (val ~= "") then
|
||||
text = string.rep("*", text:len())
|
||||
end
|
||||
text = text .. string.rep(" ", space)
|
||||
self:addBlit(1, verticalAlign, text, tHex[fCol]:rep(text:len()), tHex[bCol]:rep(text:len()))
|
||||
|
||||
if(self:isFocused())then
|
||||
parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self:getForeground())
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,170 +1,109 @@
|
||||
local Object = require("Object")
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.getValueFromXML
|
||||
local createText = utils.createText
|
||||
local wrapText = utils.wrapText
|
||||
local writeWrappedText = utils.writeWrappedText
|
||||
local tHex = require("tHex")
|
||||
local bigFont = require("bigfont")
|
||||
|
||||
return function(name)
|
||||
return function(name, basalt)
|
||||
-- Label
|
||||
local base = Object(name)
|
||||
local base = basalt.getObject("VisualObject")(name, basalt)
|
||||
local objectType = "Label"
|
||||
|
||||
base:setZIndex(3)
|
||||
base:setSize(5, 1)
|
||||
base:setBackground(false)
|
||||
|
||||
local autoSize = true
|
||||
base:setValue("Label")
|
||||
base.width = 5
|
||||
|
||||
local textHorizontalAlign = "left"
|
||||
local textVerticalAlign = "top"
|
||||
local fontsize = 0
|
||||
|
||||
local fgColChanged,bgColChanged = false,false
|
||||
local text, textAlign = "Label", "left"
|
||||
|
||||
local object = {
|
||||
--- Returns the object type.
|
||||
--- @return string
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
|
||||
--- Returns the label's base object.
|
||||
--- @return object
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
setText = function(self, text)
|
||||
text = tostring(text)
|
||||
base:setValue(text)
|
||||
if (autoSize) then
|
||||
local xOffset = self.parent:getOffset()
|
||||
if(text:len()+self:getX()>self.parent:getWidth()+xOffset)then
|
||||
local newW = self.parent:getWidth()+xOffset - self:getX()
|
||||
base.setSize(self, newW, #createText(text, newW))
|
||||
else
|
||||
base.setSize(self, text:len(), 1)
|
||||
--- Changes the label's text.
|
||||
--- @param newText string The new text of the label.
|
||||
--- @return object
|
||||
setText = function(self, newText)
|
||||
text = tostring(newText)
|
||||
if(autoSize)then
|
||||
local t = wrapText(text, #text)
|
||||
local newW, newH = 1,1
|
||||
for k,v in pairs(t)do
|
||||
newH = newH+1
|
||||
newW = math.max(newW, v:len())
|
||||
end
|
||||
self:setSize(newW, newH)
|
||||
autoSize = true
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setBackground = function(self, col)
|
||||
base.setBackground(self, col)
|
||||
bgColChanged = true
|
||||
self:updateDraw()
|
||||
--- Returns the label's autoSize property.
|
||||
--- @return boolean
|
||||
getAutoSize = function(self)
|
||||
return autoSize
|
||||
end,
|
||||
|
||||
--- Sets the label's autoSize property.
|
||||
--- @param bool boolean The new value of the autoSize property.
|
||||
--- @return object
|
||||
setAutoSize = function(self, bool)
|
||||
autoSize = bool
|
||||
return self
|
||||
end,
|
||||
|
||||
setForeground = function(self, col)
|
||||
base.setForeground(self, col)
|
||||
fgColChanged = true
|
||||
self:updateDraw()
|
||||
return self
|
||||
--- Returns the label's text.
|
||||
--- @return string
|
||||
getText = function(self)
|
||||
return text
|
||||
end,
|
||||
|
||||
setTextAlign = function(self, hor, vert)
|
||||
textHorizontalAlign = hor or textHorizontalAlign
|
||||
textVerticalAlign = vert or textVerticalAlign
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setFontSize = function(self, size)
|
||||
if(size>0)and(size<=4)then
|
||||
fontsize = size-1 or 0
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getFontSize = function(self)
|
||||
return fontsize+1
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end
|
||||
if(xmlValue("verticalAlign", data)~=nil)then textVerticalAlign = xmlValue("verticalAlign", data) end
|
||||
if(xmlValue("horizontalAlign", data)~=nil)then textHorizontalAlign = xmlValue("horizontalAlign", data) end
|
||||
if(xmlValue("font", data)~=nil)then self:setFontSize(xmlValue("font", data)) end
|
||||
return self
|
||||
end,
|
||||
|
||||
setSize = function(self, width, height, rel)
|
||||
base.setSize(self, width, height, rel)
|
||||
--- Sets the size of the label.
|
||||
--- @param width number The width of the label.
|
||||
--- @param height number The height of the label.
|
||||
--- @return object
|
||||
setSize = function(self, width, height)
|
||||
base.setSize(self, width, height)
|
||||
autoSize = false
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
eventHandler = function(self, event)
|
||||
if(event=="basalt_resize")then
|
||||
if (autoSize) then
|
||||
local text = self:getValue()
|
||||
if(text:len()+self:getX()>self.parent:getWidth())then
|
||||
local newW = self.parent:getWidth() - self:getX()
|
||||
base.setSize(self, newW, #createText(text, newW))
|
||||
else
|
||||
base.setSize(self, text:len(), 1)
|
||||
end
|
||||
else
|
||||
--self.parent:removeEvent("other_event", self)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
--- Sets the text alignment of the label.
|
||||
--- @param align string The alignment of the text. Can be "left", "center", or "right".
|
||||
--- @return object
|
||||
setTextAlign = function(self, align)
|
||||
textAlign = align or textAlign
|
||||
return self;
|
||||
end,
|
||||
|
||||
--- Queues a new draw function to be called when the object is drawn.
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
|
||||
if(fontsize==0)then
|
||||
if not(autoSize)then
|
||||
local text = createText(self:getValue(), self:getWidth())
|
||||
for k,v in pairs(text)do
|
||||
if(k<=h)then
|
||||
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
|
||||
end
|
||||
end
|
||||
else
|
||||
if(#self:getValue()+obx>self.parent:getWidth())then
|
||||
local text = createText(self:getValue(), self:getWidth())
|
||||
for k,v in pairs(text)do
|
||||
if(k<=h)then
|
||||
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
|
||||
end
|
||||
end
|
||||
else
|
||||
self.parent:writeText(obx, oby, self:getValue(), self.bgColor, self.fgColor)
|
||||
end
|
||||
end
|
||||
else
|
||||
local tData = bigFont(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.lightGray)
|
||||
if(autoSize)then
|
||||
self:setSize(#tData[1][1], #tData[1]-1)
|
||||
end
|
||||
local oX, oY = self.parent:getSize()
|
||||
local cX, cY = #tData[1][1], #tData[1]
|
||||
obx = obx or math.floor((oX - cX) / 2) + 1
|
||||
oby = oby or math.floor((oY - cY) / 2) + 1
|
||||
|
||||
for i = 1, cY do
|
||||
self.parent:setFG(obx, oby + i - 1, tData[2][i])
|
||||
self.parent:setBG(obx, oby + i - 1, tData[3][i])
|
||||
self.parent:setText(obx, oby + i - 1, tData[1][i])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
base.draw(self)
|
||||
self:addDraw("label", function()
|
||||
local w, h = self:getSize()
|
||||
local align = textAlign=="center" and math.floor(w/2-text:len()/2+0.5) or textAlign=="right" and w-(text:len()-1) or 1
|
||||
writeWrappedText(self, align, 1, text, w, h)
|
||||
end)
|
||||
end,
|
||||
|
||||
--- Initializes the label.
|
||||
init = function(self)
|
||||
self.parent:addEvent("other_event", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("LabelBG")
|
||||
self.fgColor = self.parent:getTheme("LabelText")
|
||||
if(self.parent.bgColor==colors.black)and(self.fgColor==colors.black)then
|
||||
self.fgColor = colors.lightGray
|
||||
end
|
||||
end
|
||||
base.init(self)
|
||||
local parent = self:getParent()
|
||||
self:setForeground(parent:getForeground())
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,59 +1,105 @@
|
||||
local Object = require("Object")
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "List"
|
||||
base.width = 16
|
||||
base.height = 6
|
||||
base:setZIndex(5)
|
||||
|
||||
local list = {}
|
||||
local itemSelectedBG
|
||||
local itemSelectedFG
|
||||
local itemSelectedBG = colors.black
|
||||
local itemSelectedFG = colors.lightGray
|
||||
local selectionColorActive = true
|
||||
local align = "left"
|
||||
local textAlign = "left"
|
||||
local yOffset = 0
|
||||
local scrollable = true
|
||||
|
||||
base:setSize(16, 8)
|
||||
base:setZIndex(5)
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
local parent = self:getParent()
|
||||
self:listenEvent("mouse_click")
|
||||
self:listenEvent("mouse_drag")
|
||||
self:listenEvent("mouse_scroll")
|
||||
return base.init(self)
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
setTextAlign = function(self, align)
|
||||
textAlign = align
|
||||
return self
|
||||
end,
|
||||
|
||||
getTextAlign = function(self)
|
||||
return textAlign
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
addItem = function(self, text, bgCol, fgCol, ...)
|
||||
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
table.insert(list, { text = text, bgCol = bgCol or self:getBackground(), fgCol = fgCol or self:getForeground(), args = { ... } })
|
||||
if (#list <= 1) then
|
||||
self:setValue(list[1], false)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setOptions = function(self, ...)
|
||||
list = {}
|
||||
for k,v in pairs(...)do
|
||||
if(type(v)=="string")then
|
||||
table.insert(list, { text = v, bgCol = self:getBackground(), fgCol = self:getForeground(), args = {} })
|
||||
else
|
||||
table.insert(list, { text = v[1], bgCol = v[2] or self:getBackground(), fgCol = v[3] or self:getForeground(), args = v[4] or {} })
|
||||
end
|
||||
end
|
||||
self:setValue(list[1], false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setOffset = function(self, yOff)
|
||||
yOffset = yOff
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return yOffset
|
||||
end;
|
||||
end,
|
||||
|
||||
removeItem = function(self, index)
|
||||
table.remove(list, index)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getItem = function(self, index)
|
||||
return list[index]
|
||||
end;
|
||||
end,
|
||||
|
||||
getAll = function(self)
|
||||
return list
|
||||
end;
|
||||
end,
|
||||
|
||||
getOptions = function(self)
|
||||
return list
|
||||
end,
|
||||
|
||||
getItemIndex = function(self)
|
||||
local selected = self:getValue()
|
||||
@@ -62,61 +108,53 @@ return function(name)
|
||||
return key
|
||||
end
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
clear = function(self)
|
||||
list = {}
|
||||
self:setValue({}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getItemCount = function(self)
|
||||
return #list
|
||||
end;
|
||||
end,
|
||||
|
||||
editItem = function(self, index, text, bgCol, fgCol, ...)
|
||||
table.remove(list, index)
|
||||
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
table.insert(list, index, { text = text, bgCol = bgCol or self:getBackground(), fgCol = fgCol or self:getForeground(), args = { ... } })
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
selectItem = function(self, index)
|
||||
self:setValue(list[index] or {}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setSelectedItem = function(self, bgCol, fgCol, active)
|
||||
itemSelectedBG = bgCol or self.bgColor
|
||||
itemSelectedFG = fgCol or self.fgColor
|
||||
setSelectionColor = function(self, bgCol, fgCol, active)
|
||||
itemSelectedBG = bgCol or self:getBackground()
|
||||
itemSelectedFG = fgCol or self:getForeground()
|
||||
selectionColorActive = active~=nil and active or true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getSelectionColor = function(self)
|
||||
return itemSelectedBG, itemSelectedFG
|
||||
end,
|
||||
|
||||
isSelectionColorActive = function(self)
|
||||
return selectionColorActive
|
||||
end,
|
||||
|
||||
setScrollable = function(self, scroll)
|
||||
scrollable = scroll
|
||||
if(scroll==nil)then scrollable = true end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
|
||||
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
|
||||
if(xmlValue("scrollable", data)~=nil)then if(xmlValue("scrollable", data))then self:setScrollable(true) else self:setScrollable(false) end end
|
||||
if(xmlValue("offset", data)~=nil)then yOffset = xmlValue("offset", data) end
|
||||
if(data["item"]~=nil)then
|
||||
local tab = data["item"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
@@ -148,7 +186,7 @@ return function(name)
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if(base.mouseHandler(self, button, x, y))then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local w,h = self:getSize()
|
||||
if (#list > 0) then
|
||||
for n = 1, h do
|
||||
@@ -174,42 +212,25 @@ return function(name)
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if(self.bgColor~=false)then
|
||||
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
|
||||
end
|
||||
for n = 1, h do
|
||||
if (list[n + yOffset] ~= nil) then
|
||||
if (list[n + yOffset] == self:getValue()) then
|
||||
if (selectionColorActive) then
|
||||
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), itemSelectedBG, itemSelectedFG)
|
||||
else
|
||||
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
|
||||
end
|
||||
else
|
||||
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
|
||||
end
|
||||
base.draw(self)
|
||||
self:addDraw("list", function()
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getPosition()
|
||||
local w, h = self:getSize()
|
||||
for n = 1, h do
|
||||
if list[n + yOffset] then
|
||||
local t = list[n + yOffset].text
|
||||
local fg, bg = list[n + yOffset].fgCol, list[n + yOffset].bgCol
|
||||
if list[n + yOffset] == self:getValue() and selectionColorActive then
|
||||
fg, bg = itemSelectedFG, itemSelectedBG
|
||||
end
|
||||
self:addBlit(1, n, t, tHex[fg]:rep(#t), tHex[bg]:rep(#t))
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ListBG")
|
||||
self.fgColor = self.parent:getTheme("ListText")
|
||||
itemSelectedBG = self.parent:getTheme("SelectionBG")
|
||||
itemSelectedFG = self.parent:getTheme("SelectionText")
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,170 +1,69 @@
|
||||
local Object = require("Object")
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("List")(name, basalt)
|
||||
local objectType = "Menubar"
|
||||
local object = {}
|
||||
|
||||
base.width = 30
|
||||
base.height = 1
|
||||
base:setSize(30, 1)
|
||||
base:setZIndex(5)
|
||||
|
||||
local list = {}
|
||||
local itemSelectedBG
|
||||
local itemSelectedFG
|
||||
local selectionColorActive = true
|
||||
local align = "left"
|
||||
local itemOffset = 0
|
||||
local space = 1
|
||||
local scrollable = false
|
||||
local space, outerSpace = 1, 1
|
||||
local scrollable = true
|
||||
|
||||
local function maxScroll()
|
||||
local mScroll = 0
|
||||
local xPos = 0
|
||||
local w = object:getWidth()
|
||||
local w = base:getWidth()
|
||||
local list = base:getAll()
|
||||
for n = 1, #list do
|
||||
if (xPos + list[n].text:len() + space * 2 > w) then
|
||||
if(xPos < w)then
|
||||
mScroll = mScroll + (list[n].text:len() + space * 2-(w - xPos))
|
||||
else
|
||||
mScroll = mScroll + list[n].text:len() + space * 2
|
||||
end
|
||||
end
|
||||
xPos = xPos + list[n].text:len() + space * 2
|
||||
|
||||
mScroll = mScroll + list[n].text:len() + space * 2
|
||||
end
|
||||
return mScroll
|
||||
return math.max(mScroll - w, 0)
|
||||
end
|
||||
|
||||
object = {
|
||||
init = function(self)
|
||||
local parent = self:getParent()
|
||||
self:listenEvent("mouse_click")
|
||||
self:listenEvent("mouse_drag")
|
||||
self:listenEvent("mouse_scroll")
|
||||
return base.init(self)
|
||||
end,
|
||||
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
|
||||
addItem = function(self, text, bgCol, fgCol, ...)
|
||||
table.insert(list, { text = tostring(text), bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
if (#list == 1) then
|
||||
self:setValue(list[1])
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getAll = function(self)
|
||||
return list
|
||||
end;
|
||||
|
||||
getItemIndex = function(self)
|
||||
local selected = self:getValue()
|
||||
for key, value in pairs(list) do
|
||||
if (value == selected) then
|
||||
return key
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
clear = function(self)
|
||||
list = {}
|
||||
self:setValue({}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
setSpace = function(self, _space)
|
||||
space = _space or space
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setOffset = function(self, offset)
|
||||
itemOffset = offset or 0
|
||||
if (itemOffset < 0) then
|
||||
itemOffset = 0
|
||||
end
|
||||
|
||||
local mScroll = maxScroll()
|
||||
if (itemOffset > mScroll) then
|
||||
itemOffset = mScroll
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getOffset = function(self)
|
||||
return itemOffset
|
||||
end;
|
||||
end,
|
||||
|
||||
setScrollable = function(self, scroll)
|
||||
scrollable = scroll
|
||||
if(scroll==nil)then scrollable = true end
|
||||
return self
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
|
||||
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
|
||||
if(xmlValue("scrollable", data)~=nil)then if(xmlValue("scrollable", data))then self:setScrollable(true) else self:setScrollable(false) end end
|
||||
if(xmlValue("offset", data)~=nil)then self:setOffset(xmlValue("offset", data)) end
|
||||
if(xmlValue("space", data)~=nil)then space = xmlValue("space", data) end
|
||||
if(data["item"]~=nil)then
|
||||
local tab = data["item"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
removeItem = function(self, index)
|
||||
table.remove(list, index)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getItem = function(self, index)
|
||||
return list[index]
|
||||
end;
|
||||
|
||||
getItemCount = function(self)
|
||||
return #list
|
||||
end;
|
||||
|
||||
editItem = function(self, index, text, bgCol, fgCol, ...)
|
||||
table.remove(list, index)
|
||||
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
selectItem = function(self, index)
|
||||
self:setValue(list[index] or {}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setSelectedItem = function(self, bgCol, fgCol, active)
|
||||
itemSelectedBG = bgCol or self.bgColor
|
||||
itemSelectedFG = fgCol or self.fgColor
|
||||
selectionColorActive = active
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if(base.mouseHandler(self, button, x, y))then
|
||||
local objX, objY = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
if(base:getBase().mouseHandler(self, button, x, y))then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local w,h = self:getSize()
|
||||
local xPos = 0
|
||||
local list = self:getAll()
|
||||
for n = 1, #list do
|
||||
if (list[n] ~= nil) then
|
||||
if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then
|
||||
self:setValue(list[n])
|
||||
self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n])
|
||||
self:sendEvent(event, self, event, 0, x, y, list[n])
|
||||
end
|
||||
xPos = xPos + list[n].text:len() + space * 2
|
||||
end
|
||||
@@ -172,11 +71,10 @@ return function(name)
|
||||
self:updateDraw()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if(base.scrollHandler(self, dir, x, y))then
|
||||
if(base:getBase().scrollHandler(self, dir, x, y))then
|
||||
if(scrollable)then
|
||||
itemOffset = itemOffset + dir
|
||||
if (itemOffset < 0) then
|
||||
@@ -196,46 +94,31 @@ return function(name)
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if(self.bgColor~=false)then
|
||||
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
|
||||
base.draw(self)
|
||||
self:addDraw("list", function()
|
||||
local parent = self:getParent()
|
||||
local w,h = self:getSize()
|
||||
local text = ""
|
||||
local textBGCol = ""
|
||||
local textFGCol = ""
|
||||
local itemSelectedBG, itemSelectedFG = self:getSelectionColor()
|
||||
for _, v in pairs(self:getAll()) do
|
||||
local newItem = (" "):rep(space) .. v.text .. (" "):rep(space)
|
||||
text = text .. newItem
|
||||
if(v == self:getValue())then
|
||||
textBGCol = textBGCol .. tHex[itemSelectedBG or v.bgCol or self:getBackground()]:rep(newItem:len())
|
||||
textFGCol = textFGCol .. tHex[itemSelectedFG or v.FgCol or self:getForeground()]:rep(newItem:len())
|
||||
else
|
||||
textBGCol = textBGCol .. tHex[v.bgCol or self:getBackground()]:rep(newItem:len())
|
||||
textFGCol = textFGCol .. tHex[v.FgCol or self:getForeground()]:rep(newItem:len())
|
||||
end
|
||||
local text = ""
|
||||
local textBGCol = ""
|
||||
local textFGCol = ""
|
||||
for _, v in pairs(list) do
|
||||
local newItem = (" "):rep(space) .. v.text .. (" "):rep(space)
|
||||
text = text .. newItem
|
||||
if(v == self:getValue())then
|
||||
textBGCol = textBGCol .. tHex[itemSelectedBG or v.bgCol or self.bgColor]:rep(newItem:len())
|
||||
textFGCol = textFGCol .. tHex[itemSelectedFG or v.FgCol or self.fgColor]:rep(newItem:len())
|
||||
else
|
||||
textBGCol = textBGCol .. tHex[v.bgCol or self.bgColor]:rep(newItem:len())
|
||||
textFGCol = textFGCol .. tHex[v.FgCol or self.fgColor]:rep(newItem:len())
|
||||
end
|
||||
end
|
||||
|
||||
self.parent:setText(obx, oby, text:sub(itemOffset+1, w+itemOffset))
|
||||
self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, w+itemOffset))
|
||||
self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, w+itemOffset))
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("MenubarBG")
|
||||
self.fgColor = self.parent:getTheme("MenubarText")
|
||||
itemSelectedBG = self.parent:getTheme("SelectionBG")
|
||||
itemSelectedFG = self.parent:getTheme("SelectionText")
|
||||
end
|
||||
self:addBlit(1, 1, text:sub(itemOffset+1, w+itemOffset), textFGCol:sub(itemOffset+1, w+itemOffset), textBGCol:sub(itemOffset+1, w+itemOffset))
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
81
Basalt/objects/MonitorFrame.lua
Normal file
@@ -0,0 +1,81 @@
|
||||
local basaltMon = require("basaltMon")
|
||||
local max,min,sub,rep = math.max,math.min,string.sub,string.rep
|
||||
|
||||
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("BaseFrame")(name, basalt)
|
||||
local objectType = "MonitorFrame"
|
||||
|
||||
base:setTerm(nil)
|
||||
local isMonitorGroup = false
|
||||
local monGroup
|
||||
|
||||
local object = {
|
||||
|
||||
getType = function()
|
||||
return objectType
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
setMonitor = function(self, newMon)
|
||||
if(type(newMon)=="string")then
|
||||
local mon = peripheral.wrap(newMon)
|
||||
if(mon~=nil)then
|
||||
self:setTerm(mon)
|
||||
end
|
||||
elseif(type(newMon)=="table")then
|
||||
self:setTerm(newMon)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setMonitorGroup = function(self, monGrp)
|
||||
monGroup = basaltMon(monGrp)
|
||||
self:setTerm(monGroup)
|
||||
isMonitorGroup = true
|
||||
return self
|
||||
end,
|
||||
|
||||
render = function(self)
|
||||
if(self:getTerm()~=nil)then
|
||||
base.render(self)
|
||||
end
|
||||
end,
|
||||
|
||||
show = function(self)
|
||||
base:getBase().show(self)
|
||||
basalt.setActiveFrame(self)
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
termObject.setPaletteColor(v, colors.packRGB(term.nativePaletteColor((v))))
|
||||
end
|
||||
end
|
||||
for k,v in pairs(colorTheme)do
|
||||
if(type(v)=="number")then
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
|
||||
else
|
||||
local r,g,b = table.unpack(v)
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
}
|
||||
|
||||
object.mouseHandler = function(self, btn, x, y, isMon, monitor, ...)
|
||||
if(isMonitorGroup)then
|
||||
x, y = monGroup.calculateClick(monitor, x, y)
|
||||
end
|
||||
base.mouseHandler(self, btn, x, y, isMon, monitor, ...)
|
||||
end
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
92
Basalt/objects/MovableFrame.lua
Normal file
@@ -0,0 +1,92 @@
|
||||
local max,min,sub,rep = math.max,math.min,string.sub,string.rep
|
||||
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Frame")(name, basalt)
|
||||
local objectType = "MovableFrame"
|
||||
local parent
|
||||
|
||||
local dragXOffset, dragYOffset = 0, 0
|
||||
|
||||
local dragMap = {
|
||||
{x1 = 1, x2 = "width", y1 = 1, y2 = 1}
|
||||
}
|
||||
|
||||
local object = {
|
||||
getType = function()
|
||||
return objectType
|
||||
end,
|
||||
|
||||
setDraggingMap = function(self, t)
|
||||
dragMap = t
|
||||
return self
|
||||
end,
|
||||
|
||||
getDraggingMap = function(self)
|
||||
return dragMap
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType==t or (base.isType~=nil and base.isType(t)) or false
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
load = function(self)
|
||||
base.load(self)
|
||||
self:listenEvent("mouse_click")
|
||||
self:listenEvent("mouse_up")
|
||||
self:listenEvent("mouse_drag")
|
||||
end,
|
||||
|
||||
dragHandler = function(self, btn, x, y)
|
||||
if(base.dragHandler(self, btn, x, y))then
|
||||
if (isDragging) then
|
||||
local xO, yO = parent:getOffset()
|
||||
xO = xO < 0 and math.abs(xO) or -xO
|
||||
yO = yO < 0 and math.abs(yO) or -yO
|
||||
local parentX = 1
|
||||
local parentY = 1
|
||||
parentX, parentY = parent:getAbsolutePosition()
|
||||
self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO)
|
||||
self:updateDraw()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, btn, x, y, ...)
|
||||
if(base.mouseHandler(self, btn, x, y, ...))then
|
||||
parent:setImportant(self)
|
||||
local fx, fy = self:getAbsolutePosition()
|
||||
local w, h = self:getSize()
|
||||
for k,v in pairs(dragMap)do
|
||||
local x1, x2 = v.x1=="width" and w or v.x1, v.x2=="width" and w or v.x2
|
||||
local y1, y2= v.y1=="height" and h or v.y1, v.y2=="height" and h or v.y2
|
||||
if(x>=fx+x1-1)and(x<=fx+x2-1)and(y>=fy+y1-1)and(y<=fy+y2-1)then
|
||||
isDragging = true
|
||||
dragXOffset = fx - x
|
||||
dragYOffset = fy - y
|
||||
return true
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
mouseUpHandler = function(self, ...)
|
||||
isDragging = false
|
||||
return base.mouseUpHandler(self, ...)
|
||||
end,
|
||||
|
||||
setParent = function(self, p, ...)
|
||||
base.setParent(self, p, ...)
|
||||
parent = p
|
||||
return self
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
255
Basalt/objects/Object.lua
Normal file
@@ -0,0 +1,255 @@
|
||||
local basaltEvent = require("basaltEvent")
|
||||
local utils = require("utils")
|
||||
local uuid = utils.uuid
|
||||
|
||||
local unpack,sub = table.unpack,string.sub
|
||||
|
||||
return function(name, basalt)
|
||||
name = name or uuid()
|
||||
assert(basalt~=nil, "Unable to find basalt instance! ID: "..name)
|
||||
|
||||
-- Base object
|
||||
local objectType = "Object" -- not changeable
|
||||
local isEnabled,initialized = true,false
|
||||
|
||||
local eventSystem = basaltEvent()
|
||||
local activeEvents = {}
|
||||
|
||||
local parent
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
if(initialized)then return false end
|
||||
initialized = true
|
||||
return true
|
||||
end,
|
||||
|
||||
load = function(self)
|
||||
end,
|
||||
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end,
|
||||
isType = function(self, t)
|
||||
return objectType==t
|
||||
end,
|
||||
|
||||
getName = function(self)
|
||||
return name
|
||||
end,
|
||||
|
||||
getParent = function(self)
|
||||
return parent
|
||||
end,
|
||||
|
||||
setParent = function(self, newParent, noRemove)
|
||||
if(noRemove)then parent = newParent return self end
|
||||
if (newParent.getType ~= nil and newParent:isType("Container")) then
|
||||
self:remove()
|
||||
newParent:addObject(self)
|
||||
if (self.show) then
|
||||
self:show()
|
||||
end
|
||||
parent = newParent
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
updateEvents = function(self)
|
||||
for k,v in pairs(activeEvents)do
|
||||
parent:removeEvent(k, self)
|
||||
if(v)then
|
||||
parent:addEvent(k, self)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
listenEvent = function(self, event, active)
|
||||
if(parent~=nil)then
|
||||
if(active)or(active==nil)then
|
||||
activeEvents[event] = true
|
||||
parent:addEvent(event, self)
|
||||
elseif(active==false)then
|
||||
activeEvents[event] = false
|
||||
parent:removeEvent(event, self)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
getZIndex = function(self)
|
||||
return 1
|
||||
end,
|
||||
|
||||
enable = function(self)
|
||||
isEnabled = true
|
||||
return self
|
||||
end,
|
||||
|
||||
disable = function(self)
|
||||
isEnabled = false
|
||||
return self
|
||||
end,
|
||||
|
||||
isEnabled = function(self)
|
||||
return isEnabled
|
||||
end,
|
||||
|
||||
remove = function(self)
|
||||
if (parent ~= nil) then
|
||||
parent:removeObject(self)
|
||||
parent:removeEvents(self)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getBaseFrame = function(self)
|
||||
if(parent~=nil)then
|
||||
return parent:getBaseFrame()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onEvent = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("other_event", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
getEventSystem = function(self)
|
||||
return eventSystem
|
||||
end,
|
||||
|
||||
registerEvent = function(self, event, func)
|
||||
if(parent~=nil)then
|
||||
parent:addEvent(event, self)
|
||||
end
|
||||
return eventSystem:registerEvent(event, func)
|
||||
end,
|
||||
|
||||
removeEvent = function(self, event, index)
|
||||
if(eventSystem:getEventCount(event)<1)then
|
||||
if(parent~=nil)then
|
||||
parent:removeEvent(event, self)
|
||||
end
|
||||
end
|
||||
return eventSystem:removeEvent(event, index)
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, ...)
|
||||
local val = self:sendEvent("other_event", event, ...)
|
||||
if(val~=nil)then return val end
|
||||
end,
|
||||
|
||||
customEventHandler = function(self, event, ...)
|
||||
local val = self:sendEvent("custom_event", event, ...)
|
||||
if(val~=nil)then return val end
|
||||
return true
|
||||
end,
|
||||
|
||||
sendEvent = function(self, event, ...)
|
||||
if(event=="other_event")or(event=="custom_event")then
|
||||
return eventSystem:sendEvent(event, self, ...)
|
||||
end
|
||||
return eventSystem:sendEvent(event, self, event, ...)
|
||||
end,
|
||||
|
||||
onClick = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_click", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onClickUp = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_up", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onRelease = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_release", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onScroll = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_scroll", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onHover = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_hover", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onLeave = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_leave", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onDrag = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_drag", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onKey = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("key", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onChar = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("char", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onKeyUp = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("key_up", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return object
|
||||
end
|
||||
@@ -1,28 +1,16 @@
|
||||
local Object = require("Object")
|
||||
local log = require("basaltLogs")
|
||||
|
||||
return function(name)
|
||||
return function(name, basalt)
|
||||
-- Pane
|
||||
local base = Object(name)
|
||||
local base = basalt.getObject("VisualObject")(name, basalt)
|
||||
local objectType = "Pane"
|
||||
|
||||
base:setSize(25, 10)
|
||||
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setBackground = function(self, col, sym, symC)
|
||||
base.setBackground(self, col, sym, symC)
|
||||
return self
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("PaneBG")
|
||||
self.fgColor = self.parent:getTheme("PaneBG")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,19 +1,16 @@
|
||||
local Object = require("Object")
|
||||
local tHex = require("tHex")
|
||||
local process = require("process")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
|
||||
local sub = string.sub
|
||||
|
||||
return function(name, parent)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("VisualObject")(name, basalt)
|
||||
local objectType = "Program"
|
||||
base:setZIndex(5)
|
||||
local object
|
||||
local cachedPath
|
||||
local enviroment = {}
|
||||
|
||||
local function createBasaltWindow(x, y, width, height, self)
|
||||
local function createBasaltWindow(x, y, width, height)
|
||||
local xCursor, yCursor = 1, 1
|
||||
local bgColor, fgColor = colors.black, colors.white
|
||||
local cursorBlink = false
|
||||
@@ -30,7 +27,7 @@ return function(name, parent)
|
||||
|
||||
for i = 0, 15 do
|
||||
local c = 2 ^ i
|
||||
tPalette[c] = { parent:getBasaltInstance().getBaseTerm().getPaletteColour(c) }
|
||||
tPalette[c] = { basalt.getTerm().getPaletteColour(c) }
|
||||
end
|
||||
|
||||
local function createEmptyLines()
|
||||
@@ -66,67 +63,17 @@ return function(name, parent)
|
||||
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
|
||||
if yCursor < 1 or yCursor > height or xCursor < 1 or xCursor + #sText - 1 > width then
|
||||
return
|
||||
end
|
||||
cacheT[yCursor] = sub(cacheT[yCursor], 1, xCursor - 1) .. sText .. sub(cacheT[yCursor], xCursor + #sText, width)
|
||||
cacheFG[yCursor] = sub(cacheFG[yCursor], 1, xCursor - 1) .. sTextColor .. sub(cacheFG[yCursor], xCursor + #sText, width)
|
||||
cacheBG[yCursor] = sub(cacheBG[yCursor], 1, xCursor - 1) .. sBackgroundColor .. sub(cacheBG[yCursor], xCursor + #sText, width)
|
||||
xCursor = xCursor + #sText
|
||||
if visible then
|
||||
updateCursor()
|
||||
end
|
||||
object:updateDraw()
|
||||
end
|
||||
|
||||
local function setText(_x, _y, text)
|
||||
@@ -233,7 +180,7 @@ return function(name, parent)
|
||||
if (visible) then
|
||||
updateCursor()
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
getCursorPos = function()
|
||||
return xCursor, yCursor
|
||||
@@ -310,57 +257,40 @@ return function(name, parent)
|
||||
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
|
||||
for n = 1, height do
|
||||
object:addBlit(1, n, cacheT[n], cacheFG[n], cacheBG[n])
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
scroll = function(offset)
|
||||
if type(offset) ~= "number" then
|
||||
error("bad argument #1 (expected number, got " .. type(offset) .. ")", 2)
|
||||
end
|
||||
assert(type(offset) == "number", "bad argument #1 (expected number, got " .. type(offset) .. ")")
|
||||
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
|
||||
for newY = 1, height do
|
||||
local y = newY + offset
|
||||
if y < 1 or y > height then
|
||||
cacheT[newY] = emptySpaceLine
|
||||
cacheFG[newY] = emptyColorLines[fgColor]
|
||||
cacheBG[newY] = emptyColorLines[bgColor]
|
||||
else
|
||||
cacheT[newY] = cacheT[y]
|
||||
cacheBG[newY] = cacheBG[y]
|
||||
cacheFG[newY] = cacheFG[y]
|
||||
end
|
||||
end
|
||||
end
|
||||
if (visible) then
|
||||
updateCursor()
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
|
||||
isColor = function()
|
||||
return parent:getBasaltInstance().getBaseTerm().isColor()
|
||||
return basalt.getTerm().isColor()
|
||||
end;
|
||||
|
||||
isColour = function()
|
||||
return parent:getBasaltInstance().getBaseTerm().isColor()
|
||||
return basalt.getTerm().isColor()
|
||||
end;
|
||||
|
||||
write = function(text)
|
||||
@@ -416,19 +346,20 @@ return function(name, parent)
|
||||
return basaltwindow
|
||||
end
|
||||
|
||||
base.width = 30
|
||||
base.height = 12
|
||||
local pWindow = createBasaltWindow(1, 1, base.width, base.height)
|
||||
base:setZIndex(5)
|
||||
base:setSize(30, 12)
|
||||
local pWindow = createBasaltWindow(1, 1, 30, 12)
|
||||
local curProcess
|
||||
local paused = false
|
||||
local queuedEvent = {}
|
||||
|
||||
local function updateCursor(self)
|
||||
local parent = self:getParent()
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local obx, oby = self:getPosition()
|
||||
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())
|
||||
parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
|
||||
@@ -452,7 +383,7 @@ return function(name, parent)
|
||||
end
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true))
|
||||
local absX, absY = self:getAbsolutePosition()
|
||||
resumeProcess(self, event, p1, x-absX+1, y-absY+1)
|
||||
updateCursor(self)
|
||||
end
|
||||
@@ -480,8 +411,8 @@ return function(name, parent)
|
||||
|
||||
show = function(self)
|
||||
base.show(self)
|
||||
pWindow.setBackgroundColor(self.bgColor)
|
||||
pWindow.setTextColor(self.fgColor)
|
||||
pWindow.setBackgroundColor(self:getBackground())
|
||||
pWindow.setTextColor(self:getForeground())
|
||||
pWindow.basalt_setVisible(true)
|
||||
return self
|
||||
end;
|
||||
@@ -494,14 +425,8 @@ return function(name, parent)
|
||||
|
||||
setPosition = function(self, x, y, rel)
|
||||
base.setPosition(self, x, y, rel)
|
||||
pWindow.basalt_reposition(self:getAnchorPosition())
|
||||
pWindow.basalt_reposition(self:getPosition())
|
||||
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()
|
||||
@@ -537,37 +462,34 @@ return function(name, parent)
|
||||
pWindow.setTextColor(colors.white)
|
||||
pWindow.clear()
|
||||
pWindow.setCursorPos(1, 1)
|
||||
pWindow.setBackgroundColor(self.bgColor)
|
||||
pWindow.setTextColor(self.fgColor)
|
||||
pWindow.setBackgroundColor(self:getBackground())
|
||||
pWindow.setTextColor(self:getForeground() or colors.white)
|
||||
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
|
||||
self:listenEvent("mouse_click", self)
|
||||
self:listenEvent("mouse_up", self)
|
||||
self:listenEvent("mouse_drag", self)
|
||||
self:listenEvent("mouse_scroll", self)
|
||||
self:listenEvent("key", self)
|
||||
self:listenEvent("key_up", self)
|
||||
self:listenEvent("char", self)
|
||||
self:listenEvent("other_event", self)
|
||||
return self
|
||||
end;
|
||||
|
||||
stop = function(self)
|
||||
stop = function(self)
|
||||
local parent = self:getParent()
|
||||
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
|
||||
parent:setCursor(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
self.parent:removeEvents(self)
|
||||
parent:removeEvents(self)
|
||||
return self
|
||||
end;
|
||||
|
||||
@@ -576,7 +498,7 @@ return function(name, parent)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
self:injectEvents(queuedEvent)
|
||||
self:injectEvents(table.unpack(queuedEvent))
|
||||
queuedEvent = {}
|
||||
end
|
||||
end
|
||||
@@ -588,13 +510,13 @@ return function(name, parent)
|
||||
return paused
|
||||
end;
|
||||
|
||||
injectEvent = function(self, event, p1, p2, p3, p4, ign)
|
||||
injectEvent = function(self, event, ign, ...)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if (paused == false) or (ign) then
|
||||
resumeProcess(self, event, p1, p2, p3, p4)
|
||||
resumeProcess(self, event, ...)
|
||||
else
|
||||
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
|
||||
table.insert(queuedEvent, { event = event, args = {...} })
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -610,10 +532,10 @@ return function(name, parent)
|
||||
return self
|
||||
end;
|
||||
|
||||
injectEvents = function(self, events)
|
||||
injectEvents = function(self, ...)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
for _, value in pairs(events) do
|
||||
for _, value in pairs({...}) do
|
||||
resumeProcess(self, value.event, table.unpack(value.args))
|
||||
end
|
||||
end
|
||||
@@ -682,12 +604,13 @@ return function(name, parent)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
if (self.parent ~= nil) then
|
||||
local parent = self:getParent()
|
||||
if (parent ~= nil) then
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local obx, oby = self:getPosition()
|
||||
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())
|
||||
parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -699,77 +622,70 @@ return function(name, parent)
|
||||
base.loseFocusHandler(self)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(false)
|
||||
local parent = self:getParent()
|
||||
if (parent ~= nil) then
|
||||
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
|
||||
eventHandler = function(self, event, ...)
|
||||
base.eventHandler(self, event, ...)
|
||||
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()
|
||||
if not curProcess:isDead() then
|
||||
if not paused then
|
||||
resumeProcess(self, event, ...)
|
||||
if self:isFocused() then
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getPosition()
|
||||
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
|
||||
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
|
||||
parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
|
||||
table.insert(queuedEvent, { event = event, args = { ... } })
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
resizeHandler = function(self, ...)
|
||||
base.resizeHandler(self, ...)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
pWindow.basalt_resize(self:getSize())
|
||||
resumeProcess(self, "term_resize", self:getSize())
|
||||
else
|
||||
pWindow.basalt_resize(self:getSize())
|
||||
table.insert(queuedEvent, { event = "term_resize", args = { self:getSize() } })
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
repositionHandler = function(self, ...)
|
||||
base.repositionHandler(self, ...)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
pWindow.basalt_reposition(self:getPosition())
|
||||
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
|
||||
base.draw(self)
|
||||
self:addDraw("program", function()
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getPosition()
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
local w,h = self:getSize()
|
||||
pWindow.basalt_update()
|
||||
end)
|
||||
end,
|
||||
|
||||
onError = function(self, ...)
|
||||
@@ -778,9 +694,8 @@ return function(name, parent)
|
||||
self:registerEvent("program_error", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("other_event", self)
|
||||
end
|
||||
local parent = self:getParent()
|
||||
self:listenEvent("other_event")
|
||||
return self
|
||||
end,
|
||||
|
||||
@@ -790,19 +705,13 @@ return function(name, parent)
|
||||
self:registerEvent("program_done", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("other_event", self)
|
||||
end
|
||||
local parent = self:getParent()
|
||||
self:listenEvent("other_event")
|
||||
return self
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ProgramBG")
|
||||
end
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
end
|
||||
@@ -1,52 +1,29 @@
|
||||
local Object = require("Object")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
|
||||
return function(name)
|
||||
-- Checkbox
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "Progressbar"
|
||||
|
||||
local progress = 0
|
||||
|
||||
base:setZIndex(5)
|
||||
base:setValue(false)
|
||||
base.width = 25
|
||||
base.height = 1
|
||||
base:setSize(25, 3)
|
||||
|
||||
local activeBarColor
|
||||
local activeBarColor = colors.black
|
||||
local activeBarSymbol = ""
|
||||
local activeBarSymbolCol = colors.white
|
||||
local bgBarSymbol = ""
|
||||
local direction = 0
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ProgressbarBG")
|
||||
self.fgColor = self.parent:getTheme("ProgressbarText")
|
||||
activeBarColor = self.parent:getTheme("ProgressbarActiveBG")
|
||||
end
|
||||
end,
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("direction", data)~=nil)then direction = xmlValue("direction", data) end
|
||||
if(xmlValue("progressColor", data)~=nil)then activeBarColor = colors[xmlValue("progressColor", data)] end
|
||||
if(xmlValue("progressSymbol", data)~=nil)then activeBarSymbol = xmlValue("progressSymbol", data) end
|
||||
if(xmlValue("backgroundSymbol", data)~=nil)then bgBarSymbol = xmlValue("backgroundSymbol", data) end
|
||||
if(xmlValue("progressSymbolColor", data)~=nil)then activeBarSymbolCol = colors[xmlValue("progressSymbolColor", data)] end
|
||||
if(xmlValue("onDone", data)~=nil)then self:generateXMLEventFunction(self.onProgressDone, xmlValue("onDone", data)) end
|
||||
return self
|
||||
end,
|
||||
|
||||
setDirection = function(self, dir)
|
||||
direction = dir
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setProgressBar = function(self, color, symbol, symbolcolor)
|
||||
activeBarColor = color or activeBarColor
|
||||
@@ -54,13 +31,17 @@ return function(name)
|
||||
activeBarSymbolCol = symbolcolor or activeBarSymbolCol
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getProgressBar = function(self)
|
||||
return activeBarColor, activeBarSymbol, activeBarSymbolCol
|
||||
end,
|
||||
|
||||
setBackgroundSymbol = function(self, symbol)
|
||||
bgBarSymbol = symbol:sub(1, 1)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setProgress = function(self, value)
|
||||
if (value >= 0) and (value <= 100) and (progress ~= value) then
|
||||
@@ -72,51 +53,52 @@ return function(name)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getProgress = function(self)
|
||||
return progress
|
||||
end;
|
||||
end,
|
||||
|
||||
onProgressDone = function(self, f)
|
||||
self:registerEvent("progress_done", f)
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
progressDoneHandler = function(self)
|
||||
self:sendEvent("progress_done", self)
|
||||
end;
|
||||
self:sendEvent("progress_done")
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
|
||||
if(bgBarSymbol~="")then self.parent:drawTextBox(obx, oby, w, h, bgBarSymbol) end
|
||||
if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) end
|
||||
if (direction == 1) then
|
||||
self.parent:drawBackgroundBox(obx, oby, w, h / 100 * progress, activeBarColor)
|
||||
self.parent:drawForegroundBox(obx, oby, w, h / 100 * progress, activeBarSymbolCol)
|
||||
self.parent:drawTextBox(obx, oby, w, h / 100 * progress, activeBarSymbol)
|
||||
elseif (direction == 2) then
|
||||
self.parent:drawBackgroundBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarColor)
|
||||
self.parent:drawForegroundBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbolCol)
|
||||
self.parent:drawTextBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbol)
|
||||
elseif (direction == 3) then
|
||||
self.parent:drawBackgroundBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarColor)
|
||||
self.parent:drawForegroundBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarSymbolCol)
|
||||
self.parent:drawTextBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarSymbol)
|
||||
else
|
||||
self.parent:drawBackgroundBox(obx, oby, w / 100 * progress, h, activeBarColor)
|
||||
self.parent:drawForegroundBox(obx, oby, w / 100 * progress, h, activeBarSymbolCol)
|
||||
self.parent:drawTextBox(obx, oby, w / 100 * progress, h, activeBarSymbol)
|
||||
end
|
||||
base.draw(self)
|
||||
self:addDraw("progressbar", function()
|
||||
local obx, oby = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
local bgCol,fgCol = self:getBackground(), self:getForeground()
|
||||
if(bgCol~=false)then self:addBackgroundBox(1, 1, w, h, bgCol) end
|
||||
if(bgBarSymbol~="")then self:addTextBox(1, 1, w, h, bgBarSymbol) end
|
||||
if(fgCol~=false)then self:addForegroundBox(1, 1, w, h, fgCol) end
|
||||
if (direction == 1) then
|
||||
self:addBackgroundBox(1, 1, w, h / 100 * progress, activeBarColor)
|
||||
self:addForegroundBox(1, 1, w, h / 100 * progress, activeBarSymbolCol)
|
||||
self:addTextBox(1, 1, w, h / 100 * progress, activeBarSymbol)
|
||||
elseif (direction == 3) then
|
||||
self:addBackgroundBox(1, 1 + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarColor)
|
||||
self:addForegroundBox(1, 1 + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbolCol)
|
||||
self:addTextBox(1, 1 + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbol)
|
||||
elseif (direction == 2) then
|
||||
self:addBackgroundBox(1 + math.ceil(w - w / 100 * progress), 1, w / 100 * progress, h, activeBarColor)
|
||||
self:addForegroundBox(1 + math.ceil(w - w / 100 * progress), 1, w / 100 * progress, h, activeBarSymbolCol)
|
||||
self:addTextBox(1 + math.ceil(w - w / 100 * progress), 1, w / 100 * progress, h, activeBarSymbol)
|
||||
else
|
||||
self:addBackgroundBox(1, 1, math.ceil( w / 100 * progress), h, activeBarColor)
|
||||
self:addForegroundBox(1, 1, math.ceil(w / 100 * progress), h, activeBarSymbolCol)
|
||||
self:addTextBox(1, 1, math.ceil(w / 100 * progress), h, activeBarSymbol)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,20 +1,18 @@
|
||||
local Object = require("Object")
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("List")(name, basalt)
|
||||
local objectType = "Radio"
|
||||
base.width = 8
|
||||
|
||||
base:setSize(1, 1)
|
||||
base:setZIndex(5)
|
||||
|
||||
local list = {}
|
||||
local itemSelectedBG
|
||||
local itemSelectedFG
|
||||
local boxSelectedBG
|
||||
local boxSelectedFG
|
||||
local boxNotSelectedBG
|
||||
local boxNotSelectedFG
|
||||
local boxSelectedBG = colors.black
|
||||
local boxSelectedFG = colors.green
|
||||
local boxNotSelectedBG = colors.black
|
||||
local boxNotSelectedFG = colors.red
|
||||
local selectionColorActive = true
|
||||
local symbol = "\7"
|
||||
local align = "left"
|
||||
@@ -22,148 +20,87 @@ return function(name)
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
|
||||
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
|
||||
if(xmlValue("boxBG", data)~=nil)then boxSelectedBG = colors[xmlValue("boxBG", data)] end
|
||||
if(xmlValue("inactiveBoxBG", data)~=nil)then boxNotSelectedBG = colors[xmlValue("inactiveBoxBG", data)] end
|
||||
if(xmlValue("inactiveBoxFG", data)~=nil)then boxNotSelectedFG = colors[xmlValue("inactiveBoxFG", data)] end
|
||||
if(xmlValue("boxFG", data)~=nil)then boxSelectedFG = colors[xmlValue("boxFG", data)] end
|
||||
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data) end
|
||||
if(data["item"]~=nil)then
|
||||
local tab = data["item"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
self:addItem(xmlValue("text", v), xmlValue("x", v), xmlValue("y", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
addItem = function(self, text, x, y, bgCol, fgCol, ...)
|
||||
table.insert(list, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
if (#list == 1) then
|
||||
self:setValue(list[1])
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getAll = function(self)
|
||||
return list
|
||||
end;
|
||||
|
||||
removeItem = function(self, index)
|
||||
table.remove(list, index)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getItem = function(self, index)
|
||||
return list[index]
|
||||
end;
|
||||
|
||||
getItemIndex = function(self)
|
||||
local selected = self:getValue()
|
||||
for key, value in pairs(list) do
|
||||
if (value == selected) then
|
||||
return key
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
clear = function(self)
|
||||
list = {}
|
||||
self:setValue({}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
getItemCount = function(self)
|
||||
return #list
|
||||
end;
|
||||
|
||||
editItem = function(self, index, text, x, y, bgCol, fgCol, ...)
|
||||
table.remove(list, index)
|
||||
table.insert(list, index, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
selectItem = function(self, index)
|
||||
self:setValue(list[index] or {}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setActiveSymbol = function(self, sym)
|
||||
symbol = sym:sub(1,1)
|
||||
self:updateDraw()
|
||||
base.addItem(self, text, bgCol, fgCol, ...)
|
||||
table.insert(list, { x = x or 1, y = y or #list * 2 })
|
||||
return self
|
||||
end,
|
||||
|
||||
setSelectedItem = function(self, bgCol, fgCol, boxBG, boxFG, active)
|
||||
itemSelectedBG = bgCol or itemSelectedBG
|
||||
itemSelectedFG = fgCol or itemSelectedFG
|
||||
boxSelectedBG = boxBG or boxSelectedBG
|
||||
boxSelectedFG = boxFG or boxSelectedFG
|
||||
selectionColorActive = active~=nil and active or true
|
||||
self:updateDraw()
|
||||
removeItem = function(self, index)
|
||||
base.removeItem(self, index)
|
||||
table.remove(list, index)
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
clear = function(self)
|
||||
base.clear(self)
|
||||
list = {}
|
||||
return self
|
||||
end,
|
||||
|
||||
editItem = function(self, index, text, x, y, bgCol, fgCol, ...)
|
||||
base.editItem(self, index, text, bgCol, fgCol, ...)
|
||||
table.remove(list, index)
|
||||
table.insert(list, index, { x = x or 1, y = y or 1 })
|
||||
return self
|
||||
end,
|
||||
|
||||
setBoxSelectionColor = function(self, bg, fg)
|
||||
boxSelectedBG = bg
|
||||
boxSelectedFG = fg
|
||||
return self
|
||||
end,
|
||||
|
||||
getBoxSelectionColor = function(self)
|
||||
return boxSelectedBG, boxSelectedFG
|
||||
end,
|
||||
|
||||
setBoxDefaultColor = function(self, bg, fg)
|
||||
boxNotSelectedBG = bg
|
||||
boxNotSelectedFG = fg
|
||||
return self
|
||||
end,
|
||||
|
||||
getBoxDefaultColor = function(self)
|
||||
return boxNotSelectedBG, boxNotSelectedFG
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y, ...)
|
||||
if (#list > 0) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
for _, value in pairs(list) do
|
||||
if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 1 >= x) and (oby + value.y - 1 == y) then
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local baseList = self:getAll()
|
||||
for k, value in pairs(baseList) do
|
||||
if (obx + list[k].x - 1 <= x) and (obx + list[k].x - 1 + value.text:len() + 1 >= x) and (oby + list[k].y - 1 == y) then
|
||||
self:setValue(value)
|
||||
local val = self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", button, x, y)
|
||||
if(val==false)then return val end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:setFocusedObject(self)
|
||||
end
|
||||
local val = self:sendEvent("mouse_click", self, "mouse_click", button, x, y, ...)
|
||||
self:updateDraw()
|
||||
if(val==false)then return val end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end;
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
for _, value in pairs(list) do
|
||||
self:addDraw("radio", function()
|
||||
local itemSelectedBG, itemSelectedFG = self:getSelectionColor()
|
||||
local baseList = self:getAll()
|
||||
for k, value in pairs(baseList) do
|
||||
if (value == self:getValue()) then
|
||||
if (align == "left") then
|
||||
self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG)
|
||||
self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG)
|
||||
end
|
||||
self:addBlit(list[k].x, list[k].y, symbol, tHex[boxSelectedFG], tHex[boxSelectedBG])
|
||||
self:addBlit(list[k].x + 2, list[k].y, value.text, tHex[itemSelectedFG]:rep(#value.text), tHex[itemSelectedBG]:rep(#value.text))
|
||||
else
|
||||
self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, boxNotSelectedBG or self.bgColor)
|
||||
self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol)
|
||||
self:addBackgroundBox(list[k].x, list[k].y, 1, 1, boxNotSelectedBG or colors.black)
|
||||
self:addBlit(list[k].x + 2, list[k].y, value.text, tHex[value.fgCol]:rep(#value.text), tHex[value.bgCol]:rep(#value.text))
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("MenubarBG")
|
||||
self.fgColor = self.parent:getTheme("MenubarFG")
|
||||
itemSelectedBG = self.parent:getTheme("SelectionBG")
|
||||
itemSelectedFG = self.parent:getTheme("SelectionText")
|
||||
boxSelectedBG = self.parent:getTheme("MenubarBG")
|
||||
boxSelectedFG = self.parent:getTheme("MenubarText")
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
142
Basalt/objects/ScrollableFrame.lua
Normal file
@@ -0,0 +1,142 @@
|
||||
local max,min,sub,rep = math.max,math.min,string.sub,string.rep
|
||||
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Frame")(name, basalt)
|
||||
local objectType = "ScrollableFrame"
|
||||
local parent
|
||||
|
||||
local direction = 0
|
||||
local manualScrollAmount = 0
|
||||
local calculateScrollAmount = true
|
||||
|
||||
local function getHorizontalScrollAmount(self)
|
||||
local amount = 0
|
||||
local objects = self:getObjects()
|
||||
for _, b in pairs(objects) do
|
||||
if(b.element.getWidth~=nil)and(b.element.getX~=nil)then
|
||||
local w, x = b.element:getWidth(), b.element:getX()
|
||||
local width = self:getWidth()
|
||||
if(b.element:getType()=="Dropdown")then
|
||||
if(b.element:isOpened())then
|
||||
local dropdownW = b.element:getDropdownSize()
|
||||
if (dropdownW + x - width >= amount) then
|
||||
amount = max(dropdownW + x - width, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (h + x - width >= amount) then
|
||||
amount = max(w + x - width, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
return amount
|
||||
end
|
||||
|
||||
local function getVerticalScrollAmount(self)
|
||||
local amount = 0
|
||||
local objects = self:getObjects()
|
||||
for _, b in pairs(objects) do
|
||||
if(b.element.getHeight~=nil)and(b.element.getY~=nil)then
|
||||
local h, y = b.element:getHeight(), b.element:getY()
|
||||
local height = self:getHeight()
|
||||
if(b.element:getType()=="Dropdown")then
|
||||
if(b.element:isOpened())then
|
||||
local _,dropdownH = b.element:getDropdownSize()
|
||||
if (dropdownH + y - height >= amount) then
|
||||
amount = max(dropdownH + y - height, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
if (h + y - height >= amount) then
|
||||
amount = max(h + y - height, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
return amount
|
||||
end
|
||||
|
||||
local function scrollHandler(self, dir)
|
||||
local xO, yO = self:getOffset()
|
||||
local scrollAmn
|
||||
if(direction==1)then
|
||||
scrollAmn = calculateScrollAmount and getHorizontalScrollAmount(self) or manualScrollAmount
|
||||
self:setOffset(min(scrollAmn, max(0, xO + dir)), yO)
|
||||
elseif(direction==0)then
|
||||
scrollAmn = calculateScrollAmount and getVerticalScrollAmount(self) or manualScrollAmount
|
||||
self:setOffset(xO, min(scrollAmn, max(0, yO + dir)))
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
|
||||
local object = {
|
||||
getType = function()
|
||||
return objectType
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
setDirection = function(self, dir)
|
||||
direction = dir=="horizontal" and 1 or dir=="vertical" and 0 or direction
|
||||
return self
|
||||
end,
|
||||
|
||||
setScrollAmount = function(self, amount)
|
||||
manualScrollAmount = amount
|
||||
calculateScrollAmount = false
|
||||
return self
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
load = function(self)
|
||||
base.load(self)
|
||||
self:listenEvent("mouse_scroll")
|
||||
end,
|
||||
|
||||
setParent = function(self, p, ...)
|
||||
base.setParent(self, p, ...)
|
||||
parent = p
|
||||
return self
|
||||
end,
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if(base:getBase().scrollHandler(self, dir, x, y))then
|
||||
self:sortElementOrder()
|
||||
for _, obj in ipairs(self:getEvents("mouse_scroll")) do
|
||||
if (obj.element.scrollHandler ~= nil) then
|
||||
local xO, yO = 0, 0
|
||||
if(self.getOffset~=nil)then
|
||||
xO, yO = self:getOffset()
|
||||
end
|
||||
if(obj.element.getIgnoreOffset())then
|
||||
xO, yO = 0, 0
|
||||
end
|
||||
if (obj.element.scrollHandler(obj.element, dir, x+xO, y+yO)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
scrollHandler(self, dir, x, y)
|
||||
self:removeFocusedObject()
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("scrollableFrame", function()
|
||||
if(calculateScrollAmount)then
|
||||
scrollHandler(self, 0)
|
||||
end
|
||||
end, 0)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,42 +1,40 @@
|
||||
local Object = require("Object")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("VisualObject")(name, basalt)
|
||||
local objectType = "Scrollbar"
|
||||
|
||||
base.width = 1
|
||||
base.height = 8
|
||||
base:setValue(1)
|
||||
base:setZIndex(2)
|
||||
base:setSize(1, 8)
|
||||
base:setBackground(colors.lightGray, "\127", colors.gray)
|
||||
|
||||
local barType = "vertical"
|
||||
local symbol = " "
|
||||
local symbolColor
|
||||
local bgSymbol = "\127"
|
||||
local maxValue = base.height
|
||||
local symbolBG = colors.black
|
||||
local symbolFG = colors.black
|
||||
local scrollAmount = 3
|
||||
local index = 1
|
||||
local symbolSize = 1
|
||||
local symbolAutoSize = true
|
||||
|
||||
local function updateSymbolSize()
|
||||
local w,h = base:getSize()
|
||||
if(symbolAutoSize)then
|
||||
symbolSize = math.max((barType == "vertical" and h or w-(#symbol)) - (scrollAmount-1), 1)
|
||||
end
|
||||
end
|
||||
updateSymbolSize()
|
||||
|
||||
local function mouseEvent(self, button, x, y)
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local w,h = self:getSize()
|
||||
if (barType == "horizontal") then
|
||||
for _index = 0, w do
|
||||
if (obx + _index == x) and (oby <= y) and (oby + h > y) then
|
||||
index = math.min(_index + 1, w - (symbolSize - 1))
|
||||
self:setValue(maxValue / w * (index))
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end
|
||||
if (barType == "vertical") then
|
||||
for _index = 0, h do
|
||||
if (oby + _index == y) and (obx <= x) and (obx + w > x) then
|
||||
index = math.min(_index + 1, h - (symbolSize - 1))
|
||||
self:setValue(maxValue / h * (index))
|
||||
self:updateDraw()
|
||||
end
|
||||
updateSymbolSize()
|
||||
local size = barType == "vertical" and h or w
|
||||
for i = 0, size do
|
||||
if ((barType == "vertical" and oby + i == y) or (barType == "horizontal" and obx + i == x)) and (obx <= x) and (obx + w > x) and (oby <= y) and (oby + h > y) then
|
||||
index = math.min(i + 1, size - (#symbol + symbolSize - 2))
|
||||
self:scrollbarMoveHandler()
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -44,23 +42,24 @@ return function(name)
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
|
||||
setSymbol = function(self, _symbol)
|
||||
symbol = _symbol:sub(1, 1)
|
||||
load = function(self)
|
||||
base.load(self)
|
||||
local parent = self:getParent()
|
||||
self:listenEvent("mouse_click")
|
||||
self:listenEvent("mouse_up")
|
||||
self:listenEvent("mouse_scroll")
|
||||
self:listenEvent("mouse_drag")
|
||||
end,
|
||||
|
||||
setSymbol = function(self, _symbol, bg, fg)
|
||||
symbol = _symbol:sub(1,1)
|
||||
symbolBG = bg or symbolBG
|
||||
symbolFG = fg or symbolFG
|
||||
updateSymbolSize()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("maxValue", data)~=nil)then maxValue = xmlValue("maxValue", data) end
|
||||
if(xmlValue("backgroundSymbol", data)~=nil)then bgSymbol = xmlValue("backgroundSymbol", data):sub(1,1) end
|
||||
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data):sub(1,1) end
|
||||
if(xmlValue("barType", data)~=nil)then barType = xmlValue("barType", data):lower() end
|
||||
if(xmlValue("symbolSize", data)~=nil)then self:setSymbolSize(xmlValue("symbolSize", data)) end
|
||||
if(xmlValue("symbolColor", data)~=nil)then symbolColor = colors[xmlValue("symbolColor", data)] end
|
||||
if(xmlValue("index", data)~=nil)then self:setIndex(xmlValue("index", data)) end
|
||||
end,
|
||||
|
||||
setIndex = function(self, _index)
|
||||
@@ -69,54 +68,41 @@ return function(name)
|
||||
index = 1
|
||||
end
|
||||
local w,h = self:getSize()
|
||||
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
|
||||
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
|
||||
--index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
|
||||
updateSymbolSize()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setScrollAmount = function(self, amount)
|
||||
scrollAmount = amount
|
||||
updateSymbolSize()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getIndex = function(self)
|
||||
return index
|
||||
local w,h = self:getSize()
|
||||
return scrollAmount > (barType=="vertical" and h or w) and math.floor(scrollAmount/(barType=="vertical" and h or w) * index) or index
|
||||
end,
|
||||
|
||||
setSymbolSize = function(self, size)
|
||||
symbolSize = tonumber(size) or 1
|
||||
local w,h = self:getSize()
|
||||
if (barType == "vertical") then
|
||||
self:setValue(index - 1 * (maxValue / (h - (symbolSize - 1))) - (maxValue / (h - (symbolSize - 1))))
|
||||
elseif (barType == "horizontal") then
|
||||
self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1))))
|
||||
end
|
||||
symbolAutoSize = size~=false and false or true
|
||||
updateSymbolSize()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setMaxValue = function(self, val)
|
||||
maxValue = val
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setBackgroundSymbol = function(self, _bgSymbol)
|
||||
bgSymbol = string.sub(_bgSymbol, 1, 1)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setSymbolColor = function(self, col)
|
||||
symbolColor = col
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setBarType = function(self, _typ)
|
||||
barType = _typ:lower()
|
||||
updateSymbolSize()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if (base.mouseHandler(self, button, x, y)) then
|
||||
mouseHandler = function(self, button, x, y, ...)
|
||||
if (base.mouseHandler(self, button, x, y, ...)) then
|
||||
mouseEvent(self, button, x, y)
|
||||
return true
|
||||
end
|
||||
@@ -131,58 +117,70 @@ return function(name)
|
||||
return false
|
||||
end,
|
||||
|
||||
setSize = function(self, ...)
|
||||
base.setSize(self, ...)
|
||||
updateSymbolSize()
|
||||
return self
|
||||
end,
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if(base.scrollHandler(self, dir, x, y))then
|
||||
local w,h = self:getSize()
|
||||
updateSymbolSize()
|
||||
index = index + dir
|
||||
if (index < 1) then
|
||||
index = 1
|
||||
end
|
||||
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
|
||||
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
|
||||
index = math.min(index, (barType == "vertical" and h or w) - (barType == "vertical" and symbolSize - 1 or #symbol+symbolSize-2))
|
||||
self:scrollbarMoveHandler()
|
||||
self:updateDraw()
|
||||
end
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if (barType == "horizontal") then
|
||||
self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor)
|
||||
self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor)
|
||||
self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(w - (index + symbolSize - 1)), self.bgColor, self.fgColor)
|
||||
end
|
||||
onChange = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("scrollbar_moved", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
if (barType == "vertical") then
|
||||
for n = 0, h - 1 do
|
||||
if (index == n + 1) then
|
||||
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
|
||||
self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor)
|
||||
end
|
||||
else
|
||||
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
|
||||
self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor)
|
||||
end
|
||||
|
||||
scrollbarMoveHandler = function(self)
|
||||
self:sendEvent("scrollbar_moved", self:getIndex())
|
||||
end,
|
||||
|
||||
customEventHandler = function(self, event, ...)
|
||||
base.customEventHandler(self, event, ...)
|
||||
if(event=="basalt_FrameResize")then
|
||||
updateSymbolSize()
|
||||
end
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("scrollbar", function()
|
||||
local parent = self:getParent()
|
||||
local w,h = self:getSize()
|
||||
local bgCol,fgCol = self:getBackground(), self:getForeground()
|
||||
if (barType == "horizontal") then
|
||||
for n = 0, h - 1 do
|
||||
self:addBlit(index, 1 + n, symbol:rep(symbolSize), tHex[symbolFG]:rep(#symbol*symbolSize), tHex[symbolBG]:rep(#symbol*symbolSize))
|
||||
end
|
||||
elseif (barType == "vertical") then
|
||||
for n = 0, h - 1 do
|
||||
if (index == n + 1) then
|
||||
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
|
||||
self:addBlit(1, index + curIndexOffset, symbol:rep(math.max(#symbol, w)), tHex[symbolFG]:rep(math.max(#symbol, w)), tHex[symbolBG]:rep(math.max(#symbol, w)))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ScrollbarBG")
|
||||
self.fgColor = self.parent:getTheme("ScrollbarText")
|
||||
symbolColor = self.parent:getTheme("ScrollbarSymbolColor")
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,66 +1,49 @@
|
||||
local Object = require("Object")
|
||||
local log = require("basaltLogs")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "Slider"
|
||||
|
||||
base.width = 8
|
||||
base.height = 1
|
||||
base:setSize(12, 1)
|
||||
base:setValue(1)
|
||||
base:setBackground(false, "\140", colors.black)
|
||||
|
||||
local barType = "horizontal"
|
||||
local symbol = " "
|
||||
local symbolColor
|
||||
local bgSymbol = "\140"
|
||||
local maxValue = base.width
|
||||
local symbolFG = colors.black
|
||||
local symbolBG = colors.gray
|
||||
local maxValue = 12
|
||||
local index = 1
|
||||
local symbolSize = 1
|
||||
|
||||
local function mouseEvent(self, button, x, y)
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local w,h = self:getSize()
|
||||
if (barType == "horizontal") then
|
||||
for _index = 0, w do
|
||||
if (obx + _index == x) and (oby <= y) and (oby + h > y) then
|
||||
index = math.min(_index + 1, w - (symbolSize - 1))
|
||||
self:setValue(maxValue / w * (index))
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end
|
||||
if (barType == "vertical") then
|
||||
for _index = 0, h do
|
||||
if (oby + _index == y) and (obx <= x) and (obx + w > x) then
|
||||
index = math.min(_index + 1, h - (symbolSize - 1))
|
||||
self:setValue(maxValue / h * (index))
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
local obx, oby = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
local size = barType == "vertical" and h or w
|
||||
for i = 0, size do
|
||||
if ((barType == "vertical" and oby + i == y) or (barType == "horizontal" and obx + i == x)) and (obx <= x) and (obx + w > x) and (oby <= y) and (oby + h > y) then
|
||||
index = math.min(i + 1, size - (#symbol + symbolSize - 2))
|
||||
self:setValue(maxValue / size * index)
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
end,
|
||||
|
||||
load = function(self)
|
||||
self:listenEvent("mouse_click")
|
||||
self:listenEvent("mouse_drag")
|
||||
self:listenEvent("mouse_scroll")
|
||||
end,
|
||||
|
||||
setSymbol = function(self, _symbol)
|
||||
symbol = _symbol:sub(1, 1)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("maxValue", data)~=nil)then maxValue = xmlValue("maxValue", data) end
|
||||
if(xmlValue("backgroundSymbol", data)~=nil)then bgSymbol = xmlValue("backgroundSymbol", data):sub(1,1) end
|
||||
if(xmlValue("barType", data)~=nil)then barType = xmlValue("barType", data):lower() end
|
||||
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data):sub(1,1) end
|
||||
if(xmlValue("symbolSize", data)~=nil)then self:setSymbolSize(xmlValue("symbolSize", data)) end
|
||||
if(xmlValue("symbolColor", data)~=nil)then symbolColor = colors[xmlValue("symbolColor", data)] end
|
||||
if(xmlValue("index", data)~=nil)then self:setIndex(xmlValue("index", data)) end
|
||||
end,
|
||||
|
||||
setIndex = function(self, _index)
|
||||
@@ -79,39 +62,22 @@ return function(name)
|
||||
return index
|
||||
end,
|
||||
|
||||
setSymbolSize = function(self, size)
|
||||
symbolSize = tonumber(size) or 1
|
||||
if (barType == "vertical") then
|
||||
self:setValue(index - 1 * (maxValue / (h - (symbolSize - 1))) - (maxValue / (h - (symbolSize - 1))))
|
||||
elseif (barType == "horizontal") then
|
||||
self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1))))
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setMaxValue = function(self, val)
|
||||
maxValue = val
|
||||
return self
|
||||
end;
|
||||
|
||||
setBackgroundSymbol = function(self, _bgSymbol)
|
||||
bgSymbol = string.sub(_bgSymbol, 1, 1)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setSymbolColor = function(self, col)
|
||||
symbolColor = col
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setBarType = function(self, _typ)
|
||||
barType = _typ:lower()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if (base.mouseHandler(self, button, x, y)) then
|
||||
@@ -145,44 +111,33 @@ return function(name)
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if (barType == "horizontal") then
|
||||
self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor)
|
||||
self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor)
|
||||
self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(w - (index + symbolSize - 1)), self.bgColor, self.fgColor)
|
||||
end
|
||||
base.draw(self)
|
||||
self:addDraw("slider", function()
|
||||
local w,h = self:getSize()
|
||||
local bgCol,fgCol = self:getBackground(), self:getForeground()
|
||||
if (barType == "horizontal") then
|
||||
self:addText(index, oby, symbol:rep(symbolSize))
|
||||
if(symbolBG~=false)then self:addBG(index, 1, tHex[symbolBG]:rep(#symbol*symbolSize)) end
|
||||
if(symbolFG~=false)then self:addFG(index, 1, tHex[symbolFG]:rep(#symbol*symbolSize)) end
|
||||
end
|
||||
|
||||
if (barType == "vertical") then
|
||||
for n = 0, h - 1 do
|
||||
if (index == n + 1) then
|
||||
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
|
||||
self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor)
|
||||
end
|
||||
else
|
||||
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
|
||||
self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor)
|
||||
end
|
||||
if (barType == "vertical") then
|
||||
for n = 0, h - 1 do
|
||||
if (index == n + 1) then
|
||||
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
|
||||
self:addBlit(1, 1+n+curIndexOffset, symbol, tHex[symbolColor], tHex[symbolColor])
|
||||
end
|
||||
else
|
||||
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
|
||||
self:addBlit(1, 1+n, bgSymbol, tHex[fgCol], tHex[bgCol])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("SliderBG")
|
||||
self.fgColor = self.parent:getTheme("SliderText")
|
||||
symbolColor = self.parent:getTheme("SliderSymbolColor")
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,14 +1,8 @@
|
||||
local Object = require("Object")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "Switch"
|
||||
|
||||
base.width = 2
|
||||
base.height = 1
|
||||
base.bgColor = colors.lightGray
|
||||
base.fgColor = colors.gray
|
||||
base:setSize(4, 1)
|
||||
base:setValue(false)
|
||||
base:setZIndex(5)
|
||||
|
||||
@@ -19,71 +13,53 @@ return function(name)
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setSymbolColor = function(self, symbolColor)
|
||||
bgSymbol = symbolColor
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setActiveBackground = function(self, bgcol)
|
||||
activeBG = bgcol
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setInactiveBackground = function(self, bgcol)
|
||||
inactiveBG = bgcol
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("inactiveBG", data)~=nil)then inactiveBG = colors[xmlValue("inactiveBG", data)] end
|
||||
if(xmlValue("activeBG", data)~=nil)then activeBG = colors[xmlValue("activeBG", data)] end
|
||||
if(xmlValue("symbolColor", data)~=nil)then bgSymbol = colors[xmlValue("symbolColor", data)] end
|
||||
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if (base.mouseHandler(self, button, x, y)) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
setSymbol = function(self, col)
|
||||
bgSymbol = col
|
||||
return self
|
||||
end,
|
||||
|
||||
setActiveBackground = function(self, col)
|
||||
activeBG = col
|
||||
return self
|
||||
end,
|
||||
|
||||
setInactiveBackground = function(self, col)
|
||||
inactiveBG = col
|
||||
return self
|
||||
end,
|
||||
|
||||
|
||||
load = function(self)
|
||||
self:listenEvent("mouse_click")
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, ...)
|
||||
if (base.mouseHandler(self, ...)) then
|
||||
self:setValue(not self:getValue())
|
||||
self:updateDraw()
|
||||
return true
|
||||
end
|
||||
end;
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
|
||||
if(self:getValue())then
|
||||
self.parent:drawBackgroundBox(obx, oby, 1, h, activeBG)
|
||||
self.parent:drawBackgroundBox(obx+1, oby, 1, h, bgSymbol)
|
||||
else
|
||||
self.parent:drawBackgroundBox(obx, oby, 1, h, bgSymbol)
|
||||
self.parent:drawBackgroundBox(obx+1, oby, 1, h, inactiveBG)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("SwitchBG")
|
||||
self.fgColor = self.parent:getTheme("SwitchText")
|
||||
bgSymbol = self.parent:getTheme("SwitchBGSymbol")
|
||||
inactiveBG = self.parent:getTheme("SwitchInactive")
|
||||
activeBG = self.parent:getTheme("SwitchActive")
|
||||
end
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("switch", function()
|
||||
local parent = self:getParent()
|
||||
local bgCol,fgCol = self:getBackground(), self:getForeground()
|
||||
local w,h = self:getSize()
|
||||
if(self:getValue())then
|
||||
self:addBackgroundBox(1, 1, w, h, activeBG)
|
||||
self:addBackgroundBox(w, 1, 1, h, bgSymbol)
|
||||
else
|
||||
self:addBackgroundBox(1, 1, w, h, inactiveBG)
|
||||
self:addBackgroundBox(1, 1, 1, h, bgSymbol)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,12 +1,9 @@
|
||||
local Object = require("Object")
|
||||
local tHex = require("tHex")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local log = require("basaltLogs")
|
||||
|
||||
local rep,find,gmatch,sub,len = string.rep,string.find,string.gmatch,string.sub,string.len
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "Textfield"
|
||||
local hIndex, wIndex, textX, textY = 1, 1, 1, 1
|
||||
|
||||
@@ -20,8 +17,7 @@ return function(name)
|
||||
|
||||
local selectionBG,selectionFG = colors.lightBlue,colors.black
|
||||
|
||||
base.width = 30
|
||||
base.height = 12
|
||||
base:setSize(30, 12)
|
||||
base:setZIndex(5)
|
||||
|
||||
local function isSelected()
|
||||
@@ -32,57 +28,56 @@ return function(name)
|
||||
end
|
||||
|
||||
local function getSelectionCoordinates()
|
||||
local sx,ex,sy,ey
|
||||
if(isSelected())then
|
||||
if(startSelX>endSelX)then
|
||||
sx,ex = endSelX,startSelX
|
||||
else
|
||||
sx,ex = startSelX,endSelX
|
||||
end
|
||||
if(startSelY>endSelY)then
|
||||
sy,ey = endSelY,startSelY
|
||||
else
|
||||
sy,ey = startSelY,endSelY
|
||||
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
|
||||
return sx,ex,sy,ey
|
||||
end
|
||||
|
||||
local function getSelection()
|
||||
|
||||
end
|
||||
|
||||
local function removeSelection(self)
|
||||
local sx,ex,sy,ey = getSelectionCoordinates(self)
|
||||
for n=ey,sy,-1 do
|
||||
if(n==sy)or(n==ey)then
|
||||
local l = lines[n]
|
||||
local b = bgLines[n]
|
||||
local f = fgLines[n]
|
||||
if(n==sy)and(n==ey)then
|
||||
l = l:sub(1,sx-1)..l:sub(ex+1,l:len())
|
||||
b = b:sub(1,sx-1)..b:sub(ex+1,b:len())
|
||||
f = f:sub(1,sx-1)..f:sub(ex+1,f:len())
|
||||
elseif(n==sx)then
|
||||
l = l:sub(1, sx)
|
||||
b = b:sub(1, sx)
|
||||
f = f:sub(1, sx)
|
||||
elseif(n==sy)then
|
||||
l = l:sub(ex, l:len())
|
||||
b = b:sub(ex, b:len())
|
||||
f = f:sub(ex, f:len())
|
||||
end
|
||||
lines[n] = l
|
||||
bgLines[n] = b
|
||||
fgLines[n] = f
|
||||
else
|
||||
table.remove(lines, n)
|
||||
table.remove(bgLines, n)
|
||||
table.remove(fgLines, n)
|
||||
local sx, ex, sy, ey = getSelectionCoordinates(self)
|
||||
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 = startSelX,startSelY
|
||||
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
|
||||
|
||||
textX, textY = sx, sy
|
||||
startSelX, endSelX, startSelY, endSelY = nil, nil, nil, nil
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -105,8 +100,8 @@ return function(name)
|
||||
|
||||
local function updateColors(self, l)
|
||||
l = l or textY
|
||||
local fgLine = tHex[self.fgColor]:rep(fgLines[l]:len())
|
||||
local bgLine = tHex[self.bgColor]:rep(bgLines[l]:len())
|
||||
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
|
||||
@@ -160,60 +155,30 @@ return function(name)
|
||||
return self
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(data["lines"]~=nil)then
|
||||
local l = data["lines"]["line"]
|
||||
if(l.properties~=nil)then l = {l} end
|
||||
for k,v in pairs(l)do
|
||||
self:addLine(v:value())
|
||||
end
|
||||
end
|
||||
if(data["keywords"]~=nil)then
|
||||
for k,v in pairs(data["keywords"])do
|
||||
if(colors[k]~=nil)then
|
||||
local entry = v
|
||||
if(entry.properties~=nil)then entry = {entry} end
|
||||
local tab = {}
|
||||
for a,b in pairs(entry)do
|
||||
local keywordList = b["keyword"]
|
||||
if(b["keyword"].properties~=nil)then keywordList = {b["keyword"]} end
|
||||
for c,d in pairs(keywordList)do
|
||||
table.insert(tab, d:value())
|
||||
end
|
||||
end
|
||||
self:addKeywords(colors[k], tab)
|
||||
end
|
||||
end
|
||||
end
|
||||
if(data["rules"]~=nil)then
|
||||
if(data["rules"]["rule"]~=nil)then
|
||||
local tab = data["rules"]["rule"]
|
||||
if(data["rules"]["rule"].properties~=nil)then tab = {data["rules"]["rule"]} end
|
||||
for k,v in pairs(tab)do
|
||||
setSelection = function(self, fg, bg)
|
||||
selectionFG = fg or selectionFG
|
||||
selectionBG = bg or selectionBG
|
||||
return self
|
||||
end,
|
||||
|
||||
if(xmlValue("pattern", v)~=nil)then
|
||||
self:addRule(xmlValue("pattern", v), colors[xmlValue("fg", v)], colors[xmlValue("bg", v)])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
getSelection = function(self)
|
||||
return selectionFG, selectionBG
|
||||
end,
|
||||
|
||||
getLines = function(self)
|
||||
return lines
|
||||
end;
|
||||
end,
|
||||
|
||||
getLine = function(self, index)
|
||||
return lines[index]
|
||||
end;
|
||||
end,
|
||||
|
||||
editLine = function(self, index, text)
|
||||
lines[index] = text or lines[index]
|
||||
updateColors(self, index)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
clear = function(self)
|
||||
lines = {""}
|
||||
@@ -227,21 +192,23 @@ return function(name)
|
||||
|
||||
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[self.bgColor]:rep(text:len())
|
||||
fgLines[1] = tHex[self.fgColor]:rep(text:len())
|
||||
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[self.bgColor]:rep(text:len()))
|
||||
table.insert(fgLines, index, tHex[self.fgColor]:rep(text:len()))
|
||||
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[self.bgColor]:rep(text:len()))
|
||||
table.insert(fgLines, tHex[self.fgColor]:rep(text:len()))
|
||||
table.insert(bgLines, tHex[bgColor]:rep(text:len()))
|
||||
table.insert(fgLines, tHex[fgColor]:rep(text:len()))
|
||||
end
|
||||
end
|
||||
updateColors(self, index or #lines)
|
||||
@@ -285,13 +252,13 @@ return function(name)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setKeywords = function(self, color, tab)
|
||||
keyWords[color] = tab
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
removeLine = function(self, index)
|
||||
if(#lines>1)then
|
||||
@@ -305,83 +272,91 @@ return function(name)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getTextCursor = function(self)
|
||||
return textX, textY
|
||||
end;
|
||||
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,
|
||||
|
||||
getFocusHandler = function(self)
|
||||
base.getFocusHandler(self)
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self.fgColor)
|
||||
end
|
||||
end
|
||||
end;
|
||||
local obx, oby = self:getPosition()
|
||||
self:getParent():setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self:getForeground())
|
||||
end,
|
||||
|
||||
loseFocusHandler = function(self)
|
||||
base.loseFocusHandler(self)
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(false)
|
||||
end
|
||||
end;
|
||||
self:getParent():setCursor(false)
|
||||
end,
|
||||
|
||||
keyHandler = function(self, key)
|
||||
if (base.keyHandler(self, event, key)) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
if (key == keys.backspace) then
|
||||
-- on backspace
|
||||
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
|
||||
if(isSelected())then
|
||||
removeSelection(self)
|
||||
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
|
||||
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
|
||||
end
|
||||
if (textY < hIndex) then
|
||||
hIndex = hIndex - 1
|
||||
if (textY < hIndex) then
|
||||
hIndex = hIndex - 1
|
||||
end
|
||||
end
|
||||
updateColors(self)
|
||||
self:setValue("")
|
||||
end
|
||||
|
||||
if (key == keys.delete) then
|
||||
elseif (key == keys.delete) then
|
||||
-- on delete
|
||||
if(isSelected())then
|
||||
removeSelection(self)
|
||||
@@ -400,9 +375,10 @@ return function(name)
|
||||
end
|
||||
end
|
||||
updateColors(self)
|
||||
end
|
||||
|
||||
if (key == keys.enter) then
|
||||
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()))
|
||||
@@ -417,9 +393,8 @@ return function(name)
|
||||
hIndex = hIndex + 1
|
||||
end
|
||||
self:setValue("")
|
||||
end
|
||||
|
||||
if (key == keys.up) then
|
||||
elseif (key == keys.up) then
|
||||
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
|
||||
-- arrow up
|
||||
if (textY > 1) then
|
||||
textY = textY - 1
|
||||
@@ -440,8 +415,8 @@ return function(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if (key == keys.down) then
|
||||
elseif (key == keys.down) then
|
||||
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
|
||||
-- arrow down
|
||||
if (textY < #lines) then
|
||||
textY = textY + 1
|
||||
@@ -460,8 +435,8 @@ return function(name)
|
||||
hIndex = hIndex + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
if (key == keys.right) then
|
||||
elseif (key == keys.right) then
|
||||
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
|
||||
-- arrow right
|
||||
textX = textX + 1
|
||||
if (textY < #lines) then
|
||||
@@ -482,8 +457,8 @@ return function(name)
|
||||
wIndex = 1
|
||||
end
|
||||
|
||||
end
|
||||
if (key == keys.left) then
|
||||
elseif (key == keys.left) then
|
||||
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
|
||||
-- arrow left
|
||||
textX = textX - 1
|
||||
if (textX >= 1) then
|
||||
@@ -504,6 +479,19 @@ return function(name)
|
||||
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
|
||||
@@ -519,7 +507,7 @@ return function(name)
|
||||
if (cursorX < 1) then
|
||||
cursorX = 0
|
||||
end
|
||||
self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor)
|
||||
parent:setCursor(true, obx + cursorX, oby + cursorY, self:getForeground())
|
||||
self:updateDraw()
|
||||
return true
|
||||
end
|
||||
@@ -527,11 +515,15 @@ return function(name)
|
||||
|
||||
charHandler = function(self, char)
|
||||
if(base.charHandler(self, char))then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
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.fgColor] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
|
||||
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor] .. bgLines[textY]:sub(textX, bgLines[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
|
||||
@@ -552,10 +544,7 @@ return function(name)
|
||||
if (cursorX < 1) then
|
||||
cursorX = 0
|
||||
end
|
||||
if(isSelected())then
|
||||
removeSelection(self)
|
||||
end
|
||||
self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor)
|
||||
parent:setCursor(true, obx + cursorX, oby + cursorY, self:getForeground())
|
||||
self:updateDraw()
|
||||
return true
|
||||
end
|
||||
@@ -563,30 +552,31 @@ return function(name)
|
||||
|
||||
dragHandler = function(self, button, x, y)
|
||||
if (base.dragHandler(self, button, x, y)) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local anchx, anchy = self:getAnchorPosition()
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local anchx, anchy = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
if (lines[y - oby + hIndex] ~= nil) then
|
||||
if(anchx+w > anchx + x - (obx+1)+ wIndex)and(anchx < anchx + x - obx+ wIndex)then
|
||||
if anchx <= x - obx + wIndex and anchx + w > x - obx + wIndex then
|
||||
textX = x - obx + wIndex
|
||||
textY = y - oby + hIndex
|
||||
endSelX = textX
|
||||
endSelY = textY
|
||||
if (textX > lines[textY]:len()) then
|
||||
|
||||
if textX > lines[textY]:len() then
|
||||
textX = lines[textY]:len() + 1
|
||||
endSelX = textX
|
||||
end
|
||||
|
||||
if (textX < wIndex) then
|
||||
endSelX = textX
|
||||
endSelY = textY
|
||||
|
||||
if textX < wIndex then
|
||||
wIndex = textX - 1
|
||||
if (wIndex < 1) then
|
||||
if wIndex < 1 then
|
||||
wIndex = 1
|
||||
end
|
||||
end
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
|
||||
parent:setCursor(not isSelected(), anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
@@ -594,8 +584,9 @@ return function(name)
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if (base.scrollHandler(self, dir, x, y)) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local anchx, anchy = self:getAnchorPosition()
|
||||
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
|
||||
@@ -607,9 +598,9 @@ return function(name)
|
||||
end
|
||||
|
||||
if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (anchy + textY - hIndex >= anchy and anchy + textY - hIndex < anchy + h) then
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
parent:setCursor(not isSelected(), anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
|
||||
else
|
||||
self.parent:setCursor(false)
|
||||
parent:setCursor(false)
|
||||
end
|
||||
self:updateDraw()
|
||||
return true
|
||||
@@ -618,8 +609,9 @@ return function(name)
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if (base.mouseHandler(self, button, x, y)) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local anchx, anchy = self:getAnchorPosition()
|
||||
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
|
||||
@@ -639,17 +631,15 @@ return function(name)
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
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(self:getAnchorPosition())
|
||||
local anchx, anchy = self:getAnchorPosition()
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local anchx, anchy = self:getPosition()
|
||||
if (lines[y - oby + hIndex] ~= nil) then
|
||||
endSelX = x - obx + wIndex
|
||||
endSelY = y - oby + hIndex
|
||||
@@ -669,98 +659,86 @@ return function(name)
|
||||
if(base.eventHandler(self, event, paste, p2, p3, p4))then
|
||||
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[self.fgColor]:rep(paste:len()) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
|
||||
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor]:rep(paste:len()) .. bgLines[textY]:sub(textX, bgLines[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:getAnchorPosition()
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
local anchx, anchy = self:getPosition()
|
||||
parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, fgColor)
|
||||
updateColors(self)
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
setSelectionColor = function(self, bg, fg)
|
||||
selectionBG = bg or selectionBG
|
||||
selectionFG = fg or selectionFG
|
||||
return self
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
for n = 1, h do
|
||||
local text = ""
|
||||
local bg = ""
|
||||
local fg = ""
|
||||
if (lines[n + hIndex - 1] ~= nil) then
|
||||
text = lines[n + hIndex - 1]
|
||||
fg = fgLines[n + hIndex - 1]
|
||||
bg = bgLines[n + hIndex - 1]
|
||||
end
|
||||
text = text:sub(wIndex, w + wIndex - 1)
|
||||
bg = bg:sub(wIndex, w + wIndex - 1)
|
||||
fg = fg:sub(wIndex, w + wIndex - 1)
|
||||
local space = w - text:len()
|
||||
if (space < 0) then
|
||||
space = 0
|
||||
end
|
||||
text = text .. rep(self.bgSymbol, space)
|
||||
bg = bg .. rep(tHex[self.bgColor], space)
|
||||
fg = fg .. rep(tHex[self.fgColor], space)
|
||||
self.parent:setText(obx, oby + n - 1, text)
|
||||
self.parent:setBG(obx, oby + n - 1, bg)
|
||||
self.parent:setFG(obx, oby + n - 1, fg)
|
||||
base.draw(self)
|
||||
self:addDraw("textfield", function()
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getPosition()
|
||||
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
|
||||
--[[
|
||||
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
|
||||
local sx,ex,sy,ey = getSelectionCoordinates(self)
|
||||
for n=sy,ey do
|
||||
local line = lines[n]:len()
|
||||
local xOffset = 0
|
||||
if(n==sy)and(n==ey)then
|
||||
xOffset = sx-1
|
||||
line = line - (sx-1) - (line - ex)
|
||||
elseif(n==ey)then
|
||||
line = line - (line - ex)
|
||||
elseif(n==sy)then
|
||||
line = line-(sx-1)
|
||||
xOffset = sx-1
|
||||
end
|
||||
self.parent:setBG(obx + xOffset, oby + n - 1, rep(tHex[selectionBG], line))
|
||||
self.parent:setFG(obx + xOffset, oby + n - 1, rep(tHex[selectionFG], line))
|
||||
|
||||
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(self)
|
||||
for n = sy, ey do
|
||||
local line = #lines[n]
|
||||
local xOffset = 0
|
||||
if n == sy and n == ey then
|
||||
xOffset = sx - 1
|
||||
line = line - (sx - 1) - (line - ex)
|
||||
elseif n == ey then
|
||||
line = line - (line - ex)
|
||||
elseif n == sy then
|
||||
line = line - (sx - 1)
|
||||
xOffset = sx - 1
|
||||
end
|
||||
end]]
|
||||
if(self:isFocused())then
|
||||
local anchx, anchy = self:getAnchorPosition()
|
||||
--self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
self:addBG(1 + xOffset, n, rep(tHex[selectionBG], line))
|
||||
self:addFG(1 + xOffset, n, rep(tHex[selectionFG], line))
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
self.parent:addEvent("key", self)
|
||||
self.parent:addEvent("char", self)
|
||||
self.parent:addEvent("other_event", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("TextfieldBG")
|
||||
self.fgColor = self.parent:getTheme("TextfieldText")
|
||||
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
|
||||
end
|
||||
@@ -1,7 +1,6 @@
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Object")(name, basalt)
|
||||
|
||||
return function(name)
|
||||
local object
|
||||
local objectType = "Thread"
|
||||
|
||||
local func
|
||||
@@ -9,42 +8,9 @@ return function(name)
|
||||
local isActive = false
|
||||
local filter
|
||||
|
||||
local generateXMLEventFunction = function(self, str)
|
||||
if(str:sub(1,1)=="#")then
|
||||
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
|
||||
if(o~=nil)and(o.internalObjetCall~=nil)then
|
||||
return (function()o:internalObjetCall()end)
|
||||
end
|
||||
else
|
||||
return self:getBaseFrame():getVariable(str)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
object = {
|
||||
name = name,
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
getZIndex = function(self)
|
||||
return 1
|
||||
end;
|
||||
getName = function(self)
|
||||
return self.name
|
||||
end;
|
||||
|
||||
getBaseFrame = function(self)
|
||||
if(self.parent~=nil)then
|
||||
return self.parent:getBaseFrame()
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
local f
|
||||
if(xmlValue("thread", data)~=nil)then f = generateXMLEventFunction(self, xmlValue("thread", data)) end
|
||||
if(xmlValue("start", data)~=nil)then if(xmlValue("start", data))and(f~=nil)then self:start(f) end end
|
||||
return self
|
||||
end,
|
||||
|
||||
start = function(self, f)
|
||||
@@ -62,36 +28,36 @@ return function(name)
|
||||
error("Thread Error Occurred - " .. result)
|
||||
end
|
||||
end
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
self.parent:addEvent("key", self)
|
||||
self.parent:addEvent("key_up", self)
|
||||
self.parent:addEvent("char", self)
|
||||
self.parent:addEvent("other_event", self)
|
||||
self:listenEvent("mouse_click")
|
||||
self:listenEvent("mouse_up")
|
||||
self:listenEvent("mouse_scroll")
|
||||
self:listenEvent("mouse_drag")
|
||||
self:listenEvent("key")
|
||||
self:listenEvent("key_up")
|
||||
self:listenEvent("char")
|
||||
self:listenEvent("other_event")
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getStatus = function(self, f)
|
||||
if (cRoutine ~= nil) then
|
||||
return coroutine.status(cRoutine)
|
||||
end
|
||||
return nil
|
||||
end;
|
||||
end,
|
||||
|
||||
stop = function(self, f)
|
||||
isActive = false
|
||||
self.parent:removeEvent("mouse_click", self)
|
||||
self.parent:removeEvent("mouse_up", self)
|
||||
self.parent:removeEvent("mouse_scroll", self)
|
||||
self.parent:removeEvent("mouse_drag", self)
|
||||
self.parent:removeEvent("key", self)
|
||||
self.parent:removeEvent("key_up", self)
|
||||
self.parent:removeEvent("char", self)
|
||||
self.parent:removeEvent("other_event", self)
|
||||
self:listenEvent("mouse_click", false)
|
||||
self:listenEvent("mouse_up", false)
|
||||
self:listenEvent("mouse_scroll", false)
|
||||
self:listenEvent("mouse_drag", false)
|
||||
self:listenEvent("key", false)
|
||||
self:listenEvent("key_up", false)
|
||||
self:listenEvent("char", false)
|
||||
self:listenEvent("other_event", false)
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, ...)
|
||||
self:eventHandler("mouse_click", ...)
|
||||
@@ -119,6 +85,7 @@ return function(name)
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, ...)
|
||||
base.eventHandler(self, event, ...)
|
||||
if (isActive) then
|
||||
if (coroutine.status(cRoutine) == "suspended") then
|
||||
if(filter~=nil)then
|
||||
@@ -136,11 +103,10 @@ return function(name)
|
||||
self:stop()
|
||||
end
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
|
||||
return object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
@@ -1,71 +1,23 @@
|
||||
local basaltEvent = require("basaltEvent")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
|
||||
return function(name)
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Object")(name, basalt)
|
||||
local objectType = "Timer"
|
||||
|
||||
local timer = 0
|
||||
local savedRepeats = 0
|
||||
local repeats = 0
|
||||
local timerObj
|
||||
local eventSystem = basaltEvent()
|
||||
local timerIsActive = false
|
||||
|
||||
local generateXMLEventFunction = function(self, func, val)
|
||||
local createF = function(str)
|
||||
if(str:sub(1,1)=="#")then
|
||||
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
|
||||
if(o~=nil)and(o.internalObjetCall~=nil)then
|
||||
func(self,function()o:internalObjetCall()end)
|
||||
end
|
||||
else
|
||||
func(self,self:getBaseFrame():getVariable(str))
|
||||
end
|
||||
end
|
||||
if(type(val)=="string")then
|
||||
createF(val)
|
||||
elseif(type(val)=="table")then
|
||||
for k,v in pairs(val)do
|
||||
createF(v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
local object = {
|
||||
name = name,
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
if(xmlValue("time", data)~=nil)then timer = xmlValue("time", data) end
|
||||
if(xmlValue("repeat", data)~=nil)then savedRepeats = xmlValue("repeat", data) end
|
||||
if(xmlValue("start", data)~=nil)then if(xmlValue("start", data))then self:start() end end
|
||||
if(xmlValue("onCall", data)~=nil)then generateXMLEventFunction(self, self.onCall, xmlValue("onCall", data)) end
|
||||
return self
|
||||
end,
|
||||
|
||||
getBaseFrame = function(self)
|
||||
if(self.parent~=nil)then
|
||||
return self.parent:getBaseFrame()
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
getZIndex = function(self)
|
||||
return 1
|
||||
end;
|
||||
|
||||
getName = function(self)
|
||||
return self.name
|
||||
end;
|
||||
|
||||
setTime = function(self, _timer, _repeats)
|
||||
timer = _timer or 0
|
||||
savedRepeats = _repeats or 1
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
start = function(self)
|
||||
if(timerIsActive)then
|
||||
@@ -74,31 +26,32 @@ return function(name)
|
||||
repeats = savedRepeats
|
||||
timerObj = os.startTimer(timer)
|
||||
timerIsActive = true
|
||||
self.parent:addEvent("other_event", self)
|
||||
self:listenEvent("other_event")
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
isActive = function(self)
|
||||
return timerIsActive
|
||||
end;
|
||||
end,
|
||||
|
||||
cancel = function(self)
|
||||
if (timerObj ~= nil) then
|
||||
os.cancelTimer(timerObj)
|
||||
end
|
||||
timerIsActive = false
|
||||
self.parent:removeEvent("other_event", self)
|
||||
self:removeEvent("other_event")
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
onCall = function(self, func)
|
||||
eventSystem:registerEvent("timed_event", func)
|
||||
self:registerEvent("timed_event", func)
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, tObj)
|
||||
eventHandler = function(self, event, ...)
|
||||
base.eventHandler(self, event, ...)
|
||||
if event == "timer" and tObj == timerObj and timerIsActive then
|
||||
eventSystem:sendEvent("timed_event", self)
|
||||
self:sendEvent("timed_event")
|
||||
if (repeats >= 1) then
|
||||
repeats = repeats - 1
|
||||
if (repeats >= 1) then
|
||||
@@ -108,9 +61,9 @@ return function(name)
|
||||
timerObj = os.startTimer(timer)
|
||||
end
|
||||
end
|
||||
end;
|
||||
end,
|
||||
}
|
||||
object.__index = object
|
||||
|
||||
return object
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
320
Basalt/objects/Treeview.lua
Normal file
@@ -0,0 +1,320 @@
|
||||
local utils = require("utils")
|
||||
local tHex = require("tHex")
|
||||
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("ChangeableObject")(name, basalt)
|
||||
local objectType = "Treeview"
|
||||
|
||||
local nodes = {}
|
||||
local itemSelectedBG = colors.black
|
||||
local itemSelectedFG = colors.lightGray
|
||||
local selectionColorActive = true
|
||||
local textAlign = "left"
|
||||
local xOffset, yOffset = 0, 0
|
||||
local scrollable = true
|
||||
|
||||
base:setSize(16, 8)
|
||||
base:setZIndex(5)
|
||||
|
||||
local function newNode(text, expandable)
|
||||
text = text or ""
|
||||
expandable = expandable or false
|
||||
local expanded = false
|
||||
local parent = nil
|
||||
local children = {}
|
||||
|
||||
local node = {}
|
||||
|
||||
local onSelect
|
||||
|
||||
node = {
|
||||
getChildren = function()
|
||||
return children
|
||||
end,
|
||||
|
||||
setParent = function(p)
|
||||
if(parent~=nil)then
|
||||
parent.removeChild(parent.findChildrenByText(node.getText()))
|
||||
end
|
||||
parent = p
|
||||
base:updateDraw()
|
||||
return node
|
||||
end,
|
||||
|
||||
getParent = function()
|
||||
return parent
|
||||
end,
|
||||
|
||||
addChild = function(text, expandable)
|
||||
local childNode = newNode(text, expandable)
|
||||
childNode.setParent(node)
|
||||
table.insert(children, childNode)
|
||||
base:updateDraw()
|
||||
return childNode
|
||||
end,
|
||||
|
||||
setExpanded = function(exp)
|
||||
if(expandable)then
|
||||
expanded = exp
|
||||
end
|
||||
base:updateDraw()
|
||||
return node
|
||||
end,
|
||||
|
||||
isExpanded = function()
|
||||
return expanded
|
||||
end,
|
||||
|
||||
onSelect = function(...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
onSelect = v
|
||||
end
|
||||
end
|
||||
return node
|
||||
end,
|
||||
|
||||
callOnSelect = function()
|
||||
if(onSelect~=nil)then
|
||||
onSelect(node)
|
||||
end
|
||||
end,
|
||||
|
||||
setExpandable = function(expandable)
|
||||
expandable = expandable
|
||||
base:updateDraw()
|
||||
return node
|
||||
end,
|
||||
|
||||
isExpandable = function()
|
||||
return expandable
|
||||
end,
|
||||
|
||||
removeChild = function(index)
|
||||
if(type(index)=="table")then
|
||||
for k,v in pairs(index)do
|
||||
if(v==index)then
|
||||
index = k
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
table.remove(children, index)
|
||||
base:updateDraw()
|
||||
return node
|
||||
end,
|
||||
|
||||
findChildrenByText = function(searchText)
|
||||
local foundNodes = {}
|
||||
for _, child in ipairs(children) do
|
||||
if string.find(child.getText(), searchText) then
|
||||
table.insert(foundNodes, child)
|
||||
end
|
||||
end
|
||||
return foundNodes
|
||||
end,
|
||||
|
||||
getText = function()
|
||||
return text
|
||||
end,
|
||||
|
||||
setText = function(t)
|
||||
text = t
|
||||
base:updateDraw()
|
||||
return node
|
||||
end
|
||||
}
|
||||
|
||||
return node
|
||||
end
|
||||
|
||||
local root = newNode("Root", true)
|
||||
root.setExpanded(true)
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
local parent = self:getParent()
|
||||
self:listenEvent("mouse_click")
|
||||
self:listenEvent("mouse_scroll")
|
||||
return base.init(self)
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType == t or base.isType ~= nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
setOffset = function(self, x, y)
|
||||
xOffset = x
|
||||
yOffset = y
|
||||
return self
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return xOffset, yOffset
|
||||
end,
|
||||
|
||||
setScrollable = function(self, scroll)
|
||||
scrollable = scroll
|
||||
return self
|
||||
end,
|
||||
|
||||
setSelectionColor = function(self, bgCol, fgCol, active)
|
||||
itemSelectedBG = bgCol or self:getBackground()
|
||||
itemSelectedFG = fgCol or self:getForeground()
|
||||
selectionColorActive = active~=nil and active or true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getSelectionColor = function(self)
|
||||
return itemSelectedBG, itemSelectedFG
|
||||
end,
|
||||
|
||||
isSelectionColorActive = function(self)
|
||||
return selectionColorActive
|
||||
end,
|
||||
|
||||
getRoot = function(self)
|
||||
return root
|
||||
end,
|
||||
|
||||
setRoot = function(self, node)
|
||||
root = node
|
||||
node.setParent(nil)
|
||||
return self
|
||||
end,
|
||||
|
||||
onSelect = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("treeview_select", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
selectionHandler = function(self, node)
|
||||
node.callOnSelect(node)
|
||||
self:sendEvent("treeview_select", node)
|
||||
return self
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if base.mouseHandler(self, button, x, y) then
|
||||
local currentLine = 1 - yOffset
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local w, h = self:getSize()
|
||||
local function checkNodeClick(node, level)
|
||||
if y == oby+currentLine-1 then
|
||||
if x >= obx and x < obx + w then
|
||||
node.setExpanded(not node.isExpanded())
|
||||
self:selectionHandler(node)
|
||||
self:setValue(node)
|
||||
self:updateDraw()
|
||||
return true
|
||||
end
|
||||
end
|
||||
currentLine = currentLine + 1
|
||||
if node.isExpanded() then
|
||||
for _, child in ipairs(node.getChildren()) do
|
||||
if checkNodeClick(child, level + 1) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
for _, item in ipairs(root.getChildren()) do
|
||||
if checkNodeClick(item, 1) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if base.scrollHandler(self, dir, x, y) then
|
||||
if scrollable then
|
||||
local _, h = self:getSize()
|
||||
yOffset = yOffset + dir
|
||||
|
||||
if yOffset < 0 then
|
||||
yOffset = 0
|
||||
end
|
||||
|
||||
if dir >= 1 then
|
||||
local visibleLines = 0
|
||||
local function countVisibleLines(node, level)
|
||||
visibleLines = visibleLines + 1
|
||||
if node.isExpanded() then
|
||||
for _, child in ipairs(node.getChildren()) do
|
||||
countVisibleLines(child, level + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, item in ipairs(root.getChildren()) do
|
||||
countVisibleLines(item, 1)
|
||||
end
|
||||
|
||||
if visibleLines > h then
|
||||
if yOffset > visibleLines - h then
|
||||
yOffset = visibleLines - h
|
||||
end
|
||||
else
|
||||
yOffset = yOffset - 1
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("treeview", function()
|
||||
local currentLine = 1 - yOffset
|
||||
local lastClickedNode = self:getValue()
|
||||
local function drawNode(node, level)
|
||||
local w, h = self:getSize()
|
||||
|
||||
if currentLine >= 1 and currentLine <= h then
|
||||
local bg = (node == lastClickedNode) and itemSelectedBG or self:getBackground()
|
||||
local fg = (node == lastClickedNode) and itemSelectedFG or self:getForeground()
|
||||
|
||||
local text = node.getText()
|
||||
self:addBlit(1 + level + xOffset, currentLine, text, tHex[fg]:rep(#text), tHex[bg]:rep(#text))
|
||||
end
|
||||
|
||||
currentLine = currentLine + 1
|
||||
|
||||
if node.isExpanded() then
|
||||
for _, child in ipairs(node.getChildren()) do
|
||||
drawNode(child, level + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, item in ipairs(root.getChildren()) do
|
||||
drawNode(item, 1)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
|
||||
|
||||
}
|
||||
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
630
Basalt/objects/VisualObject.lua
Normal file
@@ -0,0 +1,630 @@
|
||||
local utils = require("utils")
|
||||
local tHex = require("tHex")
|
||||
|
||||
local sub, find, insert = string.sub, string.find, table.insert
|
||||
|
||||
return function(name, basalt)
|
||||
local base = basalt.getObject("Object")(name, basalt)
|
||||
-- Base object
|
||||
local objectType = "VisualObject" -- not changeable
|
||||
|
||||
local isVisible,ignOffset,isHovered,isClicked,isDragging = true,false,false,false,false
|
||||
local zIndex = 1
|
||||
|
||||
local x, y, width, height = 1,1,1,1
|
||||
local dragStartX, dragStartY, dragXOffset, dragYOffset = 0, 0, 0, 0
|
||||
|
||||
local bgColor,fgColor, transparency = colors.black, colors.white, false
|
||||
local parent
|
||||
|
||||
local preDrawQueue = {}
|
||||
local drawQueue = {}
|
||||
local postDrawQueue = {}
|
||||
|
||||
local renderObject = {}
|
||||
|
||||
local function split(str, d)
|
||||
local result = {}
|
||||
if str == "" then
|
||||
return result
|
||||
end
|
||||
d = d or " "
|
||||
local start = 1
|
||||
local delim_start, delim_end = find(str, d, start)
|
||||
while delim_start do
|
||||
insert(result, {x=start, value=sub(str, start, delim_start - 1)})
|
||||
start = delim_end + 1
|
||||
delim_start, delim_end = find(str, d, start)
|
||||
end
|
||||
insert(result, {x=start, value=sub(str, start)})
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
local object = {
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end,
|
||||
|
||||
getBase = function(self)
|
||||
return base
|
||||
end,
|
||||
|
||||
isType = function(self, t)
|
||||
return objectType==t or base.isType~=nil and base.isType(t) or false
|
||||
end,
|
||||
|
||||
getBasalt = function(self)
|
||||
return basalt
|
||||
end,
|
||||
|
||||
show = function(self)
|
||||
isVisible = true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
hide = function(self)
|
||||
isVisible = false
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
isVisible = function(self)
|
||||
return isVisible
|
||||
end,
|
||||
|
||||
setVisible = function(self, _isVisible)
|
||||
isVisible = _isVisible or not isVisible
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setTransparency = function(self, _transparency)
|
||||
transparency = _transparency~= nil and _transparency or true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setParent = function(self, newParent, noRemove)
|
||||
base.setParent(self, newParent, noRemove)
|
||||
parent = newParent
|
||||
return self
|
||||
end,
|
||||
|
||||
setFocus = function(self)
|
||||
if (parent ~= nil) then
|
||||
parent:setFocusedObject(self)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setZIndex = function(self, index)
|
||||
zIndex = index
|
||||
if (parent ~= nil) then
|
||||
parent:updateZIndex(self, zIndex)
|
||||
self:updateDraw()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
getZIndex = function(self)
|
||||
return zIndex
|
||||
end,
|
||||
|
||||
updateDraw = function(self)
|
||||
if (parent ~= nil) then
|
||||
parent:updateDraw()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setPosition = function(self, xPos, yPos, rel)
|
||||
local curX, curY = x, y
|
||||
if(type(xPos)=="number")then
|
||||
x = rel and x+xPos or xPos
|
||||
end
|
||||
if(type(yPos)=="number")then
|
||||
y = rel and y+yPos or yPos
|
||||
end
|
||||
if(parent~=nil)then parent:customEventHandler("basalt_FrameReposition", self) end
|
||||
if(self:getType()=="Container")then parent:customEventHandler("basalt_FrameReposition", self) end
|
||||
self:updateDraw()
|
||||
self:repositionHandler(curX, curY)
|
||||
return self
|
||||
end,
|
||||
|
||||
getX = function(self)
|
||||
return x
|
||||
end,
|
||||
|
||||
getY = function(self)
|
||||
return y
|
||||
end,
|
||||
|
||||
getPosition = function(self)
|
||||
return x, y
|
||||
end,
|
||||
|
||||
setSize = function(self, newWidth, newHeight, rel)
|
||||
local oldW, oldH = width, height
|
||||
if(type(newWidth)=="number")then
|
||||
width = rel and width+newWidth or newWidth
|
||||
end
|
||||
if(type(newHeight)=="number")then
|
||||
height = rel and height+newHeight or newHeight
|
||||
end
|
||||
if(parent~=nil)then
|
||||
parent:customEventHandler("basalt_FrameResize", self)
|
||||
if(self:getType()=="Container")then parent:customEventHandler("basalt_FrameResize", self) end
|
||||
end
|
||||
self:resizeHandler(oldW, oldH)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getHeight = function(self)
|
||||
return height
|
||||
end,
|
||||
|
||||
getWidth = function(self)
|
||||
return width
|
||||
end,
|
||||
|
||||
getSize = function(self)
|
||||
return width, height
|
||||
end,
|
||||
|
||||
setBackground = function(self, color)
|
||||
bgColor = color
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getBackground = function(self)
|
||||
return bgColor
|
||||
end,
|
||||
|
||||
setForeground = function(self, color)
|
||||
fgColor = color or false
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getForeground = function(self)
|
||||
return fgColor
|
||||
end,
|
||||
|
||||
getAbsolutePosition = function(self, x, y)
|
||||
-- relative position to absolute position
|
||||
if (x == nil) or (y == nil) then
|
||||
x, y = self:getPosition()
|
||||
end
|
||||
|
||||
if (parent ~= nil) then
|
||||
local fx, fy = parent:getAbsolutePosition()
|
||||
x = fx + x - 1
|
||||
y = fy + y - 1
|
||||
end
|
||||
return x, y
|
||||
end,
|
||||
|
||||
ignoreOffset = function(self, ignore)
|
||||
ignOffset = ignore
|
||||
if(ignore==nil)then ignOffset = true end
|
||||
return self
|
||||
end,
|
||||
|
||||
getIgnoreOffset = function(self)
|
||||
return ignOffset
|
||||
end,
|
||||
|
||||
isCoordsInObject = function(self, x, y)
|
||||
if(isVisible)and(self:isEnabled())then
|
||||
if(x==nil)or(y==nil)then return false end
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local w, h = self:getSize()
|
||||
if (objX <= x) and (objX + w > x) and (objY <= y) and (objY + h > y) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
onGetFocus = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("get_focus", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onLoseFocus = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("lose_focus", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
isFocused = function(self)
|
||||
if (parent ~= nil) then
|
||||
return parent:getFocusedObject() == self
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
resizeHandler = function(self, ...)
|
||||
if(self:isEnabled())then
|
||||
local val = self:sendEvent("basalt_resize", ...)
|
||||
if(val==false)then return false end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
repositionHandler = function(self, ...)
|
||||
if(self:isEnabled())then
|
||||
local val = self:sendEvent("basalt_reposition", ...)
|
||||
if(val==false)then return false end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
onResize = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("basalt_resize", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onReposition = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("basalt_reposition", v)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y, isMon)
|
||||
if(self:isCoordsInObject(x, y))then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = self:sendEvent("mouse_click", button, x - (objX-1), y - (objY-1), x, y, isMon)
|
||||
if(val==false)then return false end
|
||||
if(parent~=nil)then
|
||||
parent:setFocusedObject(self)
|
||||
end
|
||||
isClicked = true
|
||||
isDragging = true
|
||||
dragStartX, dragStartY = x, y
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
mouseUpHandler = function(self, button, x, y)
|
||||
isDragging = false
|
||||
if(isClicked)then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = self:sendEvent("mouse_release", button, x - (objX-1), y - (objY-1), x, y)
|
||||
isClicked = false
|
||||
end
|
||||
if(self:isCoordsInObject(x, y))then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = self:sendEvent("mouse_up", button, x - (objX-1), y - (objY-1), x, y)
|
||||
if(val==false)then return false end
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
dragHandler = function(self, button, x, y)
|
||||
if(isDragging)then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = self:sendEvent("mouse_drag", button, x - (objX-1), y - (objY-1), dragStartX-x, dragStartY-y, x, y)
|
||||
dragStartX, dragStartY = x, y
|
||||
if(val~=nil)then return val end
|
||||
if(parent~=nil)then
|
||||
parent:setFocusedObject(self)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if(self:isCoordsInObject(x, y))then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
dragStartX, dragStartY = x, y
|
||||
dragXOffset, dragYOffset = objX - x, objY - y
|
||||
end
|
||||
end,
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if(self:isCoordsInObject(x, y))then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = self:sendEvent("mouse_scroll", dir, x - (objX-1), y - (objY-1))
|
||||
if(val==false)then return false end
|
||||
if(parent~=nil)then
|
||||
parent:setFocusedObject(self)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
hoverHandler = function(self, x, y, stopped)
|
||||
if(self:isCoordsInObject(x, y))then
|
||||
local val = self:sendEvent("mouse_hover", x, y, stopped)
|
||||
if(val==false)then return false end
|
||||
isHovered = true
|
||||
return true
|
||||
end
|
||||
if(isHovered)then
|
||||
local val = self:sendEvent("mouse_leave", x, y, stopped)
|
||||
if(val==false)then return false end
|
||||
isHovered = false
|
||||
end
|
||||
end,
|
||||
|
||||
keyHandler = function(self, key, isHolding)
|
||||
if(self:isEnabled())and(isVisible)then
|
||||
if (self:isFocused()) then
|
||||
local val = self:sendEvent("key", key, isHolding)
|
||||
if(val==false)then return false end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
keyUpHandler = function(self, key)
|
||||
if(self:isEnabled())and(isVisible)then
|
||||
if (self:isFocused()) then
|
||||
local val = self:sendEvent("key_up", key)
|
||||
if(val==false)then return false end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
charHandler = function(self, char)
|
||||
if(self:isEnabled())and(isVisible)then
|
||||
if(self:isFocused())then
|
||||
local val = self:sendEvent("char", char)
|
||||
if(val==false)then return false end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
getFocusHandler = function(self)
|
||||
local val = self:sendEvent("get_focus")
|
||||
if(val~=nil)then return val end
|
||||
return true
|
||||
end,
|
||||
|
||||
loseFocusHandler = function(self)
|
||||
isDragging = false
|
||||
local val = self:sendEvent("lose_focus")
|
||||
if(val~=nil)then return val end
|
||||
return true
|
||||
end,
|
||||
|
||||
addDraw = function(self, name, f, pos, typ, active)
|
||||
local queue = (typ==nil or typ==1) and drawQueue or typ==2 and preDrawQueue or typ==3 and postDrawQueue
|
||||
pos = pos or #queue+1
|
||||
if(name~=nil)then
|
||||
for k,v in pairs(queue)do
|
||||
if(v.name==name)then
|
||||
table.remove(queue, k)
|
||||
break
|
||||
end
|
||||
end
|
||||
local t = {name=name, f=f, pos=pos, active=active~=nil and active or true}
|
||||
table.insert(queue, pos, t)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
addPreDraw = function(self, name, f, pos, typ)
|
||||
self:addDraw(name, f, pos, 2)
|
||||
return self
|
||||
end,
|
||||
|
||||
addPostDraw = function(self, name, f, pos, typ)
|
||||
self:addDraw(name, f, pos, 3)
|
||||
return self
|
||||
end,
|
||||
|
||||
setDrawState = function(self, name, state, typ)
|
||||
local queue = (typ==nil or typ==1) and drawQueue or typ==2 and preDrawQueue or typ==3 and postDrawQueue
|
||||
for k,v in pairs(queue)do
|
||||
if(v.name==name)then
|
||||
v.active = state
|
||||
break
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getDrawId = function(self, name, typ)
|
||||
local queue = typ==1 and drawQueue or typ==2 and preDrawQueue or typ==3 and postDrawQueue or drawQueue
|
||||
for k,v in pairs(queue)do
|
||||
if(v.name==name)then
|
||||
return k
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
addText = function(self, x, y, text)
|
||||
local obj = self:getParent() or self
|
||||
local xPos,yPos = self:getPosition()
|
||||
if(parent~=nil)then
|
||||
local xO, yO = parent:getOffset()
|
||||
xPos = ignOffset and xPos or xPos - xO
|
||||
yPos = ignOffset and yPos or yPos - yO
|
||||
end
|
||||
if not(transparency)then
|
||||
obj:setText(x+xPos-1, y+yPos-1, text)
|
||||
return
|
||||
end
|
||||
local t = split(text, "\0")
|
||||
for k,v in pairs(t)do
|
||||
if(v.value~="")and(v.value~="\0")then
|
||||
obj:setText(x+v.x+xPos-2, y+yPos-1, v.value)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
addBG = function(self, x, y, bg, noText)
|
||||
local obj = parent or self
|
||||
local xPos,yPos = self:getPosition()
|
||||
if(parent~=nil)then
|
||||
local xO, yO = parent:getOffset()
|
||||
xPos = ignOffset and xPos or xPos - xO
|
||||
yPos = ignOffset and yPos or yPos - yO
|
||||
end
|
||||
if not(transparency)then
|
||||
obj:setBG(x+xPos-1, y+yPos-1, bg)
|
||||
return
|
||||
end
|
||||
local t = split(bg)
|
||||
for k,v in pairs(t)do
|
||||
if(v.value~="")and(v.value~=" ")then
|
||||
if(noText~=true)then
|
||||
obj:setText(x+v.x+xPos-2, y+yPos-1, (" "):rep(#v.value))
|
||||
obj:setBG(x+v.x+xPos-2, y+yPos-1, v.value)
|
||||
else
|
||||
table.insert(renderObject, {x=x+v.x-1,y=y,bg=v.value})
|
||||
obj:setBG(x+xPos-1, y+yPos-1, fg)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
addFG = function(self, x, y, fg)
|
||||
local obj = parent or self
|
||||
local xPos,yPos = self:getPosition()
|
||||
if(parent~=nil)then
|
||||
local xO, yO = parent:getOffset()
|
||||
xPos = ignOffset and xPos or xPos - xO
|
||||
yPos = ignOffset and yPos or yPos - yO
|
||||
end
|
||||
if not(transparency)then
|
||||
obj:setFG(x+xPos-1, y+yPos-1, fg)
|
||||
return
|
||||
end
|
||||
local t = split(fg)
|
||||
for k,v in pairs(t)do
|
||||
if(v.value~="")and(v.value~=" ")then
|
||||
obj:setFG(x+v.x+xPos-2, y+yPos-1, v.value)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
addBlit = function(self, x, y, t, fg, bg)
|
||||
local obj = parent or self
|
||||
local xPos,yPos = self:getPosition()
|
||||
if(parent~=nil)then
|
||||
local xO, yO = parent:getOffset()
|
||||
xPos = ignOffset and xPos or xPos - xO
|
||||
yPos = ignOffset and yPos or yPos - yO
|
||||
end
|
||||
if not(transparency)then
|
||||
obj:blit(x+xPos-1, y+yPos-1, t, fg, bg)
|
||||
return
|
||||
end
|
||||
local _text = split(t, "\0")
|
||||
local _fg = split(fg)
|
||||
local _bg = split(bg)
|
||||
for k,v in pairs(_text)do
|
||||
if(v.value~="")or(v.value~="\0")then
|
||||
obj:setText(x+v.x+xPos-2, y+yPos-1, v.value)
|
||||
end
|
||||
end
|
||||
for k,v in pairs(_bg)do
|
||||
if(v.value~="")or(v.value~=" ")then
|
||||
obj:setBG(x+v.x+xPos-2, y+yPos-1, v.value)
|
||||
end
|
||||
end
|
||||
for k,v in pairs(_fg)do
|
||||
if(v.value~="")or(v.value~=" ")then
|
||||
obj:setFG(x+v.x+xPos-2, y+yPos-1, v.value)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
addTextBox = function(self, x, y, w, h, text)
|
||||
local obj = parent or self
|
||||
local xPos,yPos = self:getPosition()
|
||||
if(parent~=nil)then
|
||||
local xO, yO = parent:getOffset()
|
||||
xPos = ignOffset and xPos or xPos - xO
|
||||
yPos = ignOffset and yPos or yPos - yO
|
||||
end
|
||||
obj:drawTextBox(x+xPos-1, y+yPos-1, w, h, text)
|
||||
end,
|
||||
|
||||
addForegroundBox = function(self, x, y, w, h, col)
|
||||
local obj = parent or self
|
||||
local xPos,yPos = self:getPosition()
|
||||
if(parent~=nil)then
|
||||
local xO, yO = parent:getOffset()
|
||||
xPos = ignOffset and xPos or xPos - xO
|
||||
yPos = ignOffset and yPos or yPos - yO
|
||||
end
|
||||
obj:drawForegroundBox(x+xPos-1, y+yPos-1, w, h, col)
|
||||
end,
|
||||
|
||||
addBackgroundBox = function(self, x, y, w, h, col)
|
||||
local obj = parent or self
|
||||
local xPos,yPos = self:getPosition()
|
||||
if(parent~=nil)then
|
||||
local xO, yO = parent:getOffset()
|
||||
xPos = ignOffset and xPos or xPos - xO
|
||||
yPos = ignOffset and yPos or yPos - yO
|
||||
end
|
||||
obj:drawBackgroundBox(x+xPos-1, y+yPos-1, w, h, col)
|
||||
end,
|
||||
|
||||
render = function(self)
|
||||
if (isVisible)then
|
||||
self:redraw()
|
||||
end
|
||||
end,
|
||||
|
||||
redraw = function(self)
|
||||
for k,v in pairs(preDrawQueue)do
|
||||
if (v.active)then
|
||||
v.f(self)
|
||||
end
|
||||
end
|
||||
for k,v in pairs(drawQueue)do
|
||||
if (v.active)then
|
||||
v.f(self)
|
||||
end
|
||||
end
|
||||
for k,v in pairs(postDrawQueue)do
|
||||
if (v.active)then
|
||||
v.f(self)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
self:addDraw("base", function()
|
||||
local w,h = self:getSize()
|
||||
if(bgColor~=false)then
|
||||
self:addTextBox(1, 1, w, h, " ")
|
||||
self:addBackgroundBox(1, 1, w, h, bgColor)
|
||||
end
|
||||
if(fgColor~=false)then
|
||||
self:addForegroundBox(1, 1, w, h, fgColor)
|
||||
end
|
||||
end, 1)
|
||||
end,
|
||||
}
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
56
Basalt/plugin.lua
Normal file
@@ -0,0 +1,56 @@
|
||||
local args = {...}
|
||||
local plugins = {}
|
||||
|
||||
local dir = fs.getDir(args[2] or "Basalt")
|
||||
local pluginDir = fs.combine(dir, "plugins")
|
||||
if(packaged)then
|
||||
for k,v in pairs(getProject("plugins"))do
|
||||
local newPlugin = v()
|
||||
if(type(newPlugin)=="table")then
|
||||
for a,b in pairs(newPlugin)do
|
||||
if(type(a)=="string")then
|
||||
if(plugins[a]==nil)then plugins[a] = {} end
|
||||
table.insert(plugins[a], b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if(fs.exists(pluginDir))then
|
||||
for _,v in pairs(fs.list(pluginDir))do
|
||||
local newPlugin = require(v:gsub(".lua", ""))
|
||||
if(type(newPlugin)=="table")then
|
||||
for a,b in pairs(newPlugin)do
|
||||
if(type(a)=="string")then
|
||||
if(plugins[a]==nil)then plugins[a] = {} end
|
||||
table.insert(plugins[a], b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get(name)
|
||||
return plugins[name]
|
||||
end
|
||||
|
||||
return {
|
||||
get = get,
|
||||
addPlugins = function(objects, basalt)
|
||||
for k,v in pairs(objects)do
|
||||
local plugList = plugins[k]
|
||||
if(plugList~=nil)then
|
||||
objects[k] = function(...)
|
||||
local moddedObject = v(...)
|
||||
for a,b in pairs(plugList)do
|
||||
local ext = b(moddedObject, basalt, ...)
|
||||
ext.__index = ext
|
||||
moddedObject = setmetatable(ext, moddedObject)
|
||||
end
|
||||
return moddedObject
|
||||
end
|
||||
end
|
||||
end
|
||||
return objects
|
||||
end
|
||||
}
|
||||
54
Basalt/plugins/advancedBackground.lua
Normal file
@@ -0,0 +1,54 @@
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.xmlValue
|
||||
|
||||
return {
|
||||
VisualObject = function(base)
|
||||
local bgSymbol = false
|
||||
local bgSymbolColor = colors.black
|
||||
|
||||
local object = {
|
||||
setBackground = function(self, bg, symbol, symbolCol)
|
||||
base.setBackground(self, bg)
|
||||
bgSymbol = symbol or bgSymbol
|
||||
bgSymbolColor = symbolCol or bgSymbolColor
|
||||
return self
|
||||
end,
|
||||
|
||||
setBackgroundSymbol = function(self, symbol, symbolCol)
|
||||
bgSymbol = symbol
|
||||
bgSymbolColor = symbolCol or bgSymbolColor
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getBackgroundSymbol = function(self)
|
||||
return bgSymbol
|
||||
end,
|
||||
|
||||
getBackgroundSymbolColor = function(self)
|
||||
return bgSymbolColor
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data, scripts)
|
||||
base.setValuesByXMLData(self, data, scripts)
|
||||
if(xmlValue("background-symbol", data)~=nil)then self:setBackgroundSymbol(xmlValue("background-symbol", data), xmlValue("background-symbol-color", data)) end
|
||||
return self
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("advanced-bg", function()
|
||||
local w, h = self:getSize()
|
||||
if(bgSymbol~=false)then
|
||||
self:addTextBox(1, 1, w, h, bgSymbol:sub(1,1))
|
||||
if(bgSymbol~=" ")then
|
||||
self:addForegroundBox(1, 1, w, h, bgSymbolColor)
|
||||
end
|
||||
end
|
||||
end, 2)
|
||||
end,
|
||||
}
|
||||
|
||||
return object
|
||||
end
|
||||
}
|
||||
362
Basalt/plugins/animations.lua
Normal file
@@ -0,0 +1,362 @@
|
||||
local floor,sin,cos,pi,sqrt,pow = math.floor,math.sin,math.cos,math.pi,math.sqrt,math.pow
|
||||
|
||||
-- You can find the easing curves here https://easings.net
|
||||
|
||||
local function lerp(s, e, pct)
|
||||
return s + (e - s) * pct
|
||||
end
|
||||
|
||||
local function linear(t)
|
||||
return t
|
||||
end
|
||||
|
||||
local function flip(t)
|
||||
return 1 - t
|
||||
end
|
||||
|
||||
local function easeIn(t)
|
||||
return t * t * t
|
||||
end
|
||||
|
||||
local function easeOut(t)
|
||||
return flip(easeIn(flip(t)))
|
||||
end
|
||||
|
||||
local function easeInOut(t)
|
||||
return lerp(easeIn(t), easeOut(t), t)
|
||||
end
|
||||
|
||||
local function easeOutSine(t)
|
||||
return sin((t * pi) / 2);
|
||||
end
|
||||
|
||||
local function easeInSine(t)
|
||||
return flip(cos((t * pi) / 2))
|
||||
end
|
||||
|
||||
local function easeInOutSine(t)
|
||||
return -(cos(pi * x) - 1) / 2
|
||||
end
|
||||
|
||||
local function easeInBack(t)
|
||||
local c1 = 1.70158;
|
||||
local c3 = c1 + 1
|
||||
return c3*t^3-c1*t^2
|
||||
end
|
||||
|
||||
local function easeInCubic(t)
|
||||
return t^3
|
||||
end
|
||||
|
||||
local function easeInElastic(t)
|
||||
local c4 = (2*pi)/3;
|
||||
return t == 0 and 0 or (t == 1 and 1 or (
|
||||
-2^(10*t-10)*sin((t*10-10.75)*c4)
|
||||
))
|
||||
end
|
||||
|
||||
local function easeInExpo(t)
|
||||
return t == 0 and 0 or 2^(10*t-10)
|
||||
end
|
||||
|
||||
local function easeInExpo(t)
|
||||
return t == 0 and 0 or 2^(10*t-10)
|
||||
end
|
||||
|
||||
local function easeInOutBack(t)
|
||||
local c1 = 1.70158;
|
||||
local c2 = c1 * 1.525;
|
||||
return t < 0.5 and ((2*t)^2*((c2+1)*2*t-c2))/2 or ((2*t-2)^2*((c2+1)*(t*2-2)+c2)+2)/2
|
||||
end
|
||||
|
||||
local function easeInOutCubic(t)
|
||||
return t < 0.5 and 4 * t^3 or 1-(-2*t+2)^3 / 2
|
||||
end
|
||||
|
||||
local function easeInOutElastic(t)
|
||||
local c5 = (2*pi) / 4.5
|
||||
return t==0 and 0 or (t == 1 and 1 or (t < 0.5 and -(2^(20*t-10) * sin((20*t - 11.125) * c5))/2 or (2^(-20*t+10) * sin((20*t - 11.125) * c5))/2 + 1))
|
||||
end
|
||||
|
||||
local function easeInOutExpo(t)
|
||||
return t == 0 and 0 or (t == 1 and 1 or (t < 0.5 and 2^(20*t-10)/2 or (2-2^(-20*t+10)) /2))
|
||||
end
|
||||
|
||||
local function easeInOutQuad(t)
|
||||
return t < 0.5 and 2*t^2 or 1-(-2*t+2)^2/2
|
||||
end
|
||||
|
||||
local function easeInOutQuart(t)
|
||||
return t < 0.5 and 8*t^4 or 1 - (-2*t+2)^4 / 2
|
||||
end
|
||||
|
||||
local function easeInOutQuint(t)
|
||||
return t < 0.5 and 16*t^5 or 1-(-2*t+2)^5 / 2
|
||||
end
|
||||
|
||||
local function easeInQuad(t)
|
||||
return t^2
|
||||
end
|
||||
|
||||
local function easeInQuart(t)
|
||||
return t^4
|
||||
end
|
||||
|
||||
local function easeInQuint(t)
|
||||
return t^5
|
||||
end
|
||||
|
||||
local function easeOutBack(t)
|
||||
local c1 = 1.70158;
|
||||
local c3 = c1 + 1
|
||||
return 1+c3*(t-1)^3+c1*(t-1)^2
|
||||
end
|
||||
|
||||
local function easeOutCubic(t)
|
||||
return 1 - (1-t)^3
|
||||
end
|
||||
|
||||
local function easeOutElastic(t)
|
||||
local c4 = (2*pi)/3;
|
||||
|
||||
return t == 0 and 0 or (t == 1 and 1 or (2^(-10*t)*sin((t*10-0.75)*c4)+1))
|
||||
end
|
||||
|
||||
local function easeOutExpo(t)
|
||||
return t == 1 and 1 or 1-2^(-10*t)
|
||||
end
|
||||
|
||||
local function easeOutQuad(t)
|
||||
return 1 - (1 - t) * (1 - t)
|
||||
end
|
||||
|
||||
local function easeOutQuart(t)
|
||||
return 1 - (1-t)^4
|
||||
end
|
||||
|
||||
local function easeOutQuint(t)
|
||||
return 1 - (1 - t)^5
|
||||
end
|
||||
|
||||
local function easeInCirc(t)
|
||||
return 1 - sqrt(1 - pow(t, 2))
|
||||
end
|
||||
|
||||
local function easeOutCirc(t)
|
||||
return sqrt(1 - pow(t - 1, 2))
|
||||
end
|
||||
|
||||
local function easeInOutCirc(t)
|
||||
return t < 0.5 and (1 - sqrt(1 - pow(2 * t, 2))) / 2 or (sqrt(1 - pow(-2 * t + 2, 2)) + 1) / 2;
|
||||
end
|
||||
|
||||
local function easeOutBounce(t)
|
||||
local n1 = 7.5625;
|
||||
local d1 = 2.75;
|
||||
|
||||
if (t < 1 / d1)then
|
||||
return n1 * t * t
|
||||
elseif (t < 2 / d1)then
|
||||
local a = t - 1.5 / d1
|
||||
return n1 * a * a + 0.75;
|
||||
elseif (t < 2.5 / d1)then
|
||||
local a = t - 2.25 / d1
|
||||
return n1 * a * a + 0.9375;
|
||||
else
|
||||
local a = t - 2.625 / d1
|
||||
return n1 * a * a + 0.984375;
|
||||
end
|
||||
end
|
||||
|
||||
local function easeInBounce(t)
|
||||
return 1 - easeOutBounce(1 - t)
|
||||
end
|
||||
|
||||
local function easeInOutBounce(t)
|
||||
return x < 0.5 and (1 - easeOutBounce(1 - 2 * t)) / 2 or (1 + easeOutBounce(2 * t - 1)) / 2;
|
||||
end
|
||||
|
||||
local lerp = {
|
||||
linear = linear,
|
||||
lerp = lerp,
|
||||
flip=flip,
|
||||
easeIn=easeIn,
|
||||
easeInSine = easeInSine,
|
||||
easeInBack=easeInBack,
|
||||
easeInCubic=easeInCubic,
|
||||
easeInElastic=easeInElastic,
|
||||
easeInExpo=easeInExpo,
|
||||
easeInQuad=easeInQuad,
|
||||
easeInQuart=easeInQuart,
|
||||
easeInQuint=easeInQuint,
|
||||
easeInCirc=easeInCirc,
|
||||
easeInBounce=easeInBounce,
|
||||
easeOut=easeOut,
|
||||
easeOutSine = easeOutSine,
|
||||
easeOutBack=easeOutBack,
|
||||
easeOutCubic=easeOutCubic,
|
||||
easeOutElastic=easeOutElastic,
|
||||
easeOutExpo=easeOutExpo,
|
||||
easeOutQuad=easeOutQuad,
|
||||
easeOutQuart=easeOutQuart,
|
||||
easeOutQuint=easeOutQuint,
|
||||
easeOutCirc=easeOutCirc,
|
||||
easeOutBounce=easeOutBounce,
|
||||
easeInOut=easeInOut,
|
||||
easeInOutSine = easeInOutSine,
|
||||
easeInOutBack=easeInOutBack,
|
||||
easeInOutCubic=easeInOutCubic,
|
||||
easeInOutElastic=easeInOutElastic,
|
||||
easeInOutExpo=easeInOutExpo,
|
||||
easeInOutQuad=easeInOutQuad,
|
||||
easeInOutQuart=easeInOutQuart,
|
||||
easeInOutQuint=easeInOutQuint,
|
||||
easeInOutCirc=easeInOutCirc,
|
||||
easeInOutBounce=easeInOutBounce,
|
||||
}
|
||||
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.xmlValue
|
||||
|
||||
return {
|
||||
VisualObject = function(base, basalt)
|
||||
local activeAnimations = {}
|
||||
local defaultMode = "linear"
|
||||
|
||||
local function getAnimation(self, timerId)
|
||||
for k,v in pairs(activeAnimations)do
|
||||
if(v.timerId==timerId)then
|
||||
return v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function createAnimation(self, v1, v2, duration, timeOffset, mode, typ, f, get, set)
|
||||
local v1Val, v2Val = get(self)
|
||||
if(activeAnimations[typ]~=nil)then
|
||||
os.cancelTimer(activeAnimations[typ].timerId)
|
||||
end
|
||||
activeAnimations[typ] = {}
|
||||
activeAnimations[typ].call = function()
|
||||
local progress = activeAnimations[typ].progress
|
||||
local _v1 = math.floor(lerp.lerp(v1Val, v1, lerp[mode](progress / duration))+0.5)
|
||||
local _v2 = math.floor(lerp.lerp(v2Val, v2, lerp[mode](progress / duration))+0.5)
|
||||
set(self, _v1, _v2)
|
||||
end
|
||||
activeAnimations[typ].finished = function()
|
||||
set(self, v1, v2)
|
||||
if(f~=nil)then f(self) end
|
||||
end
|
||||
|
||||
activeAnimations[typ].timerId=os.startTimer(0.05+timeOffset)
|
||||
activeAnimations[typ].progress=0
|
||||
activeAnimations[typ].duration=duration
|
||||
activeAnimations[typ].mode=mode
|
||||
self:listenEvent("other_event")
|
||||
end
|
||||
|
||||
local function createColorAnimation(self, duration, timeOffset, typ, set, ...)
|
||||
local newColors = {...}
|
||||
if(activeAnimations[typ]~=nil)then
|
||||
os.cancelTimer(activeAnimations[typ].timerId)
|
||||
end
|
||||
activeAnimations[typ] = {}
|
||||
local colorIndex = 1
|
||||
activeAnimations[typ].call = function()
|
||||
local color = newColors[colorIndex]
|
||||
set(self, color)
|
||||
end
|
||||
end
|
||||
|
||||
local object = {
|
||||
animatePosition = function(self, x, y, duration, timeOffset, mode, f)
|
||||
mode = mode or defaultMode
|
||||
duration = duration or 1
|
||||
timeOffset = timeOffset or 0
|
||||
x = math.floor(x+0.5)
|
||||
y = math.floor(y+0.5)
|
||||
createAnimation(self, x, y, duration, timeOffset, mode, "position", f, self.getPosition, self.setPosition)
|
||||
return self
|
||||
end,
|
||||
|
||||
animateSize = function(self, w, h, duration, timeOffset, mode, f)
|
||||
mode = mode or defaultMode
|
||||
duration = duration or 1
|
||||
timeOffset = timeOffset or 0
|
||||
createAnimation(self, w, h, duration, timeOffset, mode, "size", f, self.getSize, self.setSize)
|
||||
return self
|
||||
end,
|
||||
|
||||
animateOffset = function(self, x, y, duration, timeOffset, mode, f)
|
||||
mode = mode or defaultMode
|
||||
duration = duration or 1
|
||||
timeOffset = timeOffset or 0
|
||||
createAnimation(self, x, y, duration, timeOffset, mode, "offset", f, self.getOffset, self.setOffset)
|
||||
return self
|
||||
end,
|
||||
|
||||
animateBackground = function(self, color, duration, timeOffset, mode, f)
|
||||
mode = mode or defaultMode
|
||||
duration = duration or 1
|
||||
timeOffset = timeOffset or 0
|
||||
createColorAnimation(self, color, nil, duration, timeOffset, mode, "background", f, self.getBackground, self.setBackground)
|
||||
return self
|
||||
end,
|
||||
|
||||
doneHandler = function(self, timerId, ...)
|
||||
for k,v in pairs(activeAnimations)do
|
||||
if(v.timerId==timerId)then
|
||||
activeAnimations[k] = nil
|
||||
self:sendEvent("animation_done", self, "animation_done", k)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
onAnimationDone = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("animation_done", v)
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, timerId, ...)
|
||||
base.eventHandler(self, event, timerId, ...)
|
||||
if(event=="timer")then
|
||||
local animation = getAnimation(self, timerId)
|
||||
if(animation~=nil)then
|
||||
if(animation.progress<animation.duration)then
|
||||
animation.call()
|
||||
animation.progress = animation.progress+0.05
|
||||
animation.timerId=os.startTimer(0.05)
|
||||
else
|
||||
animation.finished()
|
||||
self:doneHandler(timerId)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data, scripts)
|
||||
base.setValuesByXMLData(self, data, scripts)
|
||||
local animX, animY, animateDuration, animeteTimeOffset, animateMode = xmlValue("animateX", data), xmlValue("animateY", data), xmlValue("animateDuration", data), xmlValue("animateTimeOffset", data), xmlValue("animateMode", data)
|
||||
local animW, animH, animateDuration, animeteTimeOffset, animateMode = xmlValue("animateW", data), xmlValue("animateH", data), xmlValue("animateDuration", data), xmlValue("animateTimeOffset", data), xmlValue("animateMode", data)
|
||||
local animXOffset, animYOffset, animateDuration, animeteTimeOffset, animateMode = xmlValue("animateXOffset", data), xmlValue("animateYOffset", data), xmlValue("animateDuration", data), xmlValue("animateTimeOffset", data), xmlValue("animateMode", data)
|
||||
if(animX~=nil and animY~=nil)then
|
||||
self:animatePosition(animX, animY, animateDuration, animeteTimeOffset, animateMode)
|
||||
end
|
||||
if(animW~=nil and animH~=nil)then
|
||||
self:animateSize(animW, animH, animateDuration, animeteTimeOffset, animateMode)
|
||||
end
|
||||
if(animXOffset~=nil and animYOffset~=nil)then
|
||||
self:animateOffset(animXOffset, animYOffset, animateDuration, animeteTimeOffset, animateMode)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
}
|
||||
|
||||
return object
|
||||
end
|
||||
}
|
||||
10
Basalt/plugins/basaltAdditions.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
return {
|
||||
basalt = function()
|
||||
return {
|
||||
cool = function()
|
||||
print("ello")
|
||||
sleep(2)
|
||||
end
|
||||
}
|
||||
end
|
||||
}
|
||||
42
Basalt/plugins/betterError.lua
Normal file
@@ -0,0 +1,42 @@
|
||||
local utils = require("utils")
|
||||
local wrapText = utils.wrapText
|
||||
|
||||
return {
|
||||
basalt = function(basalt)
|
||||
local frame
|
||||
local errorList
|
||||
return {
|
||||
getBasaltErrorFrame = function()
|
||||
return frame
|
||||
end,
|
||||
basaltError = function(err)
|
||||
if(frame==nil)then
|
||||
local mainFrame = basalt.getMainFrame()
|
||||
local w, h = mainFrame:getSize()
|
||||
frame = mainFrame:addMovableFrame("basaltErrorFrame"):setSize(w-10, h-4):setBackground(colors.lightGray):setForeground(colors.white):setZIndex(500)
|
||||
frame:addPane("titleBackground"):setSize(w, 1):setPosition(1, 1):setBackground(colors.black):setForeground(colors.white)
|
||||
frame:setPosition(w/2-frame:getWidth()/2, h/2-frame:getHeight()/2):setBorder(colors.black)
|
||||
frame:addLabel("title"):setText("Basalt Unexpected Error"):setPosition(2, 1):setBackground(colors.black):setForeground(colors.white)
|
||||
errorList = frame:addList("errorList"):setSize(frame:getWidth()-2, frame:getHeight()-6):setPosition(2, 3):setBackground(colors.lightGray):setForeground(colors.white):setSelectionColor(colors.lightGray, colors.gray)
|
||||
frame:addButton("xButton"):setText("x"):setPosition(frame:getWidth(), 1):setSize(1, 1):setBackground(colors.black):setForeground(colors.red):onClick(function()
|
||||
frame:hide()
|
||||
end)
|
||||
frame:addButton("Clear"):setText("Clear"):setPosition(frame:getWidth()-19, frame:getHeight()-1):setSize(9, 1):setBackground(colors.black):setForeground(colors.white):onClick(function()
|
||||
errorList:clear()
|
||||
end)
|
||||
frame:addButton("Close"):setText("Close"):setPosition(frame:getWidth()-9, frame:getHeight()-1):setSize(9, 1):setBackground(colors.black):setForeground(colors.white):onClick(function()
|
||||
basalt.autoUpdate(false)
|
||||
term.clear()
|
||||
term.setCursorPos(1, 1)
|
||||
end)
|
||||
end
|
||||
frame:show()
|
||||
errorList:addItem(("-"):rep(frame:getWidth()-2))
|
||||
local err = wrapText(err, frame:getWidth()-2)
|
||||
for i=1, #err do
|
||||
errorList:addItem(err[i])
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
}
|
||||
105
Basalt/plugins/border.lua
Normal file
@@ -0,0 +1,105 @@
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.xmlValue
|
||||
|
||||
return {
|
||||
VisualObject = function(base)
|
||||
local inline = true
|
||||
local borderColors = {top = false, bottom = false, left = false, right = false}
|
||||
|
||||
local object = {
|
||||
setBorder = function(self, ...)
|
||||
local t = {...}
|
||||
if(t~=nil)then
|
||||
for k,v in pairs(t)do
|
||||
if(v=="left")or(#t==1)then
|
||||
borderColors["left"] = t[1]
|
||||
end
|
||||
if(v=="top")or(#t==1)then
|
||||
borderColors["top"] = t[1]
|
||||
end
|
||||
if(v=="right")or(#t==1)then
|
||||
borderColors["right"] = t[1]
|
||||
end
|
||||
if(v=="bottom")or(#t==1)then
|
||||
borderColors["bottom"] = t[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("border", function()
|
||||
local x, y = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
local bgCol = self:getBackground()
|
||||
if(inline)then
|
||||
if(borderColors["left"]~=false)then
|
||||
self:addTextBox(1, 1, 1, h, "\149")
|
||||
if(bgCol~=false)then self:addBackgroundBox(1, 1, 1, h, bgCol) end
|
||||
self:addForegroundBox(1, 1, 1, h, borderColors["left"])
|
||||
end
|
||||
|
||||
if(borderColors["top"]~=false)then
|
||||
self:addTextBox(1, 1, w, 1, "\131")
|
||||
if(bgCol~=false)then self:addBackgroundBox(1, 1, w, 1, bgCol) end
|
||||
self:addForegroundBox(1, 1, w, 1, borderColors["top"])
|
||||
end
|
||||
|
||||
if(borderColors["left"]~=false)and(borderColors["top"]~=false)then
|
||||
self:addTextBox(1, 1, 1, 1, "\151")
|
||||
if(bgCol~=false)then self:addBackgroundBox(1, 1, 1, 1, bgCol) end
|
||||
self:addForegroundBox(1, 1, 1, 1, borderColors["left"])
|
||||
end
|
||||
if(borderColors["right"]~=false)then
|
||||
self:addTextBox(w, 1, 1, h, "\149")
|
||||
if(bgCol~=false)then self:addForegroundBox(w, 1, 1, h, bgCol) end
|
||||
self:addBackgroundBox(w, 1, 1, h, borderColors["right"])
|
||||
end
|
||||
if(borderColors["bottom"]~=false)then
|
||||
self:addTextBox(1, h, w, 1, "\143")
|
||||
if(bgCol~=false)then self:addForegroundBox(1, h, w, 1, bgCol) end
|
||||
self:addBackgroundBox(1, h, w, 1, borderColors["bottom"])
|
||||
end
|
||||
if(borderColors["top"]~=false)and(borderColors["right"]~=false)then
|
||||
self:addTextBox(w, 1, 1, 1, "\148")
|
||||
if(bgCol~=false)then self:addForegroundBox(w, 1, 1, 1, bgCol) end
|
||||
self:addBackgroundBox(w, 1, 1, 1, borderColors["right"])
|
||||
end
|
||||
if(borderColors["right"]~=false)and(borderColors["bottom"]~=false)then
|
||||
self:addTextBox(w, h, 1, 1, "\133")
|
||||
if(bgCol~=false)then self:addForegroundBox(w, h, 1, 1, bgCol) end
|
||||
self:addBackgroundBox(w, h, 1, 1, borderColors["right"])
|
||||
end
|
||||
if(borderColors["bottom"]~=false)and(borderColors["left"]~=false)then
|
||||
self:addTextBox(1, h, 1, 1, "\138")
|
||||
if(bgCol~=false)then self:addForegroundBox(0, h, 1, 1, bgCol) end
|
||||
self:addBackgroundBox(1, h, 1, 1, borderColors["left"])
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data, scripts)
|
||||
base.setValuesByXMLData(self, data)
|
||||
local borders = {}
|
||||
if(xmlValue("border", data)~=nil)then
|
||||
borders["top"] = colors[xmlValue("border", data)]
|
||||
borders["bottom"] = colors[xmlValue("border", data)]
|
||||
borders["left"] = colors[xmlValue("border", data)]
|
||||
borders["right"] = colors[xmlValue("border", data)]
|
||||
end
|
||||
if(xmlValue("borderTop", data)~=nil)then borders["top"] = colors[xmlValue("borderTop", data)] end
|
||||
if(xmlValue("borderBottom", data)~=nil)then borders["bottom"] = colors[xmlValue("borderBottom", data)] end
|
||||
if(xmlValue("borderLeft", data)~=nil)then borders["left"] = colors[xmlValue("borderLeft", data)] end
|
||||
if(xmlValue("borderRight", data)~=nil)then borders["right"] = colors[xmlValue("borderRight", data)] end
|
||||
self:setBorder(borders["top"], borders["bottom"], borders["left"], borders["right"])
|
||||
return self
|
||||
end
|
||||
}
|
||||
|
||||
return object
|
||||
end
|
||||
}
|
||||
97
Basalt/plugins/debug.lua
Normal file
@@ -0,0 +1,97 @@
|
||||
local utils = require("utils")
|
||||
local wrapText = utils.wrapText
|
||||
|
||||
return {
|
||||
basalt = function(basalt)
|
||||
local mainFrame = basalt.getMainFrame()
|
||||
local debugFrame
|
||||
local debugList
|
||||
local debugLabel
|
||||
local debugExitButton
|
||||
|
||||
local function createDebuggingFrame()
|
||||
local minW = 16
|
||||
local minH = 6
|
||||
local maxW = 99
|
||||
local maxH = 99
|
||||
local w, h = mainFrame:getSize()
|
||||
debugFrame = mainFrame:addMovableFrame("basaltDebuggingFrame"):setSize(w-20, h-10):setBackground(colors.gray):setForeground(colors.white):setZIndex(100):hide()
|
||||
debugFrame:addPane():setSize("parent.w", 1):setPosition(1, 1):setBackground(colors.black):setForeground(colors.white)
|
||||
debugFrame:setPosition(-w, h/2-debugFrame:getHeight()/2):setBorder(colors.black)
|
||||
local resizeButton = debugFrame:addButton()
|
||||
:setPosition("parent.w", "parent.h")
|
||||
:setSize(1, 1)
|
||||
:setText("\133")
|
||||
:setForeground(colors.gray)
|
||||
:setBackground(colors.black)
|
||||
:onClick(function() end)
|
||||
:onDrag(function(self, event, btn, xOffset, yOffset)
|
||||
local w, h = debugFrame:getSize()
|
||||
local wOff, hOff = w, h
|
||||
if(w+xOffset-1>=minW)and(w+xOffset-1<=maxW)then
|
||||
wOff = w+xOffset-1
|
||||
end
|
||||
if(h+yOffset-1>=minH)and(h+yOffset-1<=maxH)then
|
||||
hOff = h+yOffset-1
|
||||
end
|
||||
debugFrame:setSize(wOff, hOff)
|
||||
end)
|
||||
|
||||
debugExitButton = debugFrame:addButton():setText("Close"):setPosition("parent.w - 6", 1):setSize(7, 1):setBackground(colors.red):setForeground(colors.white):onClick(function()
|
||||
debugFrame:animatePosition(-w, h/2-debugFrame:getHeight()/2, 0.5)
|
||||
end)
|
||||
debugList = debugFrame:addList()
|
||||
:setSize("parent.w - 2", "parent.h - 3")
|
||||
:setPosition(2, 3)
|
||||
:setBackground(colors.gray)
|
||||
:setForeground(colors.white)
|
||||
:setSelectionColor(colors.gray, colors.white)
|
||||
if(debugLabel==nil)then
|
||||
debugLabel = mainFrame:addLabel()
|
||||
:setPosition(1, "parent.h")
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.white)
|
||||
:setZIndex(100)
|
||||
:onClick(function()
|
||||
debugFrame:show()
|
||||
debugFrame:animatePosition(w/2-debugFrame:getWidth()/2, h/2-debugFrame:getHeight()/2, 0.5)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
debug = function(...)
|
||||
local args = { ... }
|
||||
if(mainFrame==nil)then
|
||||
mainFrame = basalt.getMainFrame()
|
||||
if(mainFrame~=nil)then
|
||||
createDebuggingFrame()
|
||||
else
|
||||
print(...) return
|
||||
end
|
||||
end
|
||||
if (mainFrame:getName() ~= "basaltDebuggingFrame") then
|
||||
if (mainFrame ~= debugFrame) then
|
||||
debugLabel:setParent(mainFrame)
|
||||
end
|
||||
end
|
||||
local str = ""
|
||||
for key, value in pairs(args) do
|
||||
str = str .. tostring(value) .. (#args ~= key and ", " or "")
|
||||
end
|
||||
debugLabel:setText("[Debug] " .. str)
|
||||
for k,v in pairs(wrapText(str, debugList:getWidth()))do
|
||||
debugList:addItem(v)
|
||||
end
|
||||
if (debugList:getItemCount() > 50) then
|
||||
debugList:removeItem(1)
|
||||
end
|
||||
debugList:setValue(debugList:getItem(debugList:getItemCount()))
|
||||
if(debugList.getItemCount() > debugList:getHeight())then
|
||||
debugList:setOffset(debugList:getItemCount() - debugList:getHeight())
|
||||
end
|
||||
debugLabel:show()
|
||||
end
|
||||
}
|
||||
end
|
||||
}
|
||||
125
Basalt/plugins/dynamicValues.lua
Normal file
@@ -0,0 +1,125 @@
|
||||
local utils = require("utils")
|
||||
local count = utils.tableCount
|
||||
local xmlValue = utils.xmlValue
|
||||
|
||||
return {
|
||||
VisualObject = function(base, basalt)
|
||||
local dynObjects = {}
|
||||
local curProperties = {}
|
||||
local properties = {x="getX", y="getY", w="getWidth", h="getHeight"}
|
||||
|
||||
local function stringToNumber(str)
|
||||
local ok, result = pcall(load("return " .. str, "", nil, {math=math}))
|
||||
if not(ok)then error(str.." - is not a valid dynamic value string") end
|
||||
return result
|
||||
end
|
||||
|
||||
local function createDynamicValue(self, key, val)
|
||||
local objectGroup = {}
|
||||
local properties = properties
|
||||
for a,b in pairs(properties)do
|
||||
for v in val:gmatch("%a+%."..a)do
|
||||
local name = v:gsub("%."..a, "")
|
||||
if(name~="self")and(name~="parent")then
|
||||
table.insert(objectGroup, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local parent = self:getParent()
|
||||
local objects = {}
|
||||
for k,v in pairs(objectGroup)do
|
||||
objects[v] = parent:getObject(v)
|
||||
if(objects[v]==nil)then
|
||||
error("Dynamic Values - unable to find object: "..v)
|
||||
end
|
||||
end
|
||||
objects["self"] = self
|
||||
objects["parent"] = parent
|
||||
|
||||
dynObjects[key] = function()
|
||||
local mainVal = val
|
||||
for a,b in pairs(properties)do
|
||||
for v in val:gmatch("%w+%."..a) do
|
||||
local obj = objects[v:gsub("%."..a, "")]
|
||||
if(obj~=nil)then
|
||||
mainVal = mainVal:gsub(v, obj[b](obj))
|
||||
else
|
||||
error("Dynamic Values - unable to find object: "..v)
|
||||
end
|
||||
end
|
||||
end
|
||||
curProperties[key] = math.floor(stringToNumber(mainVal)+0.5)
|
||||
end
|
||||
dynObjects[key]()
|
||||
end
|
||||
|
||||
local function updatePositions(self)
|
||||
if(count(dynObjects)>0)then
|
||||
for k,v in pairs(dynObjects)do
|
||||
v()
|
||||
end
|
||||
local properties = {x="getX", y="getY", w="getWidth", h="getHeight"}
|
||||
for k,v in pairs(properties)do
|
||||
if(dynObjects[k]~=nil)then
|
||||
if(curProperties[k]~=self[v](self))then
|
||||
if(k=="x")or(k=="y")then
|
||||
base.setPosition(self, curProperties["x"] or self:getX(), curProperties["y"] or self:getY())
|
||||
end
|
||||
if(k=="w")or(k=="h")then
|
||||
base.setSize(self, curProperties["w"] or self:getWidth(), curProperties["h"] or self:getHeight())
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local object = {
|
||||
updatePositions = updatePositions,
|
||||
createDynamicValue = createDynamicValue,
|
||||
|
||||
setPosition = function(self, xPos, yPos, rel)
|
||||
curProperties.x = xPos
|
||||
curProperties.y = yPos
|
||||
if(type(xPos)=="string")then
|
||||
createDynamicValue(self, "x", xPos)
|
||||
else
|
||||
dynObjects["x"] = nil
|
||||
end
|
||||
if(type(yPos)=="string")then
|
||||
createDynamicValue(self, "y", yPos)
|
||||
else
|
||||
dynObjects["y"] = nil
|
||||
end
|
||||
base.setPosition(self, curProperties.x, curProperties.y, rel)
|
||||
return self
|
||||
end,
|
||||
|
||||
setSize = function(self, w, h, rel)
|
||||
curProperties.w = w
|
||||
curProperties.h = h
|
||||
if(type(w)=="string")then
|
||||
createDynamicValue(self, "w", w)
|
||||
else
|
||||
dynObjects["w"] = nil
|
||||
end
|
||||
if(type(h)=="string")then
|
||||
createDynamicValue(self, "h", h)
|
||||
else
|
||||
dynObjects["h"] = nil
|
||||
end
|
||||
base.setSize(self, curProperties.w, curProperties.h, rel)
|
||||
return self
|
||||
end,
|
||||
|
||||
customEventHandler = function(self, event, ...)
|
||||
base.customEventHandler(self, event, ...)
|
||||
if(event=="basalt_FrameReposition")or(event=="basalt_FrameResize")then
|
||||
updatePositions(self)
|
||||
end
|
||||
end,
|
||||
}
|
||||
return object
|
||||
end
|
||||
}
|
||||
221
Basalt/plugins/pixelbox.lua
Normal file
@@ -0,0 +1,221 @@
|
||||
-- Most of this is made by Dev9551, you can find his awesome work here: https://github.com/9551-Dev/apis/blob/main/pixelbox_lite.lua
|
||||
-- Slighly modified by NyoriE to work with Basalt
|
||||
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
Copyright © 2022 Oliver Caha (9551Dev)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
local t_sort,t_cat,s_char = table.sort,table.concat,string.char
|
||||
local function sort(a,b) return a[2] > b[2] end
|
||||
|
||||
local distances = {
|
||||
{5,256,16,8,64,32},
|
||||
{4,16,16384,256,128},
|
||||
[4] = {4,64,1024,256,128},
|
||||
[8] = {4,512,2048,256,1},
|
||||
[16] = {4,2,16384,256,1},
|
||||
[32] = {4,8192,4096,256,1},
|
||||
[64] = {4,4,1024,256,1},
|
||||
[128] = {6,32768,256,1024,2048,4096,16384},
|
||||
[256] = {6,1,128,2,512,4,8192},
|
||||
[512] = {4,8,2048,256,128},
|
||||
[1024] = {4,4,64,128,32768},
|
||||
[2048] = {4,512,8,128,32768},
|
||||
[4096] = {4,8192,32,128,32768},
|
||||
[8192] = {3,32,4096,256128},
|
||||
[16384] = {4,2,16,128,32768},
|
||||
[32768] = {5,128,1024,2048,4096,16384}
|
||||
}
|
||||
|
||||
local to_colors = {}
|
||||
for i = 0, 15 do
|
||||
to_colors[("%x"):format(i)] = 2^i
|
||||
end
|
||||
|
||||
local to_blit = {}
|
||||
for i = 0, 15 do
|
||||
to_blit[2^i] = ("%x"):format(i)
|
||||
end
|
||||
|
||||
local function pixelbox(colTable, defaultCol)
|
||||
defaultCol = defaultCol or "f"
|
||||
local width, height = #colTable[1], #colTable
|
||||
local cache = {}
|
||||
local canv = {}
|
||||
local cached = false
|
||||
|
||||
local function generateCanvas()
|
||||
for y = 1, height * 3 do
|
||||
for x = 1, width * 2 do
|
||||
if not canv[y] then canv[y] = {} end
|
||||
canv[y][x] = defaultCol
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in ipairs(colTable) do
|
||||
for x = 1, #v do
|
||||
local col = v:sub(x, x)
|
||||
canv[k][x] = to_colors[col]
|
||||
end
|
||||
end
|
||||
end
|
||||
generateCanvas()
|
||||
|
||||
local function setSize(w,h)
|
||||
width, height = w, h
|
||||
canv = {}
|
||||
cached = false
|
||||
generateCanvas()
|
||||
end
|
||||
|
||||
|
||||
local function generateChar(a,b,c,d,e,f)
|
||||
local arr = {a,b,c,d,e,f}
|
||||
local c_types = {}
|
||||
local sortable = {}
|
||||
local ind = 0
|
||||
for i=1,6 do
|
||||
local c = arr[i]
|
||||
if not c_types[c] then
|
||||
ind = ind + 1
|
||||
c_types[c] = {0,ind}
|
||||
end
|
||||
|
||||
local t = c_types[c]
|
||||
local t1 = t[1] + 1
|
||||
|
||||
t[1] = t1
|
||||
sortable[t[2]] = {c,t1}
|
||||
end
|
||||
local n = #sortable
|
||||
while n > 2 do
|
||||
t_sort(sortable,sort)
|
||||
local bit6 = distances[sortable[n][1]]
|
||||
local index,run = 1,false
|
||||
local nm1 = n - 1
|
||||
for i=2,bit6[1] do
|
||||
if run then break end
|
||||
local tab = bit6[i]
|
||||
for j=1,nm1 do
|
||||
if sortable[j][1] == tab then
|
||||
index = j
|
||||
run = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
local from,to = sortable[n][1],sortable[index][1]
|
||||
for i=1,6 do
|
||||
if arr[i] == from then
|
||||
arr[i] = to
|
||||
local sindex = sortable[index]
|
||||
sindex[2] = sindex[2] + 1
|
||||
end
|
||||
end
|
||||
|
||||
sortable[n] = nil
|
||||
n = n - 1
|
||||
end
|
||||
|
||||
local n = 128
|
||||
local a6 = arr[6]
|
||||
|
||||
if arr[1] ~= a6 then n = n + 1 end
|
||||
if arr[2] ~= a6 then n = n + 2 end
|
||||
if arr[3] ~= a6 then n = n + 4 end
|
||||
if arr[4] ~= a6 then n = n + 8 end
|
||||
if arr[5] ~= a6 then n = n + 16 end
|
||||
|
||||
if sortable[1][1] == arr[6] then
|
||||
return s_char(n),sortable[2][1],arr[6]
|
||||
else
|
||||
return s_char(n),sortable[1][1],arr[6]
|
||||
end
|
||||
end
|
||||
|
||||
local function convert()
|
||||
local w_double = width * 2
|
||||
|
||||
local sy = 0
|
||||
for y = 1, height * 3, 3 do
|
||||
sy = sy + 1
|
||||
local layer_1 = canv[y]
|
||||
local layer_2 = canv[y + 1]
|
||||
local layer_3 = canv[y + 2]
|
||||
local char_line, fg_line, bg_line = {}, {}, {}
|
||||
local n = 0
|
||||
for x = 1, w_double, 2 do
|
||||
local xp1 = x + 1
|
||||
local b11, b21, b12, b22, b13, b23 = layer_1[x], layer_1[xp1], layer_2[x], layer_2[xp1], layer_3[x], layer_3[xp1]
|
||||
|
||||
local char, fg, bg = " ", 1, b11
|
||||
if not (b21 == b11 and b12 == b11 and b22 == b11 and b13 == b11 and b23 == b11) then
|
||||
char, fg, bg = generateChar(b11, b21, b12, b22, b13, b23)
|
||||
end
|
||||
n = n + 1
|
||||
char_line[n] = char
|
||||
fg_line[n] = to_blit[fg]
|
||||
bg_line[n] = to_blit[bg]
|
||||
end
|
||||
|
||||
cache[sy] = {t_cat(char_line), t_cat(fg_line), t_cat(bg_line)}
|
||||
end
|
||||
cached = true
|
||||
end
|
||||
|
||||
return {
|
||||
convert = convert,
|
||||
generateCanvas = generateCanvas,
|
||||
setSize = setSize,
|
||||
getSize = function()
|
||||
return width, height
|
||||
end,
|
||||
set = function(colTab, defCol)
|
||||
colTable = colTab
|
||||
defaultCol = defCol or defaultCol
|
||||
canv = {}
|
||||
cached = false
|
||||
generateCanvas()
|
||||
end,
|
||||
get = function(y)
|
||||
if not cached then convert() end
|
||||
return y~= nil and cache[y] or cache
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
Image = function(base, basalt)
|
||||
return {
|
||||
shrink = function(self)
|
||||
local bimg = self:getImageFrame(1)
|
||||
local img = {}
|
||||
for k,v in pairs(bimg)do
|
||||
if(type(k)=="number")then
|
||||
table.insert(img,v[3])
|
||||
end
|
||||
end
|
||||
local shrinkedImg = pixelbox(img, self:getBackground()).get()
|
||||
self:setImage(shrinkedImg)
|
||||
return self
|
||||
end,
|
||||
|
||||
getShrinkedImage = function(self)
|
||||
local bimg = self:getImageFrame(1)
|
||||
local img = {}
|
||||
for k,v in pairs(bimg)do
|
||||
if(type(k)=="number")then
|
||||
table.insert(img, v[3])
|
||||
end
|
||||
end
|
||||
return pixelbox(img, self:getBackground()).get()
|
||||
end,
|
||||
}
|
||||
end,
|
||||
}
|
||||
43
Basalt/plugins/shadow.lua
Normal file
@@ -0,0 +1,43 @@
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.xmlValue
|
||||
|
||||
return {
|
||||
VisualObject = function(base)
|
||||
local shadow = false
|
||||
|
||||
local object = {
|
||||
setShadow = function(self, color)
|
||||
shadow = color
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getShadow = function(self)
|
||||
return shadow
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("shadow", function()
|
||||
if(shadow~=false)then
|
||||
local w,h = self:getSize()
|
||||
if(shadow)then
|
||||
self:addBackgroundBox(w+1, 2, 1, h, shadow)
|
||||
self:addBackgroundBox(2, h+1, w, 1, shadow)
|
||||
self:addForegroundBox(w+1, 2, 1, h, shadow)
|
||||
self:addForegroundBox(2, h+1, w, 1, shadow)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data, scripts)
|
||||
base.setValuesByXMLData(self, data, scripts)
|
||||
if(xmlValue("shadow", data)~=nil)then self:setShadow(xmlValue("shadow", data)) end
|
||||
return self
|
||||
end
|
||||
}
|
||||
|
||||
return object
|
||||
end
|
||||
}
|
||||
123
Basalt/plugins/textures.lua
Normal file
@@ -0,0 +1,123 @@
|
||||
local images = require("images")
|
||||
local utils = require("utils")
|
||||
local xmlValue = utils.xmlValue
|
||||
return {
|
||||
VisualObject = function(base)
|
||||
local textureId, infinitePlay = 1, true
|
||||
local bimg, texture, textureTimerId
|
||||
local textureMode = "default"
|
||||
|
||||
local object = {
|
||||
addTexture = function(self, path, animate)
|
||||
bimg = images.loadImageAsBimg(path)
|
||||
texture = bimg[1]
|
||||
if(animate)then
|
||||
if(bimg.animated)then
|
||||
self:listenEvent("other_event")
|
||||
local t = bimg[textureId].duration or bimg.secondsPerFrame or 0.2
|
||||
textureTimerId = os.startTimer(t)
|
||||
end
|
||||
end
|
||||
self:setBackground(false)
|
||||
self:setForeground(false)
|
||||
self:setDrawState("texture-base", true)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setTextureMode = function(self, mode)
|
||||
textureMode = mode or textureMode
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setInfinitePlay = function(self, state)
|
||||
infinitePlay = state
|
||||
return self
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, timerId, ...)
|
||||
base.eventHandler(self, event, timerId, ...)
|
||||
if(event=="timer")then
|
||||
if(timerId == textureTimerId)then
|
||||
if(bimg[textureId+1]~=nil)then
|
||||
textureId = textureId + 1
|
||||
texture = bimg[textureId]
|
||||
local t = bimg[textureId].duration or bimg.secondsPerFrame or 0.2
|
||||
textureTimerId = os.startTimer(t)
|
||||
self:updateDraw()
|
||||
else
|
||||
if(infinitePlay)then
|
||||
textureId = 1
|
||||
texture = bimg[1]
|
||||
local t = bimg[textureId].duration or bimg.secondsPerFrame or 0.2
|
||||
textureTimerId = os.startTimer(t)
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
base.draw(self)
|
||||
self:addDraw("texture-base", function()
|
||||
local obj = self:getParent() or self
|
||||
local x, y = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
local wP,hP = obj:getSize()
|
||||
|
||||
local textureWidth = bimg.width or #bimg[textureId][1][1]
|
||||
local textureHeight = bimg.height or #bimg[textureId]
|
||||
|
||||
local startX, startY = 0, 0
|
||||
|
||||
if (textureMode == "center") then
|
||||
startX = x + math.floor((w - textureWidth) / 2 + 0.5) - 1
|
||||
startY = y + math.floor((h - textureHeight) / 2 + 0.5) - 1
|
||||
elseif (textureMode == "default") then
|
||||
startX, startY = x, y
|
||||
elseif (textureMode == "right") then
|
||||
startX, startY = x + w - textureWidth, y + h - textureHeight
|
||||
end
|
||||
|
||||
local textureX = x - startX
|
||||
local textureY = y - startY
|
||||
|
||||
if startX < x then
|
||||
startX = x
|
||||
textureWidth = textureWidth - textureX
|
||||
end
|
||||
if startY < y then
|
||||
startY = y
|
||||
textureHeight = textureHeight - textureY
|
||||
end
|
||||
if startX + textureWidth > x + w then
|
||||
textureWidth = (x + w) - startX
|
||||
end
|
||||
if startY + textureHeight > y + h then
|
||||
textureHeight = (y + h) - startY
|
||||
end
|
||||
|
||||
for k = 1, textureHeight do
|
||||
if(texture[k+textureY]~=nil)then
|
||||
local t, f, b = table.unpack(texture[k+textureY])
|
||||
self:addBlit(1, k, t:sub(textureX, textureX + textureWidth), f:sub(textureX, textureX + textureWidth), b:sub(textureX, textureX + textureWidth))
|
||||
end
|
||||
end
|
||||
end, 1)
|
||||
self:setDrawState("texture-base", false)
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data, scripts)
|
||||
base.setValuesByXMLData(self, data, scripts)
|
||||
if(xmlValue("texture", data)~=nil)then self:addTexture(xmlValue("texture", data), xmlValue("animate", data)) end
|
||||
if(xmlValue("textureMode", data)~=nil)then self:setTextureMode(xmlValue("textureMode", data)) end
|
||||
if(xmlValue("infinitePlay", data)~=nil)then self:setInfinitePlay(xmlValue("infinitePlay", data)) end
|
||||
return self
|
||||
end
|
||||
}
|
||||
|
||||
return object
|
||||
end
|
||||
}
|
||||
99
Basalt/plugins/themes.lua
Normal file
@@ -0,0 +1,99 @@
|
||||
local baseTheme = { -- The default main theme for basalt!
|
||||
BaseFrameBG = colors.lightGray,
|
||||
BaseFrameText = colors.black,
|
||||
FrameBG = colors.gray,
|
||||
FrameText = colors.black,
|
||||
ButtonBG = colors.gray,
|
||||
ButtonText = colors.black,
|
||||
CheckboxBG = colors.lightGray,
|
||||
CheckboxText = colors.black,
|
||||
InputBG = colors.black,
|
||||
InputText = colors.lightGray,
|
||||
TextfieldBG = colors.black,
|
||||
TextfieldText = colors.white,
|
||||
ListBG = colors.gray,
|
||||
ListText = colors.black,
|
||||
MenubarBG = colors.gray,
|
||||
MenubarText = colors.black,
|
||||
DropdownBG = colors.gray,
|
||||
DropdownText = colors.black,
|
||||
RadioBG = colors.gray,
|
||||
RadioText = colors.black,
|
||||
SelectionBG = colors.black,
|
||||
SelectionText = colors.lightGray,
|
||||
GraphicBG = colors.black,
|
||||
ImageBG = colors.black,
|
||||
PaneBG = colors.black,
|
||||
ProgramBG = colors.black,
|
||||
ProgressbarBG = colors.gray,
|
||||
ProgressbarText = colors.black,
|
||||
ProgressbarActiveBG = colors.black,
|
||||
ScrollbarBG = colors.lightGray,
|
||||
ScrollbarText = colors.gray,
|
||||
ScrollbarSymbolColor = colors.black,
|
||||
SliderBG = false,
|
||||
SliderText = colors.gray,
|
||||
SliderSymbolColor = colors.black,
|
||||
SwitchBG = colors.lightGray,
|
||||
SwitchText = colors.gray,
|
||||
LabelBG = false,
|
||||
LabelText = colors.black,
|
||||
GraphBG = colors.gray,
|
||||
GraphText = colors.black
|
||||
}
|
||||
|
||||
local plugin = {
|
||||
Container = function(base, name, basalt)
|
||||
local theme = {}
|
||||
|
||||
local object = {
|
||||
getTheme = function(self, name)
|
||||
local parent = self:getParent()
|
||||
return theme[name] or (parent~=nil and parent:getTheme(name) or baseTheme[name])
|
||||
end,
|
||||
setTheme = function(self, _theme, col)
|
||||
if(type(_theme)=="table")then
|
||||
theme = _theme
|
||||
elseif(type(_theme)=="string")then
|
||||
theme[_theme] = col
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
}
|
||||
return object
|
||||
end,
|
||||
|
||||
basalt = function()
|
||||
return {
|
||||
getTheme = function(name)
|
||||
return baseTheme[name]
|
||||
end,
|
||||
setTheme = function(_theme, col)
|
||||
if(type(_theme)=="table")then
|
||||
baseTheme = _theme
|
||||
elseif(type(_theme)=="string")then
|
||||
baseTheme[_theme] = col
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
for k,v in pairs({"BaseFrame", "Frame", "ScrollableFrame", "MovableFrame", "Button", "Checkbox", "Dropdown", "Graph", "Graphic", "Input", "Label", "List", "Menubar", "Pane", "Program", "Progressbar", "Radio", "Scrollbar", "Slider", "Switch", "Textfield"})do
|
||||
plugin[v] = function(base, name, basalt)
|
||||
local object = {
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
local parent = self:getParent() or self
|
||||
self:setBackground(parent:getTheme(v.."BG"))
|
||||
self:setForeground(parent:getTheme(v.."Text"))
|
||||
end
|
||||
end
|
||||
}
|
||||
return object
|
||||
end
|
||||
end
|
||||
|
||||
return plugin
|
||||
1185
Basalt/plugins/xml.lua
Normal file
@@ -1,47 +0,0 @@
|
||||
return { -- The default main theme for basalt!
|
||||
BasaltBG = colors.lightGray,
|
||||
BasaltText = colors.black,
|
||||
FrameBG = colors.gray,
|
||||
FrameText = colors.black,
|
||||
ButtonBG = colors.gray,
|
||||
ButtonText = colors.black,
|
||||
CheckboxBG = colors.gray,
|
||||
CheckboxText = colors.black,
|
||||
InputBG = colors.gray,
|
||||
InputText = colors.black,
|
||||
TextfieldBG = colors.gray,
|
||||
TextfieldText = colors.black,
|
||||
ListBG = colors.gray,
|
||||
ListText = colors.black,
|
||||
MenubarBG = colors.gray,
|
||||
MenubarText = colors.black,
|
||||
DropdownBG = colors.gray,
|
||||
DropdownText = colors.black,
|
||||
RadioBG = colors.gray,
|
||||
RadioText = colors.black,
|
||||
SelectionBG = colors.black,
|
||||
SelectionText = colors.lightGray,
|
||||
GraphicBG = colors.black,
|
||||
ImageBG = colors.black,
|
||||
PaneBG = colors.black,
|
||||
ProgramBG = colors.black,
|
||||
ProgressbarBG = colors.gray,
|
||||
ProgressbarText = colors.black,
|
||||
ProgressbarActiveBG = colors.black,
|
||||
ScrollbarBG = colors.lightGray,
|
||||
ScrollbarText = colors.gray,
|
||||
ScrollbarSymbolColor = colors.black,
|
||||
SliderBG = false,
|
||||
SliderText = colors.gray,
|
||||
SliderSymbolColor = colors.black,
|
||||
SwitchBG = colors.lightGray,
|
||||
SwitchText = colors.gray,
|
||||
SwitchBGSymbol = colors.black,
|
||||
SwitchInactive = colors.red,
|
||||
SwitchActive = colors.green,
|
||||
LabelBG = false,
|
||||
LabelText = colors.black,
|
||||
GraphBG = colors.gray,
|
||||
GraphText = colors.black
|
||||
|
||||
}
|
||||
12
docs/Home.md
@@ -2,11 +2,19 @@
|
||||
|
||||
*Note: The Basalt Wiki is a work in progress. Please treat wiki errors the same as bugs and report them accordingly.*
|
||||
|
||||
Here you can find information about how to use Basalt as well as examples of functional Basalt code. The aim of Basalt is to improve user interaction through visual display.
|
||||
Basalt is a user-friendly UI framework for CC:Tweaked (also known as "ComputerCraft: Tweaked") - a popular Minecraft mod. It was developed to enhance user interaction through visual displays. In this wiki, you'll find information on how to use Basalt as well as examples of functional Basalt code.
|
||||
|
||||
This Website is made with the help of ChatGPT.
|
||||
|
||||
## About Basalt
|
||||
|
||||
Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (Also known as "ComputerCraft: Tweaked") - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's [wiki](https://tweaked.cc/) or [download](https://modrinth.com/mod/cc-tweaked).
|
||||
Basalt is an easy-to-understand UI framework designed to improve user interaction with CC:Tweaked. Some of its key features include:
|
||||
|
||||
- A set of pre-built UI components for creating interfaces quickly and easily.
|
||||
- A flexible layout system that allows users to create custom designs.
|
||||
- A powerful event handling system for managing user input and interaction.
|
||||
- Support for multiple screen resolutions and aspect ratios.
|
||||
- Extensive documentation and examples to help users get started quickly.
|
||||
|
||||
## Quick Demo
|
||||
|
||||
|
||||
@@ -1,32 +1,41 @@
|
||||
[1.6 Docs](https://basalt.madefor.cc/docs1_6)
|
||||
|
||||
- About
|
||||
- [Home](home)
|
||||
- [Home](/)
|
||||
- [How To](home/How-To)
|
||||
- [Download](home/download)
|
||||
- Objects
|
||||
- [Basalt](objects/Basalt.md)
|
||||
- [Object](objects/Object.md)
|
||||
- [VisualObject](objects/VisualObject.md)
|
||||
- [ChangeableObject](objects/ChangeableObject.md)
|
||||
- [Container](objects/Container.md)
|
||||
- [BaseFrame](objects/BaseFrame.md)
|
||||
- [MonitorFrame](objects/MonitorFrame.md)
|
||||
- [Frame](objects/Frame.md)
|
||||
- [Flexbox](objects/Flexbox.md)
|
||||
- [MovableFrame](objects/MovableFrame.md)
|
||||
- [ScrollableFrame](objects/ScrollableFrame.md)
|
||||
- [Button](objects/Button.md)
|
||||
- [Checkbox](objects/Checkbox.md)
|
||||
- [Dropdown](objects/Dropdown.md)
|
||||
- [Frame](objects/Frame.md)
|
||||
- [Graph](objects/Graph.md)
|
||||
- [Image](objects/Image.md)
|
||||
- [Input](objects/Input.md)
|
||||
- [Label](objects/Label.md)
|
||||
- [List](objects/List.md)
|
||||
- [Menubar](objects/Menubar.md)
|
||||
- [Dropdown](objects/Dropdown.md)
|
||||
- [Menubar](objects/Menubar.md)
|
||||
- [Radio](objects/Radio.md)
|
||||
- [Pane](objects/Pane.md)
|
||||
- [Program](objects/Program.md)
|
||||
- [Progressbar](objects/Progressbar.md)
|
||||
- [Radio](objects/Radio.md)
|
||||
- [Scrollbar](objects/Scrollbar.md)
|
||||
- [Slider](objects/Slider.md)
|
||||
- [Textfield](objects/Textfield.md)
|
||||
- [Animation](objects/Animation.md)
|
||||
- [Thread](objects/Thread.md)
|
||||
- [Treeview](objects/Treeview.md)
|
||||
- [Timer](objects/Timer.md)
|
||||
- Tips & Tricks
|
||||
- [Your Logic](tips/logic.md)
|
||||
- [Button coloring](tips/buttonColoring.md)
|
||||
- [Designing/Animating](tips/design.md)
|
||||
- [Dynamic Values](tips/dynamicvalues.md)
|
||||
- [XML](tips/xml.md)
|
||||
- Guides
|
||||
- [Introduction to Basalt](guides/introduction.md)
|
||||
- [Dynamic Values](guides/dynamicvalues.md)
|
||||
- [XML](guides/xml.md)
|
||||
|
||||
0
docs/docs1_6/.nojekyll
Normal file
1
docs/docs1_6/CNAME
Normal file
@@ -0,0 +1 @@
|
||||
basalt.madefor.cc
|
||||
19
docs/docs1_6/Home.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Welcome to The Basalt Wiki
|
||||
|
||||
*Note: The Basalt Wiki is a work in progress. Please treat wiki errors the same as bugs and report them accordingly.*
|
||||
|
||||
Here you can find information about how to use Basalt as well as examples of functional Basalt code. The aim of Basalt is to improve user interaction through visual display.
|
||||
|
||||
## About Basalt
|
||||
|
||||
Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (Also known as "ComputerCraft: Tweaked") - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's [wiki](https://tweaked.cc/) or [download](https://modrinth.com/mod/cc-tweaked).
|
||||
|
||||
## Quick Demo
|
||||
|
||||

|
||||
|
||||
## Questions & Bugs
|
||||
|
||||
Obviously NyoriE has implemented some easter eggs, *some people* call them "bugs". If you happen to discover one of these just make a new [Github Issue](https://github.com/Pyroxenium/Basalt/issues)
|
||||
|
||||
Additionally, if you have questions about Basalt or how to make use of it, feel free to create a new discussion on [Basalt's Discussion Board (Github)](https://github.com/Pyroxenium/Basalt/discussions), or ask in our [discord](https://discord.gg/yNNnmBVBpE).
|
||||
3
docs/docs1_6/_footer.md
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
|
||||
Thanks for checking out our wiki, join our discord for more help: [discord.gg/yM7kndJdJJ](discord.gg/yNNnmBVBpE)
|
||||
BIN
docs/docs1_6/_media/basaltPreview2.gif
Normal file
|
After Width: | Height: | Size: 3.1 MiB |
BIN
docs/docs1_6/_media/dynamic-frames.mp4
Normal file
BIN
docs/docs1_6/_media/frames-with-menubars.mp4
Normal file
BIN
docs/docs1_6/_media/frames-with-sidebar.mp4
Normal file
BIN
docs/docs1_6/_media/installer.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
docs/docs1_6/_media/logo.png
Normal file
|
After Width: | Height: | Size: 252 KiB |
BIN
docs/docs1_6/_media/pane-example-1.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
docs/docs1_6/_media/pane-example-2.png
Normal file
|
After Width: | Height: | Size: 717 B |
BIN
docs/docs1_6/_media/resizable-frames.mp4
Normal file
BIN
docs/docs1_6/_media/scrollable-frames.mp4
Normal file
4
docs/docs1_6/_navbar.md
Normal file
@@ -0,0 +1,4 @@
|
||||
- Getting Started
|
||||
- [Home](Home)
|
||||
- [How To](home/How-To)
|
||||
- [Download](home/download)
|
||||
32
docs/docs1_6/_sidebar.md
Normal file
@@ -0,0 +1,32 @@
|
||||
- About
|
||||
- [Home](home)
|
||||
- [How To](home/How-To)
|
||||
- [Download](home/download)
|
||||
- Objects
|
||||
- [Basalt](objects/Basalt.md)
|
||||
- [Object](objects/Object.md)
|
||||
- [Button](objects/Button.md)
|
||||
- [Checkbox](objects/Checkbox.md)
|
||||
- [Dropdown](objects/Dropdown.md)
|
||||
- [Frame](objects/Frame.md)
|
||||
- [Image](objects/Image.md)
|
||||
- [Input](objects/Input.md)
|
||||
- [Label](objects/Label.md)
|
||||
- [List](objects/List.md)
|
||||
- [Menubar](objects/Menubar.md)
|
||||
- [Pane](objects/Pane.md)
|
||||
- [Program](objects/Program.md)
|
||||
- [Progressbar](objects/Progressbar.md)
|
||||
- [Radio](objects/Radio.md)
|
||||
- [Scrollbar](objects/Scrollbar.md)
|
||||
- [Slider](objects/Slider.md)
|
||||
- [Textfield](objects/Textfield.md)
|
||||
- [Animation](objects/Animation.md)
|
||||
- [Thread](objects/Thread.md)
|
||||
- [Timer](objects/Timer.md)
|
||||
- Tips & Tricks
|
||||
- [Your Logic](tips/logic.md)
|
||||
- [Button coloring](tips/buttonColoring.md)
|
||||
- [Designing/Animating](tips/design.md)
|
||||
- [Dynamic Values](tips/dynamicvalues.md)
|
||||
- [XML](tips/xml.md)
|
||||
BIN
docs/docs1_6/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
docs/docs1_6/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
docs/docs1_6/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
61
docs/docs1_6/home/How-To.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# How-To
|
||||
|
||||
After downloading the project you can finally start creating your own program and use basalt. The first thing you want to use in your program is always:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
```
|
||||
|
||||
It doesn't matter if you're using the source folder or the minified/packed version of basalt. Both can be found by using require("basalt") without .lua.
|
||||
|
||||
Also to really run basalt you should use
|
||||
|
||||
```lua
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
somewhere on the bottom of your program. basalt.autoUpdate() starts the event listener and the draw handler.
|
||||
|
||||
## Example
|
||||
|
||||
Here is a fully working example of how a program could look like:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") --> Load the basalt framework into the variable called "basalt"
|
||||
|
||||
--> Now we want to create a base frame, we call the variable "main" - by default everything you create is visible. (you don't need to use :show())
|
||||
local main = basalt.createFrame()
|
||||
|
||||
local button = main:addButton() --> Here we add our first button
|
||||
button:setPosition(4, 4) -- of course we want to change the default position of our button
|
||||
button:setSize(16, 3) -- and the default size.
|
||||
button:setText("Click me!") --> This method displays what the text of our button should look like
|
||||
|
||||
local function buttonClick() --> Let us create a function we want to call when the button gets clicked
|
||||
basalt.debug("I got clicked!")
|
||||
end
|
||||
|
||||
-- Now we just need to register the function to the buttons onClick event handlers, this is how we can achieve that:
|
||||
button:onClick(buttonClick)
|
||||
|
||||
|
||||
basalt.autoUpdate() -- As soon as we call basalt.autoUpdate, the event and draw handlers will listen to any incomming events (and draw if necessary)
|
||||
```
|
||||
|
||||
If you're like us and strive for succinct and beautiful code, here is a cleaner implementation of the code above:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
local button = main --> Basalt returns an instance of the object on most methods, to make use of "call-chaining"
|
||||
:addButton() --> This is an example of call chaining
|
||||
:setPosition(4,4)
|
||||
:setText("Click me!")
|
||||
:onClick(
|
||||
function()
|
||||
basalt.debug("I got clicked!")
|
||||
end)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
36
docs/docs1_6/home/download.md
Normal file
@@ -0,0 +1,36 @@
|
||||
Basalt provides multiple unique versions. A source version, a minified version and a web version.
|
||||
|
||||
## Source
|
||||
|
||||
This version is, like the name already says, the source code of basalt. If you want to dig into the code, add additional content or just prefer to use the source, then you should aim for the source-version.
|
||||
|
||||
The following command allows you to download the source-version on your computer:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua source [foldername] [branch]`
|
||||
|
||||
The first optional argument is the folder name you wish that basalt should be installed into, by default the folder is called basalt.
|
||||
The second optional argument is the branch you want to use. If you don't know what this means please ignore it (the 2 options are master and dev)
|
||||
|
||||
## Minified / Packed
|
||||
|
||||
This version is the minified version, i also call it the packed version. There are 2 changes, the first one is that the code will be shown minified which makes the size much smaller, the second change is that you will recieve a file instead of a folder.
|
||||
|
||||
The following command allows you to download the packed-version on your computer:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua packed [filename] [branch]`
|
||||
|
||||
The first optional argument is the file name you wish that the installer should use, by default the file is called basalt.lua.
|
||||
The second optional argument is the branch you want to use. If you don't know what this means please ignore it (the 2 options are master and dev)
|
||||
|
||||
## Web
|
||||
|
||||
The web version is a special version, used if your goal is to keep your project's size as small as possible. I suggest you to use the web version only if you don't restart your program over and over again. For example if you designed your program to reboot after the user made a bad choice (leads into a error or something like that) it is better to use the minified/source version.
|
||||
|
||||
The following command allows you to download the web-version on your computer:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua web [version] [filename]`
|
||||
|
||||
By default the first argument is the latest version of basalt's releases. [Here](https://github.com/Pyroxenium/Basalt/tree/master/docs/versions) you can see which versions are available to use.
|
||||
For example: wget run https://basalt.madefor.cc/install.lua web basalt-1.6.3.lua - the second argument is just the file name, default is basaltWeb.lua.
|
||||
|
||||
Remember to rename `local basalt = require("basalt")` into `local basalt = require("basaltWeb")` if you want to use the web-version
|
||||
71
docs/docs1_6/index.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Basalt Documentation</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="Basalt is an easy-to-understand UI Framework designed for CC:Tweaked - a popular minecraft mod. ">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||
<!-- <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">-->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.28.0/themes/prism-tomorrow.min.css">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<style>
|
||||
:root {
|
||||
--theme-color: #16CC27;
|
||||
--mono-hue: 120;
|
||||
--mono-saturation: 1%;
|
||||
--mono-shade3: hsl(var(--mono-hue), var(--mono-saturation), 5%);
|
||||
--mono-shade2: hsl(var(--mono-hue), var(--mono-saturation), 6%);
|
||||
--mono-shade1: hsl(var(--mono-hue), var(--mono-saturation), 7%);
|
||||
--mono-base: hsl(var(--mono-hue), var(--mono-saturation), 20%);
|
||||
--mono-tint1: hsl(var(--mono-hue), var(--mono-saturation), 25%);
|
||||
--mono-tint2: hsl(var(--mono-hue), var(--mono-saturation), 30%);
|
||||
--mono-tint3: hsl(var(--mono-hue), var(--mono-saturation), 35%);
|
||||
--base-background-color: hsl(var(--mono-hue), var(--mono-saturation), 10%);
|
||||
--sidebar-nav-pagelink-background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='11.2' viewBox='0 0 7 11.2'%3E%3Cpath d='M1.5 1.5l4 4.1 -4 4.1' stroke-width='1.5' stroke='%23575d5e' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
|
||||
--sidebar-nav-pagelink-background-image--active: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11.2' height='7' viewBox='0 0 11.2 7'%3E%3Cpath d='M1.5 1.5l4.1 4 4.1-4' stroke-width='1.5' stroke='%23575d5e' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
|
||||
--sidebar-nav-pagelink-background-image--collapse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='7' height='11.2' viewBox='0 0 7 11.2'%3E%3Cpath d='M1.5 1.5l4 4.1 -4 4.1' stroke-width='1.5' stroke='%23575d5e' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
|
||||
--sidebar-nav-pagelink-background-image--loaded: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11.2' height='7' viewBox='0 0 11.2 7'%3E%3Cpath d='M1.5 1.5l4.1 4 4.1-4' stroke-width='1.5' stroke='%23575d5e' fill='none' stroke-linecap='square' stroke-linejoin='miter' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">Did you know: Basalt is a Pyroxene?></div>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-edit-on-github"></script>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
logo: '/_media/logo.png',
|
||||
loadNavbar: true,
|
||||
loadSidebar: true,
|
||||
loadFooter: '_footer.md',
|
||||
autoHeader: true,
|
||||
homepage: 'Home.md',
|
||||
name: 'Basalt',
|
||||
repo: 'https://github.com/Pyroxenium/Basalt',
|
||||
auto2top: true,
|
||||
search: {
|
||||
maxAge: 86400000, // Expiration time, the default one day
|
||||
paths: 'auto',
|
||||
placeholder: 'Type to search',
|
||||
noData: 'No Results!',
|
||||
// Headline depth, 1 - 6
|
||||
depth: 2,
|
||||
hideOtherSidebarContent: false, // whether or not to hide other sidebar content
|
||||
},
|
||||
plugins: [
|
||||
EditOnGithubPlugin.create("https://github.com/Pyroxenium/Basalt/blob/master/docs/", null, "Edit on Github")
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<!-- Docsify v4 -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/js/docsify-themeable.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1.28.0/components/prism-lua.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/@alertbox/docsify-footer/dist/docsify-footer.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
32
docs/docs1_6/objects/Animation.md
Normal file
@@ -0,0 +1,32 @@
|
||||
With animations, you can create a beautiful experience for users while interacting with your program.
|
||||
There are 2 types of animations, predefined animations and custom animations. By using add and wait you can create custom
|
||||
animations (calls). Pre-defined methods are for example move, offset, size, changeText,...
|
||||
|
||||
:setObject always sets the object on what pre-defined methods should apply on.
|
||||
|
||||
When calling a pre-defined animation it will check what is safed as object (:setObject) and will calculate the animation methods based on that which means you won't
|
||||
be able to change the object on the fly - you will always have to recreate the animation itself
|
||||
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|[add](objects/Animation/add.md)|Adds a new custom function to call at the current time
|
||||
|[wait](objects/Animation/wait.md)|Adds a amount to the animation time
|
||||
|[play](objects/Animation/play.md)|Plays the animation
|
||||
|[cancel](objects/Animation/cancel.md)|Cancels the animation
|
||||
|[addMode](objects/Animation/addMode.md)|Adds custom easings
|
||||
|[setMode](objects/Animation/setMode.md)|Changes the current easing-calculation
|
||||
|[setObject](objects/Animation/setObject.md)|Sets an object on which predefined animations should work on
|
||||
|[move](objects/Animation/move.md)|Predefined animation: moves the object to a new position
|
||||
|[offset](objects/Animation/offset.md)|Predefined animation: Changes the offset of that object
|
||||
|[size](objects/Animation/size.md)|Predefined animation: Changes the size on a object
|
||||
|[changeText](objects/Animation/changeText.md)|Predefined animation: Changes the text (object needs a setText method)
|
||||
|[changeTextColor](objects/Animation/changeTextColor.md)|Predefined animation: changes the foreground/textcolor on a object
|
||||
|[changeBackground](objects/Animation/changeBackground.md)|Predefined animation: changes the background on a object
|
||||
|
||||
# Events
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|[onStart](objects/Animation/onStart.md)|Gets called as soon as the animation is started
|
||||
|[onDone](objects/Animation/onDone.md)|Gets called as soon as the animation has finished
|
||||
17
docs/docs1_6/objects/Animation/add.md
Normal file
@@ -0,0 +1,17 @@
|
||||
## add
|
||||
Adds a new function to an animation
|
||||
#### Parameters:
|
||||
1. `function` The function containing animation logic
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
|
||||
#### Usage:
|
||||
* This will set the button position to 3,3, waits 1 second, then sets position to 4,4, waits 2 seconds, and then sets the position to 5,5
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton()
|
||||
local aAnimation = mainFrame:addAnimation():add(function() testButton:setPosition(3,3) end):wait(1):add(function() testButton:setPosition(1,1,"r") end):wait(2):add(function() testButton:setPosition(1,1,"r") end)
|
||||
aAnimation:play()
|
||||
```
|
||||
30
docs/docs1_6/objects/Animation/addMode.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## addMode
|
||||
Adds a new easing curve into the available easing list. Checkout the animation object if you want to know how this works.
|
||||
|
||||
#### Parameters:
|
||||
|
||||
1. `string` - The name of the curve you want to use.
|
||||
2. `functon` - The function to call
|
||||
|
||||
#### Returns:
|
||||
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
|
||||
* Creates a new curve
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton)
|
||||
|
||||
local function easeInBack(t) -- t is the time from 0 to 1
|
||||
local c1 = 1.70158;
|
||||
local c3 = c1 + 1
|
||||
return c3*t^3-c1*t^2
|
||||
end
|
||||
|
||||
aAnimation:addMode("coolEaseInBack", easeInBack)
|
||||
aAnimation:setMode("coolEaseInBack"):move(15,3,2):play()
|
||||
```
|
||||
15
docs/docs1_6/objects/Animation/cancel.md
Normal file
@@ -0,0 +1,15 @@
|
||||
## cancel
|
||||
Cancels the animation
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton()
|
||||
local aAnimation = mainFrame:addAnimation():add(function() testButton:setBackground(colors.black) end):wait(1):add(function() aAnimation:cancel() end):wait(1):add(function() testButton:setBackground(colors.lightGray) end)
|
||||
|
||||
aAnimation:play()
|
||||
```
|
||||
28
docs/docs1_6/objects/Animation/changeBackground.md
Normal file
@@ -0,0 +1,28 @@
|
||||
## changeBackground
|
||||
Changes the background color while the animation is running
|
||||
|
||||
#### Parameters:
|
||||
1. `number` duration in seconds
|
||||
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
|
||||
3. `...` multiple color numbers - example: colors.red, colors.yellow, colors.green
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor(2, 0, colors.red, colors.yellow, colors.green):play()
|
||||
```
|
||||
```xml
|
||||
<animation object="buttonToAnimate" play="true">
|
||||
<background>
|
||||
<color>red</color>
|
||||
<color>yellow</color>
|
||||
<color>green</color>
|
||||
<duration>2</duration>
|
||||
</background>
|
||||
</animation>
|
||||
```
|
||||
30
docs/docs1_6/objects/Animation/changeText.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## changeText
|
||||
Changes the text while animation is running
|
||||
|
||||
#### Parameters:
|
||||
1. `table` multiple text strings - example: {"i", "am", "groot"}
|
||||
1. `number` duration in seconds
|
||||
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
|
||||
3. `...` multiple text strings - example: "i", "am", "groot"
|
||||
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeText(2, 0, "i", "am", "groot"):play()
|
||||
```
|
||||
```xml
|
||||
<animation object="buttonToAnimate" play="true">
|
||||
<text>
|
||||
<text>i</text>
|
||||
<text>am</text>
|
||||
<text>groot</text>
|
||||
<duration>2</duration>
|
||||
</text>
|
||||
</animation>
|
||||
```
|
||||
28
docs/docs1_6/objects/Animation/changeTextColor.md
Normal file
@@ -0,0 +1,28 @@
|
||||
## changeTextColor
|
||||
Changes the text color while the animation is running
|
||||
|
||||
#### Parameters:
|
||||
1. `number` duration in seconds
|
||||
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
|
||||
1. `...` multiple color numbers - example: colors.red, colors.yellow, colors.green
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor(2, 0, colors.red, colors.yellow, colors.green):play()
|
||||
```
|
||||
```xml
|
||||
<animation object="buttonToAnimate" play="true">
|
||||
<textColor>
|
||||
<color>red</color>
|
||||
<color>yellow</color>
|
||||
<color>green</color>
|
||||
<duration>2</duration>
|
||||
</textColor>
|
||||
</animation>
|
||||
```
|
||||
25
docs/docs1_6/objects/Animation/move.md
Normal file
@@ -0,0 +1,25 @@
|
||||
## move
|
||||
Moves the object which got defined by setObject
|
||||
|
||||
#### Parameters:
|
||||
1. `number` x coordinate
|
||||
2. `number` y coordinate
|
||||
3. `number` duration in seconds
|
||||
4. `number` time - time when this part should begin (offset to when the animation starts - default 0)
|
||||
5. `table` object - optional, you could also define the object here
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
* Takes 2 seconds to move the object from its current position to x15 y3
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):move(15,3,2):play()
|
||||
```
|
||||
```xml
|
||||
<animation object="buttonToAnimate" play="true">
|
||||
<move><x>15</x><y>6</y><duration>2</duration></move>
|
||||
</animation>
|
||||
```
|
||||
25
docs/docs1_6/objects/Animation/offset.md
Normal file
@@ -0,0 +1,25 @@
|
||||
## offset
|
||||
Changes the offset on the object which got defined by setObject
|
||||
|
||||
#### Parameters:
|
||||
1. `number` x offset
|
||||
2. `number` y offset
|
||||
3. `number` duration in seconds
|
||||
4. `number` time - time when this part should begin (offset to when the animation starts - default 0)
|
||||
5. `table` object - optional, you could also define the object here
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local subFrame = mainFrame:addFrame("frameToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(subFrame):offset(1,12,1):play()
|
||||
```
|
||||
```xml
|
||||
<animation object="frameToAnimate" play="true">
|
||||
<offset><x>1</x><y>12</y><duration>1</duration></offset>
|
||||
</animation>
|
||||
```
|
||||
35
docs/docs1_6/objects/Animation/onDone.md
Normal file
@@ -0,0 +1,35 @@
|
||||
## onDone
|
||||
`onDone(self)`<br>
|
||||
This is a event which gets fired as soon as the animation has finished.
|
||||
|
||||
```lua
|
||||
local basalt = require("Basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor({colors.red, colors.yellow, colors.green}, 2):play()
|
||||
aAnimation:onDone(function()
|
||||
basalt.debug("The animation is done")
|
||||
end)
|
||||
```
|
||||
|
||||
In XML you are also able to queue multiple animations, like this:
|
||||
|
||||
```xml
|
||||
<animation id="anim2" object="buttonToAnimate">
|
||||
<textColor>
|
||||
<color>red</color>
|
||||
<color>yellow</color>
|
||||
<color>green</color>
|
||||
<duration>2</duration>
|
||||
</textColor>
|
||||
</animation>
|
||||
<animation onDone="#anim2" object="buttonToAnimate" play="true">
|
||||
<background>
|
||||
<color>red</color>
|
||||
<color>yellow</color>
|
||||
<color>green</color>
|
||||
<duration>2</duration>
|
||||
</background>
|
||||
</animation>
|
||||
```
|
||||
16
docs/docs1_6/objects/Animation/onStart.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## onStart
|
||||
`onStart(self)`<br>
|
||||
This is a event which gets fired as soon as the animation is started.
|
||||
|
||||
```lua
|
||||
local basalt = require("Basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor({colors.red, colors.yellow, colors.green}, 2)
|
||||
aAnimation:onStart(function()
|
||||
basalt.debug("The animation is started")
|
||||
end)
|
||||
|
||||
aAnimation:play()
|
||||
```
|
||||
16
docs/docs1_6/objects/Animation/play.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## play
|
||||
Plays the animation
|
||||
#### Parameters:
|
||||
1. `boolean` Whether it will loop forever, will most likely be replaced with a count in the future
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton()
|
||||
local aAnimation = mainFrame:addAnimation():add(function() testButton:setBackground(colors.black) end):wait(1):add(function() testButton:setBackground(colors.gray) end):wait(1):add(function() testButton:setBackground(colors.lightGray) end)
|
||||
|
||||
aAnimation:play() -- changes the background color of that button from black to gray and then to lightGray
|
||||
```
|
||||
36
docs/docs1_6/objects/Animation/setMode.md
Normal file
@@ -0,0 +1,36 @@
|
||||
## setMode
|
||||
Changes the easing curve. If you want to test them, here is a interesting website: https://easings.co
|
||||
|
||||
#### Parameters:
|
||||
1. `string` - The name of the curve you want to use.
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
* Takes 2 seconds to move the object from its current position to x15 y3
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):setMode("easeInBounce"):move(15,3,2):play()
|
||||
```
|
||||
|
||||
## Easing Curve List
|
||||
|
||||
Here is a list of all available easing curves:
|
||||
|
||||
| | | |
|
||||
|---|---|---|
|
||||
|linear||
|
||||
|easIn|easeOut|easeInOut
|
||||
|easeInSine|easeOutSine|easeInOutSine
|
||||
|easeInBack|easeOutBack|easeInOutBack
|
||||
|easeInCubic|easeOutCubic|easeInOutCubic
|
||||
|easeInElastic|easeOutElastic|easeInOutElastic
|
||||
|easeInExpo|easeOutExpo|easeInOutExpo
|
||||
|easeInBack|easeOutBack|easeInOutBack
|
||||
|easeInQuad|easeOutQuad|easeInOutQuad
|
||||
|easeInQuint|easeOutQuint|easeInOutQuint
|
||||
|easeInQuart|easeOutQuart|easeInOutQuart
|
||||
|easeInCirc|easeOutCirc|easeInOutCirc
|
||||
|easeInBounce|easeOutBounce|easeInOutBounce
|
||||