1.7 stuff

The master branch was reverted to 1.7 because it was very unstable (bugs and stuff that wasn't mentioned on the documentation page yet) - features will come back with 2.0

- fixed debug window
- fixed flexbox not sending drag events to it's children

- small docs updates for 1.7
- removed the examples because the are outdated
This commit is contained in:
Robert Jelic
2024-03-13 09:57:07 +01:00
parent 33753f6d8f
commit 8168fa4465
75 changed files with 2839 additions and 2844 deletions

View File

@@ -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)
@@ -40,27 +42,33 @@ return function(drawTerm)
if #t == #fg and #t == #bg then
if y >= 1 and y <= height then
if x + #t > 0 and x <= width then
local startN = x < 1 and 1 - x + 1 or 1
local endN = x + #t > width and width - x + 1 or #t
local newCacheT, newCacheFG, newCacheBG
local oldCacheT, oldCacheFG, oldCacheBG = cacheT[y], cacheFG[y], cacheBG[y]
local newCacheT = sub(oldCacheT, 1, x - 1) .. sub(t, startN, endN)
local newCacheFG = sub(oldCacheFG, 1, x - 1) .. sub(fg, startN, endN)
local newCacheBG = sub(oldCacheBG, 1, x - 1) .. sub(bg, startN, endN)
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
end
end
end
local function setText(x, y, t)
if y >= 1 and y <= height then
if x + #t > 0 and x <= width then
@@ -86,7 +94,7 @@ return function(drawTerm)
end
end
local function setBg(x, y, bg)
local function setBG(x, y, bg)
if y >= 1 and y <= height then
if x + #bg > 0 and x <= width then
local newCacheBG
@@ -111,7 +119,7 @@ return function(drawTerm)
end
end
local function setFg(x, y, fg)
local function setFG(x, y, fg)
if y >= 1 and y <= height then
if x + #fg > 0 and x <= width then
local newCacheFG
@@ -136,6 +144,32 @@ return function(drawTerm)
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
local w = #colorStr
local emptyLine = rep(" ", w)
local text = sub(cacheT[y], x, w)
blit(x, y, text, colorStr, emptyLine)
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]]
local drawHelper = {
setSize = function(w, h)
width, height = w, h
@@ -146,17 +180,17 @@ return function(drawTerm)
mirrorTerm = mirror
end,
setBg = function(x, y, colorStr)
setBg(x, y, colorStr)
setBG = function(x, y, colorStr)
setBG(x, y, colorStr)
end,
setText = function(x, y, text)
setText(x, y, text)
end,
setFg = function(x, y, colorStr)
setFg(x, y, colorStr)
end,
setFG = function(x, y, colorStr)
setFG(x, y, colorStr)
end;
blit = function(x, y, t, fg, bg)
blit(x, y, t, fg, bg)
@@ -165,13 +199,13 @@ return function(drawTerm)
drawBackgroundBox = function(x, y, width, height, bgCol)
local colorStr = rep(tHex[bgCol], width)
for n = 1, height do
setBg(x, y + (n - 1), colorStr)
setBG(x, y + (n - 1), colorStr)
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), colorStr)
setFG(x, y + (n - 1), colorStr)
end
end,
drawTextBox = function(x, y, width, height, symbol)

View File

@@ -1,5 +1,3 @@
local tableCount = require("utils").tableCount
return function()
local events = {}
@@ -20,7 +18,7 @@ return function()
end,
getEventCount = function(self, _event)
return _event~=nil and events[_event]~=nil and tableCount(events[_event]) or tableCount(events)
return events[_event]~=nil and #events[_event] or 0
end,
getEvents = function(self)

View File

@@ -1,143 +1,180 @@
-- Right now this doesn't support scroll(n)
-- Because this lbirary is mainly made for basalt - it doesn't need scroll support, maybe i will add it in the future
local max, sub = math.max,string.sub
local tHex = {
[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",
}
return function(monitorNames)
local type,len,rep,sub = type,string.len,string.rep,string.sub
return function (monitorNames)
local monitors = {}
local multiMonWidth, multiMonHeight = 0,0
local multiMonX, multiMonY = 1, 1
local bgColor, txtColor = colors.black, colors.white
for k,v in pairs(monitorNames) do
monitors[k] = {}
for k,v in pairs(monitorNames)do
monitors[k] = {}
for a,b in pairs(v)do
monitors[k][a] = {name=b, monitor=peripheral.wrap(b)}
end
end
local function calculateSize()
local absWidth, absHeight = 0,0
local height = 0
for _,v in pairs(monitors)do
local width = 0
for _,b in pairs(v)do
local w, h = b.monitor.getSize()
width = width + w
height = max(height, h)
local mon = peripheral.wrap(b)
if(mon==nil)then
error("Unable to find monitor "..b)
end
absWidth = max(absWidth, width)
absHeight = absHeight + height
height = 0
monitors[k][a] = mon
monitors[k][a].name = b
end
multiMonWidth, multiMonHeight = absWidth, absHeight
end
calculateSize()
local function getMonitorFromPosition(x, y)
local absWidth, absHeight = 0,0
local height = 0
local x,y,monX,monY,monW,monH,w,h = 1,1,1,1,0,0,0,0
local blink,scale = false,1
local fg,bg = colors.white,colors.black
local function calcSize()
local maxW,maxH = 0,0
for k,v in pairs(monitors)do
local width = 0
local _maxW,_maxH = 0,0
for a,b in pairs(v)do
local w, h = b.monitor.getSize()
width = width + w
height = max(height, h)
if(x >= absWidth and x <= absWidth + w and y >= absHeight and y <= absHeight + h)then
return b.monitor, a, k
end
absWidth = absWidth + w
local nw,nh = b.getSize()
_maxW = _maxW + nw
_maxH = nh > _maxH and nh or _maxH
end
absWidth = 0
absHeight = absHeight + height
height = 0
maxW = maxW > _maxW and maxW or _maxW
maxH = maxH + _maxH
end
w,h = maxW,maxH
end
calcSize()
local function getRelativeCursorPos(mon, x, y)
local absWidth, absHeight = 0,0
local height = 0
local function calcPosition()
local relY = 0
local mX,mY = 0,0
for k,v in pairs(monitors)do
local width = 0
local relX = 0
local _mh = 0
for a,b in pairs(v)do
local w, h = b.monitor.getSize()
width = width + w
height = max(height, h)
if(b.monitor == mon)then
return x - absWidth, y - absHeight
local mw,mh = b.getSize()
if(x-relX>=1)and(x-relX<=mw)then
mX = a
end
absWidth = absWidth + w
b.setCursorPos(x-relX, y-relY)
relX = relX + mw
if(_mh<mh)then _mh = mh end
end
absWidth = 0
absHeight = absHeight + height
height = 0
if(y-relY>=1)and(y-relY<=_mh)then
mY = k
end
relY = relY + _mh
end
monX,monY = mX,mY
end
calcPosition()
local function blit(text, fgColor, bgColor)
local mon, x, y = getMonitorFromPosition(multiMonX, multiMonY)
for k, v in pairs(monitors[y])do
if(k >= x)then
local xCursor, yCursor = getRelativeCursorPos(v.monitor, multiMonX, multiMonY)
local w, h = v.monitor.getSize()
local textToScreen = sub(text, 1, w)
text = sub(text, w+1)
local fgColorToScreen = sub(fgColor, 1, w)
fgColor = sub(fgColor, w+1)
local bgColorToScreen = sub(bgColor, 1, w)
bgColor = sub(bgColor, w+1)
v.monitor.setCursorPos(xCursor, yCursor)
v.monitor.blit(textToScreen, fgColorToScreen, bgColorToScreen)
multiMonX = multiMonX + w
local function call(f, ...)
local t = {...}
return function()
for k,v in pairs(monitors)do
for a,b in pairs(v)do
b[f](table.unpack(t))
end
end
end
end
return {
getSize = function()
return multiMonWidth, multiMonHeight
end,
local function cursorBlink()
call("setCursorBlink", false)()
if not(blink)then return end
if(monitors[monY]==nil)then return end
local mon = monitors[monY][monX]
if(mon==nil)then return end
mon.setCursorBlink(blink)
end
blit = blit,
getCursorPos = function()
return multiMonX, multiMonY
end,
setCursorPos = function(x, y)
multiMonX, multiMonY = x, y
for _,v in pairs(monitors)do
for _,b in pairs(v)do
local xCursor, yCursor = getRelativeCursorPos(b.monitor, multiMonX, multiMonY)
b.monitor.setCursorPos(xCursor, yCursor)
end
local function blit(text, tCol, bCol)
if(monitors[monY]==nil)then return end
local mon = monitors[monY][monX]
if(mon==nil)then return end
mon.blit(text, tCol, bCol)
local mW, mH = mon.getSize()
if(len(text)+x>mW)then
local monRight = monitors[monY][monX+1]
if(monRight~=nil)then
monRight.blit(text, tCol, bCol)
monX = monX + 1
x = x + len(text)
end
end
calcPosition()
end
return {
clear = call("clear"),
setCursorBlink = function(_blink)
blink = _blink
cursorBlink()
end,
getCursorBlink = function()
local mon = getMonitorFromPosition(multiMonX, multiMonY)
return mon.getCursorBlink()
return blink
end,
setCursorBlink = function(blink)
for _,v in pairs(monitors)do
for _,b in pairs(v)do
b.monitor.setCursorBlink(blink)
end
end
getCursorPos = function()
return x, y
end,
setCursorPos = function(newX,newY)
x, y = newX, newY
calcPosition()
cursorBlink()
end,
setBackgroundColor = function(color)
bgColor = color
setTextScale = function(_scale)
call("setTextScale", _scale)()
calcSize()
calcPosition()
scale = _scale
end,
getBackgroundColor = function()
return bgColor
getTextScale = function()
return scale
end,
setTextColor = function(color)
txtColor = color
blit = function(text,fgCol,bgCol)
blit(text,fgCol,bgCol)
end,
getTextColor = function()
return txtColor
write = function(text)
text = tostring(text)
local l = len(text)
blit(text, rep(tHex[fg], l), rep(tHex[bg], l))
end,
getSize = function()
return w,h
end,
setBackgroundColor = function(col)
call("setBackgroundColor", col)()
bg = col
end,
setTextColor = function(col)
call("setTextColor", col)()
fg = col
end,
calculateClick = function(name, xClick, yClick)
@@ -146,7 +183,7 @@ return function(monitorNames)
local relX = 0
local maxY = 0
for a,b in pairs(v)do
local wM,hM = b.monitor.getSize()
local wM,hM = b.getSize()
if(b.name==name)then
return xClick + relX, yClick + relY
end
@@ -157,5 +194,6 @@ return function(monitorNames)
end
return xClick, yClick
end,
}
}
end

View File

@@ -27,29 +27,24 @@ local function loadBBFAsBimg(path)
end
local function loadImage(path, binaryMode)
--Loads the image with the right loader, returns error if the file type is unknown.
if(sub(path, -5) == ".bimg")then
local function loadImage(path, f, binaryMode)
if(sub(path, -4) == ".bimg")then
return loadBIMG(path, binaryMode)
elseif(sub(path, -4) == ".bbf")then
return loadBBF(path)
elseif(sub(path, -4) == ".nfp")then
return loadNFP(path)
elseif(sub(path, -3) == ".bbf")then
return loadBBF(path, binaryMode)
else
error("Unknown file type")
return loadNFP(path, binaryMode)
end
-- ...
end
local function loadImageAsBimg(path, binaryMode)
--Loads the image with the right Bimg loader, returns error if the file type is unknown.
if(sub(path, -5) == ".bimg")then
return loadBIMG(path, binaryMode)
elseif(sub(path, -4) == ".bbf")then
local function loadImageAsBimg(path)
if(path:find(".bimg"))then
return loadBIMG(path)
elseif(path:find(".bbf"))then
return loadBBFAsBimg(path)
elseif(sub(path, -4) == ".nfp")then
return loadNFPAsBimg(path)
else
error("Unknown file type")
return loadNFPAsBimg(path)
end
end

View File

@@ -6,7 +6,6 @@ local newPackage = dofile("rom/modules/main/cc/require.lua").make
function process:new(path, window, newEnv, ...)
local args = {...}
newEnv = newEnv or {}
local newP = setmetatable({ path = path }, { __index = self })
newP.window = window
window.current = term.current

View File

@@ -167,42 +167,34 @@ local function wrapRichText(text, width)
elseif entry.bgColor then
currentBgColor = entry.bgColor
else
local paragraphs = splitString(entry.text, "\n")
for p, paragraph in ipairs(paragraphs) do
local words = splitString(paragraph, " ")
local words = splitString(entry.text, " ")
for i, word in ipairs(words) do
local wordLength = #word
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
if i > 1 then
if x + 1 + wordLength <= width then
addFormattedEntry({ text = " " })
x = x + 1
else
x = 1
y = y + 1
end
end
if p ~= #paragraphs then
x = 1
y = y + 1
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
@@ -217,7 +209,6 @@ local function wrapRichText(text, width)
end
return {
@@ -327,13 +318,10 @@ wrapRichText = wrapRichText,
--- @param height number Height
writeWrappedText = function(obj, x, y, text, width, height)
local wrapped = wrapRichText(text, width)
for k,v in pairs(wrapped)do
for _,v in pairs(wrapped)do
if(v.y>height)then
break
end
if(k==#wrapped)and(v=="")then
break
end
if(v.text~=nil)then
obj:addText(x+v.x-1, y+v.y-1, v.text)
end
@@ -352,4 +340,4 @@ 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
}
}

View File

@@ -74,4 +74,4 @@ local XMLParser = {
end
}
return XMLParser
return XMLParser

View File

@@ -9,18 +9,16 @@ local wrapText = utils.wrapText
local count = utils.tableCount
local moveThrottle = 300
local dragThrottle = 0
local renderingThrottle = 50
local renderingThrottle = 0
local newObjects = {}
local mousePos = {0, 0}
local baseTerm = term.current()
local version = "1.7.1"
local version = "1.7.0"
local projectDirectory = fs.getDir(table.pack(...)[2] or "")
local activeKey, frames, monFrames, variables, schedules = {}, {}, {}, {}, {}
local mainFrame, activeFrame, focusedObject, updaterActive
local renderingTimer = nil
local basalt = {}
@@ -84,39 +82,11 @@ local createObject = function(basalt, objectName, id)
return getObject(objectName)(id, basalt)
end
local setRenderingThrottle = function(amount)
if(amount<=0)then
renderingThrottle = 0
else
renderingTimer = nil
renderingThrottle = amount
end
end
local getRenderingThrottle = function()
return renderingThrottle
end
local debugTimer = 0
local startTimer = function()
debugTimer = os.clock("utc")
basalt.log("Timer started at "..debugTimer.." seconds")
end
local endTimer = function()
local endT = os.clock("utc") - debugTimer
basalt.log("Timer ended at "..os.clock().." seconds")
basalt.log("Timer ended after "..endT.." seconds")
end
local bInstance = {
getDynamicValueEventSetting = function()
return basalt.dynamicValueEvents
end,
getRenderingThrottle = getRenderingThrottle,
setRenderingThrottle = setRenderingThrottle,
getMainFrame = function()
return mainFrame
end,
@@ -269,14 +239,15 @@ local function mouseDragEvent(_, b, x, y)
end
local renderingTimer = nil
local function renderingUpdateTimer()
renderingTimer = nil
drawFrames()
drawFrames()
end
local function renderingUpdateEvent(timer)
if(renderingThrottle<50)then
drawFrames()
if(renderingThrottle<50)then
drawFrames()
else
if(renderingTimer==nil)then
renderingTimer = os.startTimer(renderingThrottle/1000)
@@ -298,10 +269,6 @@ local function basaltUpdateEvent(event, ...)
}
local mouseEvent = mouseEvents[event]
if(mouseEvent~=nil)then
local mouseX, mouseY = a[3], a[4]
if(mouseX~=nil and mouseY~=nil)then
mousePos = {mouseX, mouseY}
end
mouseEvent(mainFrame, ...)
handleSchedules(event, ...)
renderingUpdateEvent()
@@ -412,9 +379,9 @@ local function InitializeBasalt()
loadedPlugins = true
end
end
InitializeBasalt()
local function createFrame(name)
InitializeBasalt()
for _, v in pairs(frames) do
if (v:getName() == name) then
return nil
@@ -466,9 +433,6 @@ basalt = {
end
return objectNames
end,
getMousePosition = function()
return mousePos[1], mousePos[2]
end,
setVariable = setVariable,
getVariable = getVariable,
@@ -503,9 +467,14 @@ basalt = {
return false
end,
setRenderingThrottle = setRenderingThrottle,
getRenderingThrottle = getRenderingThrottle,
setRenderingThrottle = function(amount)
if(amount<=0)then
renderingThrottle = 0
else
renderingTimer = nil
renderingThrottle = amount
end
end,
setMouseDragThrottle = function(amount)
if(amount<=0)then
@@ -554,7 +523,7 @@ basalt = {
getFrame = function(name)
for _, value in pairs(frames) do
if (value:getName() == name) then
if (value.name == name) then
return value
end
end
@@ -590,6 +559,7 @@ basalt = {
createFrame = createFrame,
addMonitor = function(name)
InitializeBasalt()
for _, v in pairs(frames) do
if (v:getName() == name) then
return nil
@@ -602,7 +572,7 @@ basalt = {
table.insert(monFrames, newFrame)
return newFrame
end,
removeFrame = function(name)
frames[name] = nil
end,
@@ -630,4 +600,4 @@ if(basaltPlugins~=nil)then
end
end
return basalt
return basalt

View File

@@ -5,7 +5,9 @@ local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("Container")(name, basalt)
base:setType("BaseFrame")
local objectType = "BaseFrame"
local xOffset, yOffset = 0, 0
local colorTheme = {}
@@ -16,38 +18,58 @@ return function(name, basalt)
local xCursor, yCursor, cursorBlink, cursorColor = 1, 1, false, colors.white
base:addProperty("XOffset", "number", 0)
base:addProperty("YOffset", "number", 0)
base:combineProperty("Offset", "XOffset", "YOffset")
base:addProperty("Term", "table", nil, false, function(self, value)
termObject = value
basaltDraw = nil
if(value~=nil)then
basaltDraw = drawSystem(value)
base:setSize(value.getSize())
end
end)
base:setSize(termObject.getSize())
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,
setPalette = function(self, col, ...)
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,
getXOffset = function(self)
return xOffset
end,
setXOffset = function(self, newXOffset)
return self:setOffset(newXOffset, nil)
end,
getYOffset = function(self)
return yOffset
end,
setYOffset = function(self, newYOffset)
return self:setOffset(nil, newYOffset)
end,
setPalette = function(self, col, ...)
if(self==basalt.getActiveFrame())then
if(type(col)=="string")then
col = colors[col]
colorTheme[math.log(col, 2)] = ...
termObject.setPaletteColor(col, ...)
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(2 ^ k, v)
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
else
local r,g,b = table.unpack(v)
termObject.setPaletteColor(2 ^ k, r,g,b)
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
end
end
end
@@ -61,6 +83,18 @@ return function(name, basalt)
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)
@@ -71,10 +105,10 @@ return function(name, basalt)
end
for k,v in pairs(colorTheme)do
if(type(v)=="number")then
termObject.setPaletteColor(k ^ 2, v)
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
else
local r,g,b = table.unpack(v)
termObject.setPaletteColor(k ^ 2, r,g,b)
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
end
end
basalt.setMainFrame(self)
@@ -116,6 +150,20 @@ return function(name, basalt)
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()
@@ -149,7 +197,7 @@ return function(name, basalt)
end,
}
for _,v in pairs({mouse_click={"mouseHandler", true},mouse_up={"mouseUpHandler", false},mouse_drag={"dragHandler", false},mouse_scroll={"scrollHandler", true},mouse_hover={"hoverHandler", false}})do
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)
@@ -157,18 +205,17 @@ return function(name, basalt)
end
end
for _,v in pairs({"drawBackgroundBox", "drawForegroundBox", "drawTextBox"})do
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()
if(height==nil)then return end
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 _,v in pairs({"setBg", "setFg", "setText"}) do
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()

View File

@@ -4,29 +4,62 @@ local tHex = require("tHex")
return function(name, basalt)
-- Button
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Button")
local objectType = "Button"
local textHorizontalAlign = "center"
local textVerticalAlign = "center"
local text = "Button"
base:setSize(12, 3)
base:setZ(5)
base:addProperty("text", "string", "Button")
base:addProperty("textHorizontalAlign", {"left", "center", "right"}, "center")
base:addProperty("textVerticalAlign", {"left", "center", "right"}, "center")
base:combineProperty("textAlign", "textHorizontalAlign", "textVerticalAlign")
base:setZIndex(5)
local object = {
getType = function(self)
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,
getHorizontalAlign = function(self)
return textHorizontalAlign
end,
setHorizontalAlign = function(self, pos)
textHorizontalAlign = pos
self:updateDraw()
return self
end,
getVerticalAlign = function(self)
return textVerticalAlign
end,
setVerticalAlign = function(self, pos)
textVerticalAlign = pos
self:updateDraw()
return self
end,
getText = function(self)
return text
end,
setText = function(self, newText)
text = newText
self:updateDraw()
return self
end,
draw = function(self)
base.draw(self)
self:addDraw("button", function()
local w,h = self:getSize()
local textHorizontalAlign = self:getTextHorizontalAlign()
local textVerticalAlign = self:getTextVerticalAlign()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
local text = self:getText()
local xOffset
if(textHorizontalAlign=="center")then
xOffset = math.floor((w - text:len()) / 2)
@@ -35,7 +68,7 @@ return function(name, basalt)
end
self:addText(xOffset + 1, verticalAlign, text)
self:addFg(xOffset + 1, verticalAlign, tHex[self:getForeground() or colors.white]:rep(text:len()))
self:addFG(xOffset + 1, verticalAlign, tHex[self:getForeground() or colors.white]:rep(text:len()))
end)
end,
}

View File

@@ -1,21 +1,26 @@
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("ChangeableObject")
base:addProperty("ChangeHandler", "function", nil)
base:addProperty("Value", "any", nil, false, function(self, value)
local _value = self:getValue()
if (value ~= _value) then
local valueChangedHandler = self:getChangeHandler()
if(valueChangedHandler~=nil)then
valueChangedHandler(self, value)
end
self:sendEvent("value_changed", value)
end
return value
end)
-- 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
@@ -24,6 +29,10 @@ return function(name, basalt)
end
return self
end,
valueChangedHandler = function(self)
self:sendEvent("value_changed", value)
end,
}
object.__index = object

View File

@@ -4,25 +4,72 @@ local tHex = require("tHex")
return function(name, basalt)
-- Checkbox
local base = basalt.getObject("ChangeableObject")(name, basalt)
base:setType("Checkbox")
local objectType = "Checkbox"
base:setZ(5)
base:setZIndex(5)
base:setValue(false)
base:setSize(1, 1)
base:addProperty("activeSymbol", "char", "\42")
base:addProperty("inactiveSymbol", "char", " ")
base:combineProperty("Symbol", "activeSymbol", "inactiveSymbol")
base:addProperty("text", "string", "")
base:addProperty("textPosition", {"left", "right"}, "right")
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,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
setSymbol = function(self, sym, inactive)
symbol = sym or symbol
inactiveSymbol = inactive or inactiveSymbol
self:updateDraw()
return self
end,
setActiveSymbol = function(self, sym)
return self:setSymbol(sym, nil)
end,
setInactiveSymbol = function(self, inactive)
return self:setSymbol(nil, inactive)
end,
getSymbol = function(self)
return symbol, inactiveSymbol
end,
getActiveSymbol = function(self)
return symbol
end,
getInactiveSymbol = function(self)
return inactiveSymbol
end,
setText = function(self, _text)
text = _text
return self
end,
getText = function(self)
return text
end,
setTextPosition = function(self, pos)
textPos = pos or textPos
return self
end,
getTextPosition = function(self)
return textPos
end,
setChecked = base.setValue,
getChecked = base.getValue,
@@ -45,13 +92,10 @@ return function(name, basalt)
draw = function(self)
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()
local symbol = self:getActiveSymbol()
local inactiveSymbol = self:getInactiveSymbol()
local text = self:getText()
local textPos = self:getTextPosition()
if (self:getValue()) then
self:addBlit(1, verticalAlign, utils.getTextHorizontalAlign(symbol, w, "center"), tHex[fg], tHex[bg])
else

View File

@@ -1,10 +1,9 @@
local utils = require("utils")
local tableCount = utils.tableCount
local rpairs = utils.rpairs
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Container")
local objectType = "Container"
local children = {}
@@ -67,7 +66,7 @@ return function(name, basalt)
return
end
objId = objId + 1
local zIndex = element:getZ()
local zIndex = element:getZIndex()
table.insert(children, {element = element, zIndex = zIndex, objId = objId})
sorted = false
element:setParent(self, true)
@@ -96,11 +95,11 @@ return function(name, basalt)
for i, v in ipairs(children) do
if v.element == element then
table.remove(children, i)
self:removeEvents(element)
sorted = false
return true
end
end
self:removeEvents(element)
sorted = false
end
local function removeChildren(self)
@@ -112,7 +111,6 @@ return function(name, basalt)
evId = 0
focusedChild = nil
parent:removeEvents(self)
self:updateEvents()
end
local function updateZIndex(self, element, newZ)
@@ -147,10 +145,7 @@ return function(name, basalt)
end
if(tableCount(events[a])<=0)then
if(parent~=nil)then
if(self:getEventSystem().getEventCount(a)<=0)then
parent:removeEvent(a, self)
self:updateEvents()
end
parent:removeEvent(a, self)
end
end
end
@@ -172,7 +167,7 @@ return function(name, basalt)
if (getEvent(self, event, element:getName()) ~= nil) then
return
end
local zIndex = element:getZ()
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})
@@ -200,10 +195,18 @@ return function(name, basalt)
end
container = {
getBase = function(self)
return base
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")
@@ -305,23 +308,6 @@ return function(name, basalt)
getFocused = function(self)
return focusedChild
end,
getChildrenAt = function(self, x, y)
local results = {}
for _, child in rpairs(children) do
if(child.element.getPosition~=nil)and(child.element.getSize~=nil)then
local xObj, yObj = child.element:getPosition()
local wObj, hObj = child.element:getSize()
local isVisible = child.element:getVisible()
if(isVisible)then
if (x >= xObj and x <= xObj + wObj - 1 and y >= yObj and y <= yObj + hObj - 1) then
table.insert(results, child.element)
end
end
end
end
return results
end,
getChild = getChild,
getChildren = getChildren,
@@ -398,7 +384,7 @@ return function(name, basalt)
xO, yO = 0, 0
end
end
if (obj.element[v[1]](obj.element, btn, x+xO, y+yO, ...)) then
if (obj.element[v[1]](obj.element, btn, x+xO, y+yO, ...)) then
return true
end
end

View File

@@ -3,21 +3,31 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("List")(name, basalt)
base:setType("Dropdown")
local objectType = "Dropdown"
base:setSize(12, 1)
base:setZ(6)
base:setZIndex(6)
base:addProperty("Align", {"left", "center", "right"}, "left")
base:addProperty("AutoSize", "boolean", true)
base:addProperty("ClosedSymbol", "char", "\16")
base:addProperty("OpenedSymbol", "char", "\31")
base:addProperty("Opened", "boolean", false)
base:addProperty("DropdownWidth", "number", 12)
base:addProperty("DropdownHeight", "number", 0)
base:combineProperty("DropdownSize", "DropdownWidth", "DropdownHeight")
local selectionColorActive = true
local align = "left"
local yOffset = 0
local dropdownW = 0
local dropdownH = 0
local autoSize = true
local closedSymbol = "\16"
local openedSymbol = "\31"
local isOpened = false
local object = {
getType = function(self)
return objectType
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)
@@ -25,49 +35,84 @@ return function(name, basalt)
self:listenEvent("mouse_drag", self)
end,
setOffset = function(self, yOff)
yOffset = yOff
self:updateDraw()
return self
end,
getOffset = function(self)
return yOffset
end,
addItem = function(self, t, ...)
base.addItem(self, t, ...)
if(self:getAutoSize())then
local dropdownW, dropdownH = self:getDropdownSize()
self:setDropdownSize(math.max(dropdownW, #t), dropdownH + 1)
if(autoSize)then
dropdownW = math.max(dropdownW, #t)
dropdownH = dropdownH + 1
end
return self
end,
removeItem = function(self, index)
base.removeItem(self, index)
local list = self:getAll()
if(self:getAutoSize())then
local dropdownW, dropdownH = self:getDropdownSize()
if(autoSize)then
dropdownW = 0
dropdownH = 0
for n = 1, #list do
dropdownW = math.max(dropdownW, #list[n].text)
end
dropdownH = #list
self:setDropdownSize(dropdownW, dropdownH)
end
return self
end,
isOpened = function(self)
return self:getOpened()
return isOpened
end,
setOpened = function(self, open)
isOpened = open
self:updateDraw()
return self
end,
setDropdownSize = function(self, width, height)
dropdownW, dropdownH = width, height
autoSize = false
self:updateDraw()
return self
end,
setDropdownWidth = function(self, width)
return self:setDropdownSize(width, dropdownH)
end,
setDropdownHeight = function(self, height)
return self:setDropdownSize(dropdownW, height)
end,
getDropdownSize = function(self)
return dropdownW, dropdownH
end,
getDropdownWidth = function(self)
return dropdownW
end,
getDropdownHeight = function(self)
return dropdownH
end,
mouseHandler = function(self, button, x, y, isMon)
local isOpened = self:getOpened()
if (isOpened) then
local obx, oby = self:getAbsolutePosition()
if(button==1)then
local list = self:getAll()
if (#list > 0) then
local dropdownW, dropdownH = self:getDropdownSize()
local offset = self:getOffset()
for n = 1, dropdownH do
if (list[n + offset] ~= nil) then
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
self:setValue(list[n + offset])
self:selectHandler()
self:setValue(list[n + yOffset])
self:updateDraw()
local val = self:sendEvent("mouse_click", self, "mouse_click", button, x, y)
if(val==false)then return val end
@@ -86,32 +131,29 @@ return function(name, basalt)
end
local base = base:getBase()
if (base.mouseHandler(self, button, x, y)) then
self:setOpened(not isOpened)
isOpened = not isOpened
self:getParent():setImportant(self)
self:updateDraw()
return true
else
if(isOpened)then
self:updateDraw()
self:setOpened(false)
end
isOpened = false
end
return false
end
end,
mouseUpHandler = function(self, button, x, y)
local isOpened = self:getOpened()
if (isOpened) then
local obx, oby = self:getAbsolutePosition()
if(button==1)then
local list = self:getAll()
if (#list > 0) then
local dropdownW, dropdownH = self:getDropdownSize()
local offset = self:getOffset()
for n = 1, dropdownH do
if (list[n + offset] ~= nil) then
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
self:setOpened(false)
isOpened = false
self:updateDraw()
local val = self:sendEvent("mouse_up", self, "mouse_up", button, x, y)
if(val==false)then return val end
@@ -126,13 +168,11 @@ return function(name, basalt)
dragHandler = function(self, btn, x, y)
if(base.dragHandler(self, btn, x, y))then
self:setOpened(true)
isOpened = true
end
end,
scrollHandler = function(self, dir, x, y)
local isOpened = self:getOpened()
local dropdownW, dropdownH = self:getDropdownSize()
if(isOpened)then
local xPos, yPos = self:getAbsolutePosition()
if(x >= xPos)and(x <= xPos + dropdownW)and(y >= yPos)and(y <= yPos + dropdownH)then
@@ -147,21 +187,19 @@ return function(name, basalt)
if(#self:getAll() <= dropdownH)then return false end
local list = self:getAll()
local offset = self:getOffset() + dir
if (offset < 0) then
offset = 0
yOffset = yOffset + dir
if (yOffset < 0) then
yOffset = 0
end
if (dir == 1) then
if (#list > dropdownH) then
if (offset > #list - dropdownH) then
offset = #list - dropdownH
if (yOffset > #list - dropdownH) then
yOffset = #list - dropdownH
end
else
offset = math.min(#list - 1, 0)
yOffset = math.min(#list - 1, 0)
end
end
self:setOffset(offset)
local val = self:sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y)
if(val==false)then return val end
self:updateDraw()
@@ -173,16 +211,11 @@ return function(name, basalt)
base.draw(self)
self:setDrawState("list", false)
self:addDraw("dropdown", function()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local val = self:getValue()
local list = self:getAll()
local bgCol, fgCol = self:getBackground(), self:getForeground()
local openedSymbol, closedSymbol = self:getOpenedSymbol(), self:getClosedSymbol()
local align = self:getAlign()
local dropdownW, dropdownH = self:getDropdownSize()
local offset = self:getOffset()
local selectionColorActive = self:getSelectionColorActive()
local isOpened = self:getOpened()
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))
@@ -191,17 +224,17 @@ return function(name, basalt)
self:addBackgroundBox(1, 2, dropdownW, dropdownH, bgCol)
self:addForegroundBox(1, 2, dropdownW, dropdownH, fgCol)
for n = 1, dropdownH do
if (list[n + offset] ~= nil) then
local t =utils.getTextHorizontalAlign(list[n + offset].text, dropdownW, align)
if (list[n + offset] == val) then
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:addBlit(1, n+1, t, tHex[list[n + offset].fgCol]:rep(#t), tHex[list[n + offset].bgCol]:rep(#t))
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 + offset].fgCol]:rep(#t), tHex[list[n + offset].bgCol]:rep(#t))
self:addBlit(1, n+1, t, tHex[list[n + yOffset].fgCol]:rep(#t), tHex[list[n + yOffset].bgCol]:rep(#t))
end
end
end

View File

@@ -1,23 +1,48 @@
local function flexObjectPlugin(base, basalt)
local flexGrow = 0
local flexShrink = 0
local flexBasis = 0
local baseWidth, baseHeight = base:getSize()
if(base:getType()~="lineBreakFakeObject")then
base:addProperty("FlexGrow", "number", 0)
base:addProperty("FlexShrink", "number", 0)
base:addProperty("FlexBasis", "number", 0)
end
local object = {
getBaseSize = function(self)
getFlexGrow = function(self)
return flexGrow
end,
setFlexGrow = function(self, value)
flexGrow = value
return self
end,
getFlexShrink = function(self)
return flexShrink
end,
setFlexShrink = function(self, value)
flexShrink = value
return self
end,
getFlexBasis = function(self)
return flexBasis
end,
setFlexBasis = function(self, value)
flexBasis = value
return self
end,
getSize = function(self)
return baseWidth, baseHeight
end,
getBaseWidth = function(self)
getWidth = function(self)
return baseWidth
end,
getBaseHeight = function(self)
getHeight = function(self)
return baseHeight
end,
@@ -36,47 +61,28 @@ end
return function(name, basalt)
local base = basalt.getObject("ScrollableFrame")(name, basalt)
base:setType("Flexbox")
local updateLayout = false
base:addProperty("FlexDirection", {"row", "column"}, "row", nil, function(self, direction)
if(direction=="row")then
base:setDirection("horizontal")
elseif(direction=="column")then
base:setDirection("vertical")
end
end)
base:addProperty("Spacing", "number", 1, nil, function(self, spacing)
updateLayout = true
end)
base:addProperty("JustifyContent", {"flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly"}, "flex-start", nil, function(self, justifyContent)
updateLayout = true
end)
base:addProperty("Wrap", {"nowrap", "wrap"}, "nowrap", nil, function(self, wrap)
updateLayout = true
end)
local objectType = "Flexbox"
local direction = "row"
local spacing = 1
local justifyContent = "flex-start"
local wrap = "nowrap"
local children = {}
local sortedChildren = {}
local updateLayout = false
local lineBreakFakeObject = flexObjectPlugin({
getBaseHeight = function(self) return 0 end,
getBaseWidth = function(self) return 0 end,
getHeight = function(self) return 0 end,
getWidth = function(self) return 0 end,
getPosition = function(self) return 0, 0 end,
getSize = function(self) return 0, 0 end,
isType = function(self) return false end,
getType = function(self) return "lineBreakFakeObject" end,
setPosition = function(self) end,
setSize = function(self) end,
getFlexGrow = function(self) return 0 end,
getFlexShrink = function(self) return 0 end,
getFlexBasis = function(self) return 0 end,
})
local function sortChildren(self)
local direction = self:getDirection()
local spacing = self:getSpacing()
local wrap = self:getWrap()
lineBreakFakeObject:setFlexBasis(0):setFlexGrow(0):setFlexShrink(0)
local function sortChildren(self)
if(wrap=="nowrap")then
sortedChildren = {}
local index = 1
@@ -117,19 +123,19 @@ return function(name, basalt)
index = index + 1
sortedChildren[index] = {offset=lineOffset}
else
local objSize = direction == "row" and v:getBaseWidth() or v:getBaseHeight()
local objSize = direction == "row" and v:getWidth() or v:getHeight()
if(objSize+usedSize<=maxSize) then
table.insert(sortedChildren[index], v)
usedSize = usedSize + objSize + spacing
else
lineOffset = lineOffset + lineSize + spacing
lineSize = direction == "row" and v:getBaseHeight() or v:getBaseWidth()
lineSize = direction == "row" and v:getHeight() or v:getWidth()
index = index + 1
usedSize = objSize + spacing
sortedChildren[index] = {offset=lineOffset, v}
end
local childHeight = direction == "row" and v:getBaseHeight() or v:getBaseWidth()
local childHeight = direction == "row" and v:getHeight() or v:getWidth()
if childHeight > lineSize then
lineSize = childHeight
end
@@ -140,9 +146,6 @@ return function(name, basalt)
local function calculateRow(self, children)
local containerWidth, containerHeight = self:getSize()
local spacing = self:getSpacing()
local justifyContent = self:getJustifyContent()
local totalFlexGrow = 0
local totalFlexShrink = 0
local totalFlexBasis = 0
@@ -163,7 +166,7 @@ return function(name, basalt)
local flexGrow = child:getFlexGrow()
local flexShrink = child:getFlexShrink()
local baseWidth = child:getFlexBasis() ~= 0 and child:getFlexBasis() or child:getBaseWidth()
local baseWidth = child:getFlexBasis() ~= 0 and child:getFlexBasis() or child:getWidth()
if totalFlexGrow > 0 then
childWidth = baseWidth + flexGrow / totalFlexGrow * remainingSpace
else
@@ -231,9 +234,6 @@ return function(name, basalt)
local function calculateColumn(self, children)
local containerWidth, containerHeight = self:getSize()
local spacing = self:getSpacing()
local justifyContent = self:getJustifyContent()
local totalFlexGrow = 0
local totalFlexShrink = 0
local totalFlexBasis = 0
@@ -255,7 +255,7 @@ return function(name, basalt)
local flexGrow = child:getFlexGrow()
local flexShrink = child:getFlexShrink()
local baseHeight = child:getFlexBasis() ~= 0 and child:getFlexBasis() or child:getBaseHeight()
local baseHeight = child:getFlexBasis() ~= 0 and child:getFlexBasis() or child:getHeight()
if totalFlexGrow > 0 then
childHeight = baseHeight + flexGrow / totalFlexGrow * remainingSpace
else
@@ -324,7 +324,7 @@ return function(name, basalt)
local function applyLayout(self)
sortChildren(self)
if self:getFlexDirection() == "row" then
if direction == "row" then
for _,v in pairs(sortedChildren)do
calculateRow(self, v)
end
@@ -337,6 +337,58 @@ return function(name, basalt)
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,
setJustifyContent = function(self, value)
justifyContent = value
updateLayout = true
self:updateDraw()
return self
end,
getJustifyContent = function(self)
return justifyContent
end,
setDirection = function(self, value)
direction = value
updateLayout = true
self:updateDraw()
return self
end,
getDirection = function(self)
return direction
end,
setSpacing = function(self, value)
spacing = value
updateLayout = true
self:updateDraw()
return self
end,
getSpacing = function(self)
return spacing
end,
setWrap = function(self, value)
wrap = value
updateLayout = true
self:updateDraw()
return self
end,
getWrap = function(self)
return wrap
end,
updateLayout = function(self)
updateLayout = true
self:updateDraw()
@@ -378,4 +430,4 @@ return function(name, basalt)
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -4,19 +4,54 @@ 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)
base:setType("Frame")
local objectType = "Frame"
local parent
local updateRender = true
local xOffset, yOffset = 0, 0
base:setSize(30, 10)
base:setZ(10)
base:setZIndex(10)
base:addProperty("XOffset", "number", 0)
base:addProperty("YOffset", "number", 0)
base:combineProperty("Offset", "XOffset", "YOffset")
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,
local object = {
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,
getXOffset = function(self)
return xOffset
end,
setXOffset = function(self, newXOffset)
return self:setOffset(newXOffset, nil)
end,
getYOffset = function(self)
return yOffset
end,
setYOffset = function(self, newYOffset)
return self:setOffset(nil, newYOffset)
end,
setParent = function(self, p, ...)
@@ -58,7 +93,7 @@ return function(name, basalt)
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,
end,
setCursor = function(self, blink, x, y, color)
local obx, oby = self:getPosition()
@@ -68,7 +103,7 @@ return function(name, basalt)
end,
}
for _,v in pairs({"drawBackgroundBox", "drawForegroundBox", "drawTextBox"})do
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()
@@ -80,7 +115,7 @@ return function(name, basalt)
end
end
for _,v in pairs({"setBg", "setFg", "setText"})do
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()

View File

@@ -1,34 +1,102 @@
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Graph")
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Graph"
base:setZ(5)
base:setZIndex(5)
base:setSize(30, 10)
base:addProperty("GraphColor", "color", colors.gray)
base:addProperty("GraphSymbol", "char", "\7")
base:addProperty("GraphSymbolColor", "color", colors.black)
base:addProperty("MaxValue", "number", 100)
base:addProperty("MinValue", "number", 0)
base:addProperty("GraphType", {"bar", "line", "scatter"}, "line")
base:addProperty("MaxEntries", "number", 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,
setGraphSymbolColor = function(self, symbolColor)
return self:setGraphSymbolColor(nil, symbolColor)
end,
getGraphSymbol = function(self)
return graphSymbol, graphSymbolCol
end,
getGraphSymbolColor = function(self)
return graphSymbolCol
end,
addDataPoint = function(self, value)
local minValue = self:getMinValue()
local maxValue = self:getMaxValue()
if value >= minValue and value <= maxValue then
table.insert(graphData, value)
self:updateDraw()
end
while #graphData>self:getMaxEntries() do
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,
getGraphType = function(self)
return graphType
end,
setMaxEntries = function(self, value)
maxEntries = value
self:updateDraw()
return self
end,
getMaxEntries = function(self)
return maxEntries
end,
clear = function(self)
graphData = {}
self:updateDraw()
@@ -38,14 +106,9 @@ return function(name, basalt)
draw = function(self)
base.draw(self)
self:addDraw("graph", function()
local obx, oby = self:getPosition()
local w, h = self:getSize()
local graphColor = self:getGraphColor()
local graphSymbol = self:getGraphSymbol()
local graphSymbolCol = self:getGraphSymbolColor()
local maxValue = self:getMaxValue()
local minValue = self:getMinValue()
local graphType = self:getGraphType()
local maxEntries = self:getMaxEntries()
local bgCol, fgCol = self:getBackground(), self:getForeground()
local range = maxValue - minValue
local prev_x, prev_y
@@ -70,23 +133,23 @@ return function(name, basalt)
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
@@ -105,4 +168,4 @@ return function(name, basalt)
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -4,7 +4,7 @@ local unpack,sub,max,min = table.unpack,string.sub,math.max,math.min
return function(name, basalt)
-- Image
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Image")
local objectType = "Image"
local bimgLibrary = bimg()
local bimgFrame = bimgLibrary.getFrameObject(1)
@@ -16,32 +16,30 @@ return function(name, basalt)
local animTimer
local usePalette = false
local autoSize = true
local x, y = 1, 1
base:addProperty("XOffset", "number", 0)
base:addProperty("YOffset", "number", 0)
base:combineProperty("Offset", "XOffset", "YOffset")
local xOffset, yOffset = 0, 0
base:setSize(24, 8)
base:setZ(2)
base:setZIndex(2)
local function getPalette()
local function getPalette(id)
local p = {}
for k,v in pairs(colors)do
if(type(v)=="number")then
p[math.log(v, 2)] = {term.nativePaletteColor(v)}
p[k] = {term.nativePaletteColor(v)}
end
end
local globalPalette = bimgLibrary.getMetadata("palette")
if(globalPalette~=nil)then
for k,v in pairs(globalPalette)do
p[k] = v
p[k] = tonumber(v)
end
end
local localPalette = bimgFrame.getFrameData("palette")
local localPalette = bimgLibrary.getFrameData("palette")
basalt.log(localPalette)
if(localPalette~=nil)then
for k,v in pairs(localPalette)do
p[k] = v
p[k] = tonumber(v)
end
end
return p
@@ -56,12 +54,51 @@ return function(name, basalt)
end
local object = {
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, 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,
setXOffset = function(self, _x)
return self:setOffset(self, _x, nil)
end,
setYOffset = function(self, _y)
return self:setOffset(self, nil, _y)
end,
setSize = function(self, _x, _y)
base:setSize(_x, _y)
autoSize = false
return self
end,
getOffset = function(self)
return xOffset, yOffset
end,
getXOffset = function(self)
return xOffset
end,
getYOffset = function(self)
return yOffset
end,
selectFrame = function(self, id)
if(bimgLibrary.getFrameObject(id)==nil)then
bimgLibrary.addFrame(id)
@@ -298,11 +335,10 @@ return function(name, basalt)
end
if(usePalette)then
self:getParent():setPalette(getPalette())
self:getParent():setPalette(getPalette(activeFrame))
end
if(image~=nil)then
local xOffset, yOffset = self:getOffset()
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]

View File

@@ -4,26 +4,21 @@ local tHex = require("tHex")
return function(name, basalt)
-- Input
local base = basalt.getObject("ChangeableObject")(name, basalt)
base:setType("Input")
local objectType = "Input"
base:setZ(5)
local inputType = "text"
local inputLimit = 0
base:setZIndex(5)
base:setValue("")
base:setSize(12, 1)
local showingText = ""
base:addProperty("defaultText", "string", "", nil, function(self, value)
showingText = value
end)
base:addProperty("defaultForeground", "color", nil)
base:addProperty("defaultBackground", "color", nil)
base:combineProperty("default", "defaultText", "defaultForeground", "defaultBackground")
base:addProperty("offset", "number", 1)
base:addProperty("cursorPosition", "number", 1)
base:addProperty("inputType", {"text", "number", "password"}, "text")
base:addProperty("inputLimit", "number", 0)
base:addProperty("align", {"left", "center", "right"}, "left")
local textX = 1
local wIndex = 1
local defaultText = ""
local defaultBGCol = colors.black
local defaultFGCol = colors.lightGray
local showingText = defaultText
local internalValueChange = false
local object = {
@@ -35,13 +30,73 @@ return function(name, basalt)
self:listenEvent("mouse_drag")
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,
setDefaultFG = function(self, fCol)
return self:setDefaultText(self, defaultText, fCol, nil)
end,
setDefaultBG = function(self, bCol)
return self:setDefaultText(self, defaultText, nil, bCol)
end,
setDefaultText = function(self, text, fCol, bCol)
defaultText = text
defaultFGCol = fCol or defaultFGCol
defaultBGCol = bCol or defaultBGCol
if (self:isFocused()) then
showingText = ""
else
showingText = defaultText
end
self:updateDraw()
return self
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,
setValue = function(self, val)
base.setValue(self, tostring(val))
if not (internalValueChange) then
local textX = tostring(val):len() + 1
local wIndex = math.max(1, textX-self:getWidth()+1)
self:setOffset(wIndex)
self:setCursorPosition(textX)
textX = tostring(val):len() + 1
wIndex = math.max(1, textX-self:getWidth()+1)
if(self:isFocused())then
local parent = self:getParent()
local obx, oby = self:getPosition()
@@ -52,23 +107,39 @@ return function(name, basalt)
return self
end,
getValue = function(self)
local val = base.getValue(self)
return inputType == "number" and tonumber(val) or val
end,
setInputLimit = function(self, limit)
inputLimit = tonumber(limit) or inputLimit
self:updateDraw()
return self
end,
getInputLimit = function(self)
return inputLimit
end,
getFocusHandler = function(self)
base.getFocusHandler(self)
local parent = self:getParent()
if (parent ~= nil) then
local defaultText = self:getDefaultText()
local obx, oby = self:getPosition()
showingText = ""
if(defaultText~="")then
self:updateDraw()
end
parent:setCursor(true, obx + textX - wIndex, oby+math.max(math.ceil(self:getHeight()/2-1, 1)), self:getForeground())
end
end,
loseFocusHandler = function(self)
base.loseFocusHandler(self)
local parent = self:getParent()
showingText = self:getDefaultText()
if(showingText~="")then
showingText = defaultText
if(defaultText~="")then
self:updateDraw()
end
parent:setCursor(false)
@@ -79,11 +150,9 @@ return function(name, basalt)
local w,h = self:getSize()
local parent = self:getParent()
internalValueChange = true
local wIndex = self:getOffset()
local textX = self:getCursorPosition()
if (key == keys.backspace) then
-- on backspace
local text = tostring(self:getValue())
local text = tostring(base.getValue())
if (textX > 1) then
self:setValue(text:sub(1, textX - 2) .. text:sub(textX, text:len()))
textX = math.max(textX - 1, 1)
@@ -96,7 +165,7 @@ return function(name, basalt)
parent:clearFocusedChild(self)
end
if (key == keys.right) then
local tLength = tostring(self:getValue()):len()
local tLength = tostring(base.getValue()):len()
textX = textX + 1
if (textX > tLength) then
@@ -120,18 +189,9 @@ return function(name, basalt)
textX = math.max(textX, 1)
wIndex = math.max(wIndex, 1)
end
if (key == keys.home) then
-- home
textX = 1
wIndex = 1
end
if (key == keys["end"]) then
-- end
textX = tostring(self:getValue()):len() + 1
wIndex = math.max(textX - w + 1, 1)
end
self:setOffset(wIndex)
self:setCursorPosition(textX)
local obx, oby = self:getPosition()
local val = tostring(base.getValue())
self:updateDraw()
internalValueChange = false
return true
@@ -141,12 +201,8 @@ return function(name, basalt)
charHandler = function(self, char)
if (base.charHandler(self, char)) then
internalValueChange = true
local wIndex = self:getOffset()
local textX = self:getCursorPosition()
local w,h = self:getSize()
local text = tostring(self:getValue())
local inputType = self:getInputType()
local inputLimit = self:getInputLimit()
local text = base.getValue()
if (text:len() < inputLimit or inputLimit <= 0) then
if (inputType == "number") then
local cache = text
@@ -154,7 +210,7 @@ return function(name, basalt)
self:setValue(text:sub(1, textX - 1) .. char .. text:sub(textX, text:len()))
textX = textX + 1
if(char==".")or(char=="-")and(#text>0)then
if (tonumber(self:getValue()) == nil) then
if (tonumber(base.getValue()) == nil) then
self:setValue(cache)
textX = textX - 1
end
@@ -167,9 +223,9 @@ return function(name, basalt)
if (textX >= w + wIndex) then
wIndex = wIndex + 1
end
self:setOffset(wIndex)
self:setCursorPosition(textX)
end
local obx, oby = self:getPosition()
local val = tostring(base.getValue())
internalValueChange = false
self:updateDraw()
@@ -179,12 +235,12 @@ return function(name, basalt)
mouseHandler = function(self, button, x, y)
if(base.mouseHandler(self, button, x, y))then
local parent = self:getParent()
local ax, ay = self:getPosition()
local obx, oby = self:getAbsolutePosition(ax, ay)
local wIndex = self:getOffset()
local textX = self:getCursorPosition()
local w, h = self:getSize()
textX = x - obx + wIndex
local text = tostring(self:getValue())
local text = base.getValue()
if (textX > text:len()) then
textX = text:len() + 1
end
@@ -194,8 +250,7 @@ return function(name, basalt)
wIndex = 1
end
end
self:setOffset(wIndex)
self:setCursorPosition(textX)
parent:setCursor(true, ax + textX - wIndex, ay+math.max(math.ceil(h/2-1, 1)), self:getForeground())
return true
end
end,
@@ -212,54 +267,22 @@ return function(name, basalt)
end
end,
eventHandler = function(self, event, paste, ...)
base.eventHandler(self, event, paste, ...)
if(event=="paste")then
if(self:isFocused())then
local text = tostring(self:getValue())
local textX = self:getCursorPosition()
local inputType = self:getInputType()
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()))
end
if (tonumber(self:getValue()) == nil) then
self:setValue(cache)
end
else
self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len()))
end
self:updateDraw()
end
end
end,
draw = function(self)
base.draw(self)
self:addDraw("input", function()
local parent = self:getParent()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local wIndex = self:getOffset()
local textX = self:getCursorPosition()
local defaultBGCol = self:getDefaultBackground()
local defaultFGCol = self:getDefaultForeground()
local inputType = self:getInputType()
local verticalAlign = utils.getTextVerticalAlign(h, "center")
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
local val = tostring(self:getValue() or "")
local val = tostring(base.getValue())
local bCol = self:getBackground()
local fCol = self:getForeground()
local text
if (val:len() <= 0) then
if not(self:isFocused())then
text = showingText
bCol = defaultBGCol or bCol
fCol = defaultFGCol or fCol
end
text = showingText
bCol = defaultBGCol or bCol
fCol = defaultFGCol or fCol
end
text = showingText

View File

@@ -1,69 +1,115 @@
local utils = require("utils")
local wrapText = utils.wrapText
local writeWrappedText = utils.writeWrappedText
local tHex = require("tHex")
return function(name, basalt)
-- Label
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Label")
local objectType = "Label"
base:setZ(3)
base:setZIndex(3)
base:setSize(5, 1)
base:setBackground(false)
base:addProperty("text", "string", "Label", nil, function(self, value)
local autoSize = self:getAutoSize()
value = tostring(value)
if(autoSize)then
local t = wrapText(value, #value)
local newW, newH = 1,0
for _,v in pairs(t)do
newH = newH + 1
newW = math.max(newW, v:len())
end
if(newH==0)then newH = 1 end
self:setSize(newW, newH)
self:setAutoSize(true)
end
end)
base:addProperty("autoSize", "boolean", true)
base:addProperty("textAlign", {"left", "center", "right"}, "left")
local autoSize = true
local text, textAlign = "Label", "left"
local object = {
init = function(self)
base.init(self)
local parent = self:getParent()
self:setBackground(nil)
self:setForeground(parent:getForeground())
--- Returns the object type.
--- @return string
getType = function(self)
return objectType
end,
--- Returns the label's base object.
--- @return object
getBase = function(self)
return base
end,
--- 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,
--- 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,
--- Returns the label's text.
--- @return string
getText = function(self)
return text
end,
--- 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)
self:setAutoSize(false)
autoSize = false
return self
end,
--- Gets the text alignment of the label.
--- @return string
getTextAlign = function(self)
return textAlign
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)
base.draw(self)
self:addDraw("label", function()
local w, h = self:getSize()
local text = self:getText()
local textAlign = self:getTextAlign()
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+1, h)
end)
end,
--- Initializes the label.
init = function(self)
base.init(self)
local parent = self:getParent()
self:setForeground(parent:getForeground())
end
}
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -3,23 +3,22 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
base:setType("List")
local objectType = "List"
local list = {}
local itemSelectedBG = colors.black
local itemSelectedFG = colors.lightGray
local selectionColorActive = true
local textAlign = "left"
local yOffset = 0
local scrollable = true
base:setSize(16, 8)
base:setZ(5)
base:addProperty("SelectionBackground", "color", colors.black)
base:addProperty("SelectionForeground", "color", colors.lightGray)
base:combineProperty("SelectionColor", "SelectionBackground", "SelectionForeground")
base:addProperty("selectionColorActive", "boolean", true)
base:addProperty("textAlign", {"left", "center", "right"}, "left")
base:addProperty("scrollable", "boolean", true)
base:addProperty("offset", "number", 0)
base:setZIndex(5)
local object = {
init = function(self)
local parent = self:getParent()
self:listenEvent("mouse_click")
self:listenEvent("mouse_drag")
self:listenEvent("mouse_scroll")
@@ -30,6 +29,27 @@ return function(name, basalt)
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,
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:getBackground(), fgCol = fgCol or self:getForeground(), args = { ... } })
if (#list <= 1) then
@@ -53,6 +73,16 @@ return function(name, basalt)
return self
end,
setOffset = function(self, yOff)
yOffset = yOff
self:updateDraw()
return self
end,
getOffset = function(self)
return yOffset
end,
removeItem = function(self, index)
if(type(index)=="number")then
table.remove(list, index)
@@ -113,29 +143,69 @@ return function(name, basalt)
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,
setSelectionBG = function(self, bgCol)
return self:setSelectionColor(bgCol, nil, selectionColorActive)
end,
setSelectionFG = function(self, fgCol)
return self:setSelectionColor(nil, fgCol, selectionColorActive)
end,
getSelectionColor = function(self)
return itemSelectedBG, itemSelectedFG
end,
getSelectionBG = function(self)
return itemSelectedBG
end,
getSelectionFG = function(self)
return 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,
getScrollable = function(self)
return scrollable
end,
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
local scrollable = self:getScrollable()
if(scrollable)then
local offset = self:getOffset()
local w,h = self:getSize()
offset = offset + dir
if (offset < 0) then
offset = 0
yOffset = yOffset + dir
if (yOffset < 0) then
yOffset = 0
end
if (dir >= 1) then
if (#list > h) then
if (offset > #list - h) then
offset = #list - h
if (yOffset > #list - h) then
yOffset = #list - h
end
if (offset >= #list) then
offset = #list - 1
if (yOffset >= #list) then
yOffset = #list - 1
end
else
offset = offset - 1
yOffset = yOffset - 1
end
end
self:setOffset(offset)
self:updateDraw()
end
return true
@@ -148,11 +218,10 @@ return function(name, basalt)
local obx, oby = self:getAbsolutePosition()
local w,h = self:getSize()
if (#list > 0) then
local offset = self:getOffset()
for n = 1, h do
if (list[n + offset] ~= nil) then
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + w > x) and (oby + n - 1 == y) then
self:setValue(list[n + offset])
self:setValue(list[n + yOffset])
self:selectHandler()
self:updateDraw()
end
@@ -189,21 +258,16 @@ return function(name, basalt)
base.draw(self)
self:addDraw("list", function()
local w, h = self:getSize()
local offset = self:getOffset()
local selectionColorActive = self:getSelectionColorActive()
local itemSelectedBG = self:getSelectionBackground()
local itemSelectedFG = self:getSelectionForeground()
local activeObject = self:getValue()
for n = 1, h do
if list[n + offset] then
local t = list[n + offset].text
local fg, bg = list[n + offset].fgCol, list[n + offset].bgCol
if list[n + offset] == activeObject and selectionColorActive then
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:addText(1, n, t:sub(1, w))
self:addFg(1, n, tHex[fg]:rep(w))
self:addBg(1, n, tHex[bg]:rep(w))
self:addText(1, n, t:sub(1,w))
self:addBG(1, n, tHex[bg]:rep(w))
self:addFG(1, n, tHex[fg]:rep(w))
end
end
end)

View File

@@ -3,20 +3,20 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("List")(name, basalt)
base:setType("Menubar")
local objectType = "Menubar"
local object = {}
base:setSize(30, 1)
base:setZ(5)
base:setZIndex(5)
base:addProperty("ItemOffset", "number", 0)
base:addProperty("Space", "number", 1)
local itemOffset = 0
local space, outerSpace = 1, 1
local scrollable = true
local function maxScroll()
local mScroll = 0
local w = base:getWidth()
local list = base:getAll()
local space = base:getSpace()
for n = 1, #list do
mScroll = mScroll + list[n].text:len() + space * 2
end
@@ -25,29 +25,52 @@ return function(name, basalt)
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,
getBase = function(self)
return base
end,
setSpace = function(self, _space)
space = _space or space
self:updateDraw()
return self
end,
getSpace = function(self)
return space
end,
setScrollable = function(self, scroll)
scrollable = scroll
if(scroll==nil)then scrollable = true end
return self
end,
getScrollable = function(self)
return scrollable
end,
mouseHandler = function(self, button, x, y)
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()
local space = self:getSpace()
local itemOffset = self:getItemOffset()
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:selectHandler()
self:sendEvent(event, self, event, 0, x, y, list[n])
end
xPos = xPos + list[n].text:len() + space * 2
end
@@ -59,9 +82,7 @@ return function(name, basalt)
scrollHandler = function(self, dir, x, y)
if(base:getBase().scrollHandler(self, dir, x, y))then
local scrollable = self:getScrollable()
if(scrollable)then
local itemOffset = self:getItemOffset()
itemOffset = itemOffset + dir
if (itemOffset < 0) then
itemOffset = 0
@@ -72,7 +93,6 @@ return function(name, basalt)
if (itemOffset > mScroll) then
itemOffset = mScroll
end
self:setItemOffset(itemOffset)
self:updateDraw()
end
return true
@@ -83,13 +103,12 @@ return function(name, basalt)
draw = function(self)
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()
local itemOffset = self:getItemOffset()
local space = self:getSpace()
for _, v in pairs(self:getAll()) do
local newItem = (" "):rep(space) .. v.text .. (" "):rep(space)
text = text .. newItem

View File

@@ -4,37 +4,73 @@ local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("BaseFrame")(name, basalt)
base:setType("MonitorFrame")
local isMonitorGroup = false
base:addProperty("Monitor", "string|table", nil, false, function(self, value)
if(type(value)=="string")then
local mon = peripheral.wrap(value)
if(mon~=nil)then
self:setTerm(mon)
end
elseif(type(value)=="table")then
self:setTerm(value)
end
end)
base:addProperty("MonitorGroup", "string|table", nil, false, function(self, value)
self:setTerm(basaltMon(value))
isMonitorGroup = true
end)
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,
local object = {
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
local monGroup = self:getTerm()
x, y = monGroup.calculateClick(monitor, x, y)
end
base.mouseHandler(self, btn, x, y, isMon, monitor, ...)

View File

@@ -2,19 +2,37 @@ local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("Frame")(name, basalt)
base:setType("MovableFrame")
local objectType = "MovableFrame"
local parent
local dragXOffset, dragYOffset, isDragging = 0, 0, false
local renderThrottle = basalt.getRenderingThrottle()
base:addProperty("DraggingMap", "table", {{x1 = 1, x2 = "width", y1 = 1, y2 = 1}})
local dragMap = {
{x1 = 1, x2 = "width", y1 = 1, y2 = 1}
}
local object = {
getBase = function(self)
return base
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")
@@ -32,10 +50,13 @@ return function(name, basalt)
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), y + dragYOffset - (parentY - 1))
self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO)
self:updateDraw()
end
return true
@@ -47,13 +68,10 @@ return function(name, basalt)
parent:setImportant(self)
local fx, fy = self:getAbsolutePosition()
local w, h = self:getSize()
local dragMap = self:getDraggingMap()
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
renderThrottle = basalt.getRenderingThrottle()
basalt.setRenderingThrottle(50)
isDragging = true
dragXOffset = fx - x
dragYOffset = fy - y
@@ -66,7 +84,6 @@ return function(name, basalt)
mouseUpHandler = function(self, ...)
isDragging = false
basalt.setRenderingThrottle(0)
return base.mouseUpHandler(self, ...)
end,

View File

@@ -1,6 +1,5 @@
local basaltEvent = require("basaltEvent")
local utils = require("utils")
local split = utils.splitString
local uuid = utils.uuid
local unpack,sub = table.unpack,string.sub
@@ -10,197 +9,52 @@ return function(name, basalt)
assert(basalt~=nil, "Unable to find basalt instance! ID: "..name)
-- Base object
local initialized = false
local objectType = "Object" -- not changeable
local isEnabled,initialized = true,false
local eventSystem = basaltEvent()
local registeredEvents = {}
local activeEvents = {}
local properties = {}
local propertyConfig = {}
local function defaultRule(typ)
return function(self, value)
local isValid = false
if(type(typ)=="string")then
local types = split(typ, "|")
for _,v in pairs(types)do
if(type(value)==v)then
isValid = true
end
end
end
if(type(typ)=="table")then
for _,v in pairs(typ)do
if(v==value)then
isValid = true
end
end
end
if(typ=="color")then
if(type(value)=="string")then
if(colors[value]~=nil)then
isValid = true
value = colors[value]
end
else
for _,v in pairs(colors)do
if(v==value)then
isValid = true
end
end
end
end
if(typ=="char")then
if(type(value)=="string")then
if(#value==1)then
isValid = true
end
end
end
if(typ=="any")or(value==nil)or(type(value)=="function")then
isValid = true
end
if(typ=="string")and(type(value)~="function")then
value = tostring(value)
isValid = true
end
if(not isValid)then
local t = type(value)
if(type(typ)=="table")then
typ = table.concat(typ, ", ")
t = value
end
error(self:getType()..": Invalid type for property "..name.."! Expected "..typ..", got "..t)
end
return value
end
end
local parent
local object
object = {
local object = {
init = function(self)
if(initialized)then return false end
initialized = true
return true
end,
isType = function(self, typ)
for k,v in pairs(properties["Type"])do
if(v==typ)then
return true
end
end
return false
end,
getTypes = function(self)
return properties["Type"]
end,
load = function(self)
end,
getType = function(self)
return objectType
end,
isType = function(self, t)
return objectType==t
end,
getProperty = function(self, name)
local get = self["get" .. name:gsub("^%l", string.upper)]
if (get ~= nil) then
return get(self)
end
end,
setProperty = function(self, name, ...)
local set = self["set" .. name:gsub("^%l", string.upper)]
if (set ~= nil) then
return set(self, ...)
end
end,
getName = function(self)
return name
end,
getProperty = function(self, name)
local prop = properties[name:gsub("^%l", string.upper)]
if(type(prop)=="function")then
return prop()
end
return prop
end,
getProperties = function(self)
local p = {}
for k,v in pairs(properties)do
if(type(v)=="function")then
p[k] = v()
else
p[k] = v
end
end
return p
end,
setProperty = function(self, name, value, rule)
name = name:gsub("^%l", string.upper)
if(rule~=nil)then
value = rule(self, value)
end
--if(properties[name]~=value)then
properties[name] = value
if(self.updateDraw~=nil)then
self:updateDraw()
end
--end
return self
end,
getPropertyConfig = function(self, name)
return propertyConfig[name]
end,
addProperty = function(self, name, typ, defaultValue, readonly, setLogic, getLogic, alteredRule)
name = name:gsub("^%l", string.upper)
propertyConfig[name] = {type=typ, defaultValue=defaultValue, readonly=readonly}
if(properties[name]~=nil)then
error("Property "..name.." in "..self:getType().." already exists!")
end
self:setProperty(name, defaultValue)
object["get" .. name] = function(self, ...)
if(self~=nil)then
local prop = self:getProperty(name)
if(getLogic~=nil)then
return getLogic(self, prop, ...)
end
return prop
end
end
if(not readonly)then
object["set" .. name] = function(self, value, ...)
if(self~=nil)then
if(setLogic~=nil)then
local modifiedVal = setLogic(self, value, ...)
if(modifiedVal~=nil)then
value = modifiedVal
end
end
self:setProperty(name, value, alteredRule~=nil and alteredRule(typ) or defaultRule(typ))
end
return self
end
end
return self
end,
combineProperty = function(self, name, ...)
name = name:gsub("^%l", string.upper)
local args = {...}
object["get" .. name] = function(self)
local result = {}
for _,v in pairs(args)do
v = v:gsub("^%l", string.upper)
result[#result+1] = self["get" .. v](self)
end
return unpack(result)
end
object["set" .. name] = function(self, ...)
local values = {...}
for k,v in pairs(args)do
if(self["set"..v]~=nil)then -- if später entfernen
self["set" .. v](self, values[k])
end
end
return self
end
return self
getParent = function(self)
return parent
end,
setParent = function(self, newParent, noRemove)
@@ -208,15 +62,14 @@ return function(name, basalt)
if (newParent.getType ~= nil and newParent:isType("Container")) then
self:remove()
newParent:addChild(self)
if (self.show) then
self:show()
end
parent = newParent
end
return self
end,
getParent = function(self)
return parent
end,
updateEvents = function(self)
for k,v in pairs(activeEvents)do
parent:removeEvent(k, self)
@@ -240,18 +93,22 @@ return function(name, basalt)
return self
end,
getZIndex = function(self)
return 1
end,
enable = function(self)
self:setProperty("Enabled", true)
isEnabled = true
return self
end,
disable = function(self)
self:setProperty("Enabled", false)
isEnabled = false
return self
end,
isEnabled = function(self)
return self:getProperty("Enabled")
return isEnabled
end,
remove = function(self)
@@ -288,11 +145,11 @@ return function(name, basalt)
registerEvent = function(self, event, func)
if(parent~=nil)then
parent:addEvent(event, self)
if(event=="mouse_drag")then
parent:addEvent("mouse_click", self)
parent:addEvent("mouse_up", self)
end
parent:addEvent(event, self)
end
eventSystem:registerEvent(event, func)
if (registeredEvents[event] == nil) then
@@ -425,24 +282,6 @@ return function(name, basalt)
end,
}
object:addProperty("Z", "number", 1, false, function(self, value)
if (parent ~= nil) then
parent:updateZIndex(self, value)
self:updateDraw()
end
return value
end)
object:addProperty("Type", "string|table", {"Object"}, false, function(self, value)
if(type(value)=="string")then
table.insert(properties["Type"], 1, value)
return properties["Type"]
end
end,
function(self, _, depth)
return properties["Type"][depth or 1]
end)
object:addProperty("Enabled", "boolean", true)
object.__index = object
return object
end

View File

@@ -1,11 +1,15 @@
return function(name, basalt)
-- Pane
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Pane")
local objectType = "Pane"
base:setSize(25, 10)
local object = {}
local object = {
getType = function(self)
return objectType
end,
}
object.__index = object
return setmetatable(object, base)

View File

@@ -5,11 +5,10 @@ local sub = string.sub
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Program")
local objectType = "Program"
local object
base:addProperty("Path", "string", nil)
base:addProperty("Enviroment", "table", nil)
local cachedPath
local enviroment = {}
local function createBasaltWindow(x, y, width, height)
local xCursor, yCursor = 1, 1
@@ -347,7 +346,7 @@ return function(name, basalt)
return basaltwindow
end
base:setZ(5)
base:setZIndex(5)
base:setSize(30, 12)
local pWindow = createBasaltWindow(1, 1, 30, 12)
local curProcess
@@ -406,19 +405,23 @@ return function(name, basalt)
end
object = {
getType = function(self)
return objectType
end;
show = function(self)
base.show(self)
pWindow.setBackgroundColor(self:getBackground())
pWindow.setTextColor(self:getForeground())
pWindow.basalt_setVisible(true)
return self
end,
end;
hide = function(self)
base.hide(self)
pWindow.basalt_setVisible(false)
return self
end,
end;
setPosition = function(self, x, y, rel)
base.setPosition(self, x, y, rel)
@@ -428,32 +431,32 @@ return function(name, basalt)
getBasaltWindow = function()
return pWindow
end,
end;
getBasaltProcess = function()
return curProcess
end,
end;
setSize = function(self, width, height, rel)
base.setSize(self, width, height, rel)
pWindow.basalt_resize(self:getWidth(), self:getHeight())
return self
end,
end;
getStatus = function(self)
if (curProcess ~= nil) then
return curProcess:getStatus()
end
return "inactive"
end;
setEnviroment = function(self, env)
enviroment = env or {}
return self
end,
execute = function(self, path, ...)
local cachedPath = self:getPath()
local enviroment = self:getEnviroment()
cachedPath = path or cachedPath
if(path~=nil)then
self:setPath(path)
end
curProcess = process:new(cachedPath, pWindow, enviroment, ...)
pWindow.setBackgroundColor(colors.black)
pWindow.setTextColor(colors.white)
@@ -474,7 +477,7 @@ return function(name, basalt)
self:listenEvent("char", self)
self:listenEvent("other_event", self)
return self
end,
end;
setExecute = function(self, path, ...)
return self:execute(path, ...)
@@ -492,7 +495,7 @@ return function(name, basalt)
end
parent:removeEvents(self)
return self
end,
end;
pause = function(self, p)
paused = p or (not paused)
@@ -505,11 +508,11 @@ return function(name, basalt)
end
end
return self
end,
end;
isPaused = function(self)
return paused
end,
end;
injectEvent = function(self, event, ign, ...)
if (curProcess ~= nil) then
@@ -522,16 +525,16 @@ return function(name, basalt)
end
end
return self
end,
end;
getQueuedEvents = function(self)
return queuedEvent
end,
end;
updateQueuedEvents = function(self, events)
queuedEvent = events or queuedEvent
return self
end,
end;
injectEvents = function(self, ...)
if (curProcess ~= nil) then
@@ -542,7 +545,7 @@ return function(name, basalt)
end
end
return self
end,
end;
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
@@ -681,6 +684,10 @@ return function(name, basalt)
draw = function(self)
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,
@@ -691,6 +698,7 @@ return function(name, basalt)
self:registerEvent("program_error", v)
end
end
local parent = self:getParent()
self:listenEvent("other_event")
return self
end,
@@ -701,6 +709,7 @@ return function(name, basalt)
self:registerEvent("program_done", v)
end
end
local parent = self:getParent()
self:listenEvent("other_event")
return self
end,

View File

@@ -1,30 +1,96 @@
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
base:setType("ProgressBar")
local objectType = "Progressbar"
base:setZ(5)
local progress = 0
base:setZIndex(5)
base:setValue(false)
base:setSize(25, 3)
base:addProperty("Progress", "number", 0, false, function(self, value)
local progress = self:getProgress()
if (value >= 0) and (value <= 100) and (progress ~= value) then
self:setValue(progress)
if (progress == 100) then
self:progressDoneHandler()
end
return value
end
return progress
end)
base:addProperty("Direction", "number", 0)
base:addProperty("ActiveBarSymbol", "string", " ")
base:addProperty("ActiveBarColor", "color", colors.black)
base:addProperty("ActiveBarSymbolColor", "color", colors.white)
base:combineProperty("ProgressBar", "ActiveBarColor", "ActiveBarSymbol", "ActiveBarSymbolColor")
base:addProperty("BackgroundSymbol", "char", "")
local activeBarColor = colors.black
local activeBarSymbol = ""
local activeBarSymbolCol = colors.white
local bgBarSymbol = ""
local direction = 0
local object = {
getType = function(self)
return objectType
end,
setDirection = function(self, dir)
direction = dir
self:updateDraw()
return self
end,
getDirection = function(self)
return direction
end,
setProgressBar = function(self, color, symbol, symbolcolor)
activeBarColor = color or activeBarColor
activeBarSymbol = symbol or activeBarSymbol
activeBarSymbolCol = symbolcolor or activeBarSymbolCol
self:updateDraw()
return self
end,
getProgressBar = function(self)
return activeBarColor, activeBarSymbol, activeBarSymbolCol
end,
setActiveBarColor = function(self, color)
return self:setProgressBar(color, nil, nil)
end,
getActiveBarColor = function(self)
return activeBarColor
end,
setActiveBarSymbol = function(self, symbol)
return self:setProgressBar(nil, symbol, nil)
end,
getActiveBarSymbol = function(self)
return activeBarSymbol
end,
setActiveBarSymbolColor = function(self, symbolColor)
return self:setProgressBar(nil, nil, symbolColor)
end,
getActiveBarSymbolColor = function(self)
return activeBarSymbolCol
end,
setBackgroundSymbol = function(self, symbol)
bgBarSymbol = symbol:sub(1, 1)
self:updateDraw()
return self
end,
getBackgroundSymbol = function(self)
return bgBarSymbol
end,
setProgress = function(self, value)
if (value >= 0) and (value <= 100) and (progress ~= value) then
progress = value
self:setValue(progress)
if (progress == 100) then
self:progressDoneHandler()
end
end
self:updateDraw()
return self
end,
getProgress = function(self)
return progress
end,
onProgressDone = function(self, f)
self:registerEvent("progress_done", f)
return self
@@ -37,31 +103,28 @@ return function(name, basalt)
draw = function(self)
base.draw(self)
self:addDraw("progressbar", function()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local p = self:getProperties()
local activeBarColor, activeBarSymbol, activeBarSymbolCol = self:getActiveBarColor(), self:getActiveBarSymbol(), self:getActiveBarSymbolColor()
activeBarColor = activeBarColor or colors.red
activeBarSymbol = activeBarSymbol or " "
activeBarSymbolCol = activeBarSymbolCol or colors.white
if(p.Background~=nil)then self:addBackgroundBox(1, 1, w, h, p.Background) end
if(p.BgSymbol~="")then self:addTextBox(1, 1, w, h, p.BgSymbol) end
if(p.Foreground~=nil)then self:addForegroundBox(1, 1, w, h, p.Foreground) end
if (p.Direction == 1) then
self:addBackgroundBox(1, 1, w, h / 100 * p.Progress, activeBarColor)
self:addForegroundBox(1, 1, w, h / 100 * p.Progress, activeBarSymbolCol)
self:addTextBox(1, 1, w, h / 100 * p.Progress, activeBarSymbol)
elseif (p.Direction == 3) then
self:addBackgroundBox(1, 1 + math.ceil(h - h / 100 * p.Progress), w, h / 100 * p.Progress, activeBarColor)
self:addForegroundBox(1, 1 + math.ceil(h - h / 100 * p.Progress), w, h / 100 * p.Progress, activeBarSymbolCol)
self:addTextBox(1, 1 + math.ceil(h - h / 100 * p.Progress), w, h / 100 * p.Progress, activeBarSymbol)
elseif (p.Direction == 2) then
self:addBackgroundBox(1 + math.ceil(w - w / 100 * p.Progress), 1, w / 100 * p.Progress, h, activeBarColor)
self:addForegroundBox(1 + math.ceil(w - w / 100 * p.Progress), 1, w / 100 * p.Progress, h, activeBarSymbolCol)
self:addTextBox(1 + math.ceil(w - w / 100 * p.Progress), 1, w / 100 * p.Progress, h, activeBarSymbol)
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 * p.Progress), h, activeBarColor)
self:addForegroundBox(1, 1, math.ceil(w / 100 * p.Progress), h, activeBarSymbolCol)
self:addTextBox(1, 1, math.ceil(w / 100 * p.Progress), h, activeBarSymbol)
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,
@@ -70,4 +133,4 @@ return function(name, basalt)
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -3,26 +3,25 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("List")(name, basalt)
base:setType("Radio")
local objectType = "Radio"
base:setSize(1, 1)
base:setZ(5)
base:addProperty("BoxSelectionBG", "color", colors.black)
base:addProperty("BoxSelectionFG", "color", colors.green)
base:combineProperty("BoxSelectionColor", "BoxSelectionBG", "BoxSelectionFG")
base:addProperty("BoxNotSelectionBG", "color", colors.black)
base:addProperty("BoxNotSelectionFG", "color", colors.red)
base:combineProperty("BoxNotSelectionColor", "BoxNotSelectionBG", "BoxNotSelectionFG")
base:addProperty("SelectionColorActive", "boolean", true)
base:addProperty("Symbol", "char", "\7")
base:addProperty("Align", "string", { "left", "right" }, "left")
base:setZIndex(5)
local list = {}
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"
local object = {
getType = function(self)
return objectType
end,
addItem = function(self, text, x, y, bgCol, fgCol, ...)
base.addItem(self, text, bgCol, fgCol, ...)
table.insert(list, { x = x or 1, y = y or #list * 2 })
@@ -48,6 +47,58 @@ return function(name, basalt)
return self
end,
setBoxSelectionColor = function(self, bg, fg)
boxSelectedBG = bg
boxSelectedFG = fg
return self
end,
setBoxSelectionBG = function(self, bg)
return self:setBoxSelectionColor(bg, boxSelectedFG)
end,
setBoxSelectionFG = function(self, fg)
return self:setBoxSelectionColor(boxSelectedBG, fg)
end,
getBoxSelectionColor = function(self)
return boxSelectedBG, boxSelectedFG
end,
getBoxSelectionBG = function(self)
return boxSelectedBG
end,
getBoxSelectionFG = function(self)
return boxSelectedFG
end,
setBoxDefaultColor = function(self, bg, fg)
boxNotSelectedBG = bg
boxNotSelectedFG = fg
return self
end,
setBoxDefaultBG = function(self, bg)
return self:setBoxDefaultColor(bg, boxNotSelectedFG)
end,
setBoxDefaultFG = function(self, fg)
return self:setBoxDefaultColor(boxNotSelectedBG, fg)
end,
getBoxDefaultColor = function(self)
return boxNotSelectedBG, boxNotSelectedFG
end,
getBoxDefaultBG = function(self)
return boxNotSelectedBG
end,
getBoxDefaultFG = function(self)
return boxNotSelectedFG
end,
mouseHandler = function(self, button, x, y, ...)
if (#list > 0) then
local obx, oby = self:getAbsolutePosition()
@@ -55,7 +106,6 @@ return function(name, basalt)
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)
self:selectHandler()
local val = self:sendEvent("mouse_click", self, "mouse_click", button, x, y, ...)
self:updateDraw()
if(val==false)then return val end
@@ -69,9 +119,6 @@ return function(name, basalt)
self:addDraw("radio", function()
local itemSelectedBG, itemSelectedFG = self:getSelectionColor()
local baseList = self:getAll()
local boxSelectedBG, boxSelectedFG = self:getBoxSelectionColor()
local boxNotSelectedBG, boxNotSelectedFG = self:getBoxNotSelectionColor()
local symbol = self:getSymbol()
for k, value in pairs(baseList) do
if (value == self:getValue()) then
self:addBlit(list[k].x, list[k].y, symbol, tHex[boxSelectedFG], tHex[boxSelectedBG])

View File

@@ -1,30 +1,13 @@
local max,min,sub,rep = math.max,math.min,string.sub,string.rep
local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("Frame")(name, basalt)
base:setType("ScrollableFrame")
local objectType = "ScrollableFrame"
local parent
base:addProperty("AutoCalculate", "boolean", true)
base:addProperty("Direction", {"vertical", "horizontal"}, "vertical")
base:addProperty("Scrollbar", "boolean", false)
base:addProperty("ScrollbarSymbolBackground", "number", colors.black)
base:addProperty("ScrollbarSymbolForeground", "number", colors.black)
base:addProperty("ScrollbarSymbol", "char", " ")
base:combineProperty("ScrollbarFront", "ScrollbarSymbol", "ScrollbarSymbolBackground", "ScrollbarSymbolForeground")
base:addProperty("ScrollbarBackgroundSymbol", "char", "\127")
base:addProperty("ScrollbarBackground", "number", colors.gray)
base:addProperty("ScrollbarForeground", "number", colors.black)
base:combineProperty("ScrollbarBack", "ScrollbarBackgroundSymbol", "ScrollbarBackground", "ScrollbarForeground")
base:addProperty("ScrollbarArrowForeground", "number", colors.lightGray)
base:addProperty("ScrollbarArrowBackground", "number", colors.black)
base:combineProperty("ScrollbarArrowColor", "ScrollbarArrowBackground", "ScrollbarArrowForeground")
base:addProperty("ScrollAmount", "number", 0, false, function(self, value)
self:setAutoCalculate(false)
end)
base:addProperty("ScrollSpeed", "number", 1)
local direction = 0
local manualScrollAmount = 0
local calculateScrollAmount = true
local function getHorizontalScrollAmount(self)
local amount = 0
@@ -76,69 +59,54 @@ return function(name, basalt)
local function scrollHandler(self, dir)
local xO, yO = self:getOffset()
local scrollAmn
local direction = self:getDirection()
local calculateScrollAmount = self:getAutoCalculate()
local manualScrollAmount = self:getScrollAmount()
local scrollSpeed = self:getScrollSpeed()
if(direction=="horizontal")then
if(direction==1)then
scrollAmn = calculateScrollAmount and getHorizontalScrollAmount(self) or manualScrollAmount
self:setOffset(min(scrollAmn, max(0, xO + dir * scrollSpeed)), yO)
elseif(direction=="vertical")then
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 * scrollSpeed)))
self:setOffset(xO, min(scrollAmn, max(0, yO + dir)))
end
self:updateDraw()
end
local function scrollWithMouse(self, x, y)
local direction = self:getDirection()
local scrollAmn
local calculateScrollAmount = self:getAutoCalculate()
local manualScrollAmount = self:getScrollAmount()
if(direction=="horizontal") then
if(y==self:getHeight()) then
if(x>1)and(x<self:getWidth())then
scrollAmn = calculateScrollAmount and getHorizontalScrollAmount(self) or manualScrollAmount
self:setOffset(math.floor(x / self:getWidth() * scrollAmn), 0)
end
end
elseif(direction=="vertical") then
if(x==self:getWidth()) then
if(y>1)and(y<self:getHeight())then
scrollAmn = calculateScrollAmount and getVerticalScrollAmount(self) or manualScrollAmount
self:setOffset(0, math.floor(y / self:getHeight() * scrollAmn))
end
if(y==1)then
scrollHandler(self, -1)
end
if(y==self:getHeight())then
scrollHandler(self, 1)
end
end
end
end
local object = {
getBase = function(self)
return base
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")
self:listenEvent("mouse_drag")
self:listenEvent("mouse_click")
self:listenEvent("mouse_up")
end,
removeChildren = function(self)
base.removeChildren(self)
self:listenEvent("mouse_scroll")
self:listenEvent("mouse_drag")
self:listenEvent("mouse_click")
self:listenEvent("mouse_up")
end,
setParent = function(self, p, ...)
base.setParent(self, p, ...)
parent = p
return self
end,
scrollHandler = function(self, dir, x, y)
@@ -150,104 +118,27 @@ return function(name, basalt)
if(self.getOffset~=nil)then
xO, yO = self:getOffset()
end
if(obj.element:getIgnoreOffset())then
if(obj.element.getIgnoreOffset())then
xO, yO = 0, 0
end
if (obj.element.scrollHandler(obj.element, dir, x+xO, y+yO)) then
if (obj.element.scrollHandler(obj.element, dir, x+xO, y+yO)) then
return true
end
end
end
scrollHandler(self, dir)
scrollHandler(self, dir, x, y)
self:clearFocusedChild()
return true
end
end,
mouseHandler = function(self, btn, x, y)
if(base:getBase().mouseHandler(self, btn, x, y))then
local obX, obY = self:getAbsolutePosition()
scrollWithMouse(self, x-obX+1, y-obY+1)
return true
end
end,
dragHandler = function(self, btn, x, y)
if(base:getBase().dragHandler(self, btn, x, y))then
local obX, obY = self:getAbsolutePosition()
scrollWithMouse(self, x-obX+1, y-obY+1)
return true
end
end,
draw = function(self)
base.draw(self)
self:addDraw("scrollableFrameScrollbar", function()
if(self:getScrollbar())then
local xO, yO = self:getOffset()
local p = self:getProperties()
local width, height = p.Width, p.Height
if(p.Direction=="vertical")then
local scrollAmount = getVerticalScrollAmount(self)
local scrollBarHeight = max(1, math.floor(height * height / (height + scrollAmount)))
local scrollBarY = yO * (height - scrollBarHeight) / scrollAmount
local bgSymbol, bgColor, bgFgColor = self:getScrollbarBack()
local fgSymbol, fgColor, fgFgColor = self:getScrollbarFront()
local arrowBg, arrowFg = self:getScrollbarArrowColor()
bgColor = tHex[bgColor]
fgColor = tHex[fgColor]
bgFgColor = tHex[bgFgColor]
fgFgColor = tHex[fgFgColor]
arrowBg = tHex[arrowBg]
arrowFg = tHex[arrowFg]
for y=2, height-1 do
local char = bgSymbol
local bg = bgColor
local fg = bgFgColor
if(y>=scrollBarY)and(y<=scrollBarY+scrollBarHeight)then
char = fgSymbol
bg = fgColor
fg = fgFgColor
end
self:blit(width, y, char, fg, bg)
end
self:blit(width, 1, "\30", arrowFg, arrowBg)
self:blit(width, height, "\31", arrowFg, arrowBg)
elseif(p.Direction=="horizontal")then
local scrollAmount = getHorizontalScrollAmount(self)
local scrollBarWidth = max(1, math.floor(width * width / (width + scrollAmount)))
local scrollBarX = xO * (width - scrollBarWidth) / scrollAmount
local bgSymbol, bgColor, bgFgColor = self:getScrollbarBack()
local fgSymbol, fgColor, fgFgColor = self:getScrollbarFront()
local arrowBg, arrowFg = self:getScrollbarArrowColor()
bgColor = tHex[bgColor]
fgColor = tHex[fgColor]
bgFgColor = tHex[bgFgColor]
fgFgColor = tHex[fgFgColor]
arrowBg = tHex[arrowBg]
arrowFg = tHex[arrowFg]
for x=2, width-1 do
local char = bgSymbol
local bg = bgColor
local fg = bgFgColor
if(x>=scrollBarX)and(x<=scrollBarX+scrollBarWidth)then
char = fgSymbol
bg = fgColor
fg = fgFgColor
end
self:blit(x, height, char, fg, bg)
end
self:blit(1, height, "\17", arrowFg, arrowBg)
self:blit(width, height, "\16", arrowFg, arrowBg)
end
self:addDraw("scrollableFrame", function()
if(calculateScrollAmount)then
scrollHandler(self, 0)
end
end)
end, 0)
end,
}

View File

@@ -2,43 +2,33 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Scrollbar")
local objectType = "Scrollbar"
base:setZ(2)
base:setZIndex(2)
base:setSize(1, 8)
base:setBackground(colors.lightGray, "\127", colors.black)
base:addProperty("SymbolChar", "char", " ")
base:addProperty("SymbolBG", "color", colors.black)
base:addProperty("SymbolFG", "color", colors.black)
base:combineProperty("Symbol", "SymbolChar", "SymbolBG", "SymbolFG")
base:addProperty("SymbolAutoSize", "boolean", true)
base:setBackground(colors.lightGray, "\127", colors.gray)
local barType = "vertical"
local symbol = " "
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()
local symbolAutoSize = base:getSymbolAutoSize()
if(symbolAutoSize)then
local barType = base:getBarType()
local scrollAmount = base:getScrollAmount()
local symbol = base:getSymbolChar()
base:setSymbolSize(math.max((barType == "vertical" and h or w-(#symbol)) - (scrollAmount-1), 1))
symbolSize = math.max((barType == "vertical" and h or w-(#symbol)) - (scrollAmount-1), 1)
end
end
base:addProperty("ScrollAmount", "number", 3, false, updateSymbolSize)
base:addProperty("SymbolSize", "number", 1)
base:addProperty("BarType", {"vertical", "horizontal"}, "vertical", false, updateSymbolSize)
updateSymbolSize()
local function mouseEvent(self, _, x, y)
local function mouseEvent(self, button, x, y)
local obx, oby = self:getAbsolutePosition()
local w,h = self:getSize()
updateSymbolSize()
local barType = self:getBarType()
local symbol = self:getSymbolChar()
local symbolSize = self:getSymbolSize()
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
@@ -50,31 +40,99 @@ return function(name, basalt)
end
local object = {
getType = function(self)
return objectType
end,
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,
setSymbolBG = function(self, bg)
return self:setSymbol(symbol, bg, nil)
end,
setSymbolFG = function(self, fg)
return self:setSymbol(symbol, nil, fg)
end,
getSymbol = function(self)
return symbol
end,
getSymbolBG = function(self)
return symbolBG
end,
getSymbolFG = function(self)
return symbolFG
end,
setIndex = function(self, _index)
index = _index
if (index < 1) then
index = 1
end
local w,h = self:getSize()
--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,
getScrollAmount = function(self)
return scrollAmount
end,
getIndex = function(self)
local w,h = self:getSize()
local barType = self:getBarType()
local scrollAmount = self:getScrollAmount()
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
symbolAutoSize = size~=false and false or true
updateSymbolSize()
self:updateDraw()
return self
end,
getSymbolSize = function(self)
return symbolSize
end,
setBarType = function(self, _typ)
barType = _typ:lower()
updateSymbolSize()
self:updateDraw()
return self
end,
getBarType = function(self)
return barType
end,
mouseHandler = function(self, button, x, y, ...)
if (base.mouseHandler(self, button, x, y, ...)) then
mouseEvent(self, button, x, y)
@@ -105,9 +163,6 @@ return function(name, basalt)
if (index < 1) then
index = 1
end
local barType = self:getBarType()
local symbol = self:getSymbolChar()
local symbolSize = self:getSymbolSize()
index = math.min(index, (barType == "vertical" and h or w) - (barType == "vertical" and symbolSize - 1 or #symbol+symbolSize-2))
self:scrollbarMoveHandler()
self:updateDraw()
@@ -132,23 +187,24 @@ return function(name, basalt)
base.customEventHandler(self, event, ...)
if(event=="basalt_FrameResize")then
updateSymbolSize()
end
end
end,
draw = function(self)
base.draw(self)
self:addDraw("scrollbar", function()
local p = self:getProperties()
local w, h = p.Width, p.Height
if (p.BarType == "horizontal") then
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, p.SymbolChar:rep(p.SymbolSize), tHex[p.SymbolFG]:rep(#p.SymbolChar*p.SymbolSize), tHex[p.SymbolBG]:rep(#p.SymbolChar*p.SymbolSize))
self:addBlit(index, 1 + n, symbol:rep(symbolSize), tHex[symbolFG]:rep(#symbol*symbolSize), tHex[symbolBG]:rep(#symbol*symbolSize))
end
elseif (p.BarType == "vertical") then
elseif (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(p.SymbolSize - 1, h) do
self:addBlit(1, index + curIndexOffset, p.SymbolChar:rep(math.max(#p.SymbolChar, w)), tHex[p.SymbolFG]:rep(math.max(#p.SymbolChar, w)), tHex[p.SymbolBG]:rep(math.max(#p.SymbolChar, w)))
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

View File

@@ -2,29 +2,24 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
base:setType("Slider")
local objectType = "Slider"
base:setSize(12, 1)
base:setValue(1)
base:setBackground(false, "\140", colors.black)
base:addProperty("SymbolText", "char", " ")
base:addProperty("SymbolForeground", "color", colors.black)
base:addProperty("SymbolBackground", "color", colors.gray)
base:combineProperty("Symbol", "SymbolText", "SymbolForeground", "SymbolBackground")
base:addProperty("SymbolSize", "number", 1)
base:addProperty("BarType", {"vertical", "horizontal"}, "horizontal")
base:addProperty("MaxValue", "number", 12)
local barType = "horizontal"
local symbol = " "
local symbolFG = colors.black
local symbolBG = colors.gray
local maxValue = 12
local index = 1
local symbolSize = 1
local function mouseEvent(self, _, x, y)
local function mouseEvent(self, button, x, y)
local obx, oby = self:getPosition()
local w,h = self:getSize()
local barType = self:getBarType()
local size = barType == "vertical" and h or w
local symbolSize = self:getSymbolSize()
local symbol = self:getSymbol()
local maxValue = self:getMaxValue()
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))
@@ -35,27 +30,32 @@ return function(name, basalt)
end
local object = {
init = function(self)
base.init(self)
base:setBgSymbol("\140")
base:setBgSymbolColor(colors.black)
base:setBackground(nil)
getType = function(self)
return objectType
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,
getSymbol = function(self)
return symbol
end,
setIndex = function(self, _index)
index = _index
if (index < 1) then
index = 1
end
local w,h = self:getSize()
local symbolSize = self:getSymbolSize()
local maxValue = self:getMaxValue()
local barType = self:getBarType()
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
self:updateDraw()
@@ -66,6 +66,35 @@ return function(name, basalt)
return index
end,
setMaxValue = function(self, val)
maxValue = val
return self
end,
getMaxValue = function(self)
return maxValue
end,
setSymbolColor = function(self, col)
symbolColor = col
self:updateDraw()
return self
end,
getSymbolColor = function(self)
return symbolColor
end,
setBarType = function(self, _typ)
barType = _typ:lower()
self:updateDraw()
return self
end,
getBarType = function(self)
return barType
end,
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
mouseEvent(self, button, x, y)
@@ -89,9 +118,6 @@ return function(name, basalt)
if (index < 1) then
index = 1
end
local symbolSize = self:getSymbolSize()
local maxValue = self:getMaxValue()
local barType = self:getBarType()
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
self:updateDraw()
@@ -105,27 +131,21 @@ return function(name, basalt)
self:addDraw("slider", function()
local w,h = self:getSize()
local bgCol,fgCol = self:getBackground(), self:getForeground()
local symbolSize = self:getSymbolSize()
local symbol = self:getSymbolText()
local symbolFG = self:getSymbolForeground()
local symbolBG = self:getSymbolBackground()
local barType = self:getBarType()
local obx, oby = self:getPosition()
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
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:addBlit(1, 1+n+curIndexOffset, symbol, tHex[symbolFG], tHex[symbolFG])
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, " ", tHex[fgCol], tHex[bgCol])
self:addBlit(1, 1+n, bgSymbol, tHex[fgCol], tHex[bgCol])
end
end
end

View File

@@ -1,16 +1,48 @@
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
base:setType("Switch")
local objectType = "Switch"
base:setSize(4, 1)
base:setValue(false)
base:setZ(5)
base:setZIndex(5)
base:addProperty("SymbolColor", "color", colors.black)
base:addProperty("ActiveBackground", "color", colors.green)
base:addProperty("InactiveBackground", "color", colors.red)
local bgSymbol = colors.black
local inactiveBG = colors.red
local activeBG = colors.green
local object = {
getType = function(self)
return objectType
end,
setSymbol = function(self, col)
bgSymbol = col
return self
end,
getSymbol = function(self)
return bgSymbol
end,
setActiveBackground = function(self, col)
activeBG = col
return self
end,
getActiveBackground = function(self)
return activeBG
end,
setInactiveBackground = function(self, col)
inactiveBG = col
return self
end,
getInactiveBackground = function(self)
return inactiveBG
end,
load = function(self)
self:listenEvent("mouse_click")
end,
@@ -26,9 +58,8 @@ return function(name, basalt)
draw = function(self)
base.draw(self)
self:addDraw("switch", function()
local activeBG = self:getActiveBackground()
local inactiveBG = self:getInactiveBackground()
local bgSymbol = self:getSymbolColor()
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)

View File

@@ -4,7 +4,8 @@ local rep,find,gmatch,sub,len = string.rep,string.find,string.gmatch,string.sub,
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
base:setType("Textfield")
local objectType = "Textfield"
local hIndex, wIndex, textX, textY = 1, 1, 1, 1
local lines = { "" }
local bgLines = { "" }
@@ -14,18 +15,10 @@ return function(name, basalt)
local startSelX,endSelX,startSelY,endSelY
base:addProperty("SelectionForeground", "color", colors.black)
base:addProperty("SelectionBackground", "color", colors.lightBlue)
base:combineProperty("SelectionColor", "SelectionBackground", "SelectionForeground")
base:addProperty("XOffset", "number", 1)
base:addProperty("YOffset", "number", 1)
base:combineProperty("Offset", "XOffset", "YOffset")
base:addProperty("TextXPosition", "number", 1)
base:addProperty("TextYPosition", "number", 1)
base:combineProperty("TextPosition", "TextXPosition", "TextYPosition")
local selectionBG,selectionFG = colors.lightBlue,colors.black
base:setSize(30, 12)
base:setZ(5)
base:setZIndex(5)
local function isSelected()
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
@@ -83,28 +76,11 @@ return function(name, basalt)
end
end
self:setTextPosition(sx, sy)
textX, textY = sx, sy
startSelX, endSelX, startSelY, endSelY = nil, nil, nil, nil
return self
end
local function getSelectedContent(self)
local sx, ex, sy, ey = getSelectionCoordinates()
local content = {}
if isSelected() then
if sy == ey then
table.insert(content, lines[sy]:sub(sx, ex))
else
table.insert(content, lines[sy]:sub(sx, lines[sy]:len()))
for i = sy + 1, ey - 1 do
table.insert(content, lines[i])
end
table.insert(content, lines[ey]:sub(1, ex))
end
end
return content
end
local function stringGetPositions(str, word)
local pos = {}
if(str:len()>0)then
@@ -122,22 +98,8 @@ return function(name, basalt)
return pos
end
local function stringGetKeywordPositions(str, keyword)
local pattern = "%f[%a]"..keyword.."%f[%A]"
local positions = {}
local start, finish = str:find(pattern)
while start do
table.insert(positions, start)
table.insert(positions, finish)
start, finish = str:find(pattern, finish + 1)
end
return positions
end
local function updateColors(self, l)
l = l or self:getTextYPosition()
if(l>#lines)then return end
l = l or textY
local fgLine = tHex[self:getForeground()]:rep(fgLines[l]:len())
local bgLine = tHex[self:getBackground()]:rep(bgLines[l]:len())
for k,v in pairs(rules)do
@@ -156,7 +118,7 @@ return function(name, basalt)
end
for k,v in pairs(keyWords)do
for _,b in pairs(v)do
local pos = stringGetKeywordPositions(lines[l], b)
local pos = stringGetPositions(lines[l], b)
if(#pos>0)then
for x=1,#pos/2 do
local xP = x*2 - 1
@@ -177,6 +139,10 @@ return function(name, basalt)
end
local object = {
getType = function(self)
return objectType
end;
setBackground = function(self, bg)
base.setBackground(self, bg)
updateAllColors(self)
@@ -189,6 +155,32 @@ return function(name, basalt)
return self
end,
setSelection = function(self, fg, bg)
selectionFG = fg or selectionFG
selectionBG = bg or selectionBG
return self
end,
setSelectionFG = function(self, fg)
return self:setSelection(fg, nil)
end,
setSelectionBG = function(self, bg)
return self:setSelection(nil, bg)
end,
getSelection = function(self)
return selectionFG, selectionBG
end,
getSelectionFG = function(self)
return selectionFG
end,
getSelectionBG = function(self)
return selectionBG
end,
getLines = function(self)
return lines
end,
@@ -209,8 +201,7 @@ return function(name, basalt)
bgLines = {""}
fgLines = {""}
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
self:setTextPosition(1, 1)
self:setOffset(1, 1)
hIndex, wIndex, textX, textY = 1, 1, 1, 1
self:updateDraw()
return self
end,
@@ -245,18 +236,18 @@ return function(name, basalt)
if(keyWords[color]==nil)then
keyWords[color] = {}
end
for _,v in pairs(tab)do
for k,v in pairs(tab)do
table.insert(keyWords[color], v)
end
self:updateDraw()
return self
end,
end;
addRule = function(self, rule, fg, bg)
table.insert(rules, {rule, fg, bg})
self:updateDraw()
return self
end,
end;
editRule = function(self, rule, fg, bg)
for k,v in pairs(rules)do
@@ -299,22 +290,40 @@ return function(name, basalt)
return self
end,
getLineCount = function(self)
return #lines
getTextCursor = function(self)
return textX, textY
end,
getLineLength = function(self, index)
return lines[index]:len()
getOffset = function(self)
return wIndex, hIndex
end,
getSelectedContent = getSelectedContent,
setOffset = function(self, xOff, yOff)
wIndex = xOff or wIndex
hIndex = yOff or hIndex
self:updateDraw()
return self
end,
getXOffset = function(self)
return wIndex
end,
setXOffset = function(self, xOff)
return self:setOffset(xOff, nil)
end,
getYOffset = function(self)
return hIndex
end,
setYOffset = function(self, yOff)
return self:setOffset(nil, yOff)
end,
getFocusHandler = function(self)
base.getFocusHandler(self)
basalt.setRenderingThrottle(50)
local obx, oby = self:getPosition()
local wIndex, hIndex = self:getOffset()
local textX, textY = self:getTextPosition()
self:getParent():setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self:getForeground())
end,
@@ -328,8 +337,6 @@ return function(name, basalt)
local parent = self:getParent()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local wIndex, hIndex = self:getOffset()
local textX, textY = self:getTextPosition()
if (key == keys.backspace) then
-- on backspace
if(isSelected())then
@@ -533,8 +540,6 @@ return function(name, basalt)
cursorX = 0
end
parent:setCursor(true, obx + cursorX, oby + cursorY, self:getForeground())
self:setOffset(wIndex, hIndex)
self:setTextPosition(textX, textY)
self:updateDraw()
return true
end
@@ -548,9 +553,6 @@ return function(name, basalt)
if(isSelected())then
removeSelection(self)
end
local wIndex, hIndex = self:getOffset()
local textX, textY = self:getTextPosition()
lines[textY] = lines[textY]:sub(1, textX - 1) .. char .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self:getForeground()] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self:getBackground()] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
@@ -575,8 +577,6 @@ return function(name, basalt)
cursorX = 0
end
parent:setCursor(true, obx + cursorX, oby + cursorY, self:getForeground())
self:setOffset(wIndex, hIndex)
self:setTextPosition(textX, textY)
self:updateDraw()
return true
end
@@ -588,8 +588,6 @@ return function(name, basalt)
local obx, oby = self:getAbsolutePosition()
local ox, oy = self:getPosition()
local w,h = self:getSize()
local wIndex, hIndex = self:getOffset()
local textX, textY = self:getTextPosition()
if (lines[y - oby + hIndex] ~= nil) then
if(x - obx + wIndex > 0)and(x - obx + wIndex <= w)then
textX = x - obx + wIndex
@@ -607,8 +605,6 @@ return function(name, basalt)
wIndex = 1
end
end
self:setOffset(wIndex, hIndex)
self:setTextPosition(textX, textY)
parent:setCursor(not isSelected(), ox + textX - wIndex, oy + textY - hIndex, self:getForeground())
self:updateDraw()
end
@@ -623,8 +619,6 @@ return function(name, basalt)
local obx, oby = self:getAbsolutePosition()
local anchx, anchy = self:getPosition()
local w,h = self:getSize()
local wIndex, hIndex = self:getOffset()
local textX, textY = self:getTextPosition()
hIndex = hIndex + dir
if (hIndex > #lines - (h - 1)) then
hIndex = #lines - (h - 1)
@@ -634,7 +628,6 @@ return function(name, basalt)
hIndex = 1
end
self:setOffset(wIndex, hIndex)
if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (anchy + textY - hIndex >= anchy and anchy + textY - hIndex < anchy + h) then
parent:setCursor(not isSelected(), anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
else
@@ -650,8 +643,6 @@ return function(name, basalt)
local parent = self:getParent()
local obx, oby = self:getAbsolutePosition()
local anchx, anchy = self:getPosition()
local wIndex, hIndex = self:getOffset()
local textX, textY = self:getTextPosition()
if (lines[y - oby + hIndex] ~= nil) then
textX = x - obx + wIndex
textY = y - oby + hIndex
@@ -671,8 +662,6 @@ return function(name, basalt)
end
self:updateDraw()
end
self:setOffset(wIndex, hIndex)
self:setTextPosition(textX, textY)
parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
return true
end
@@ -681,7 +670,6 @@ return function(name, basalt)
mouseUpHandler = function(self, button, x, y)
if (base.mouseUpHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition()
local wIndex, hIndex = self:getOffset()
if (lines[y - oby + hIndex] ~= nil) then
endSelX = x - obx + wIndex
endSelY = y - oby + hIndex
@@ -703,11 +691,6 @@ return function(name, basalt)
if(self:isFocused())then
local parent = self:getParent()
local fgColor, bgColor = self:getForeground(), self:getBackground()
if(isSelected())then
removeSelection(self)
end
local wIndex, hIndex = self:getOffset()
local textX, textY = self:getTextPosition()
local w, h = self:getSize()
lines[textY] = lines[textY]:sub(1, textX - 1) .. paste .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[fgColor]:rep(paste:len()) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
@@ -718,8 +701,6 @@ return function(name, basalt)
end
local anchx, anchy = self:getPosition()
parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, fgColor)
self:setOffset(wIndex, hIndex)
self:setTextPosition(textX, textY)
updateColors(self)
self:updateDraw()
end
@@ -730,9 +711,9 @@ return function(name, basalt)
base.draw(self)
self:addDraw("textfield", function()
local w, h = self:getSize()
local wIndex, hIndex = self:getOffset()
local selectionBG = self:getSelectionBackground()
local selectionFG = self:getSelectionForeground()
local bgColor = tHex[self:getBackground()]
local fgColor = tHex[self:getForeground()]
for n = 1, h do
local text = ""
local bg = ""
@@ -744,12 +725,12 @@ return function(name, basalt)
end
text = sub(text, wIndex, w + wIndex - 1)
bg = sub(bg, wIndex, w + wIndex - 1)
fg = sub(fg, 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:addBG(1, n, bg)
self:addFG(1, n, fg)
self:addBlit(1, n, text, fg, bg)
end
@@ -770,8 +751,8 @@ return function(name, basalt)
local visible_line_length = math.min(line, w - xOffset)
self:addBg(1 + xOffset, n, rep(tHex[selectionBG], visible_line_length))
self:addFg(1 + xOffset, n, rep(tHex[selectionFG], visible_line_length))
self:addBG(1 + xOffset, n, rep(tHex[selectionBG], visible_line_length))
self:addFG(1 + xOffset, n, rep(tHex[selectionFG], visible_line_length))
end
end
end)
@@ -790,4 +771,4 @@ return function(name, basalt)
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -1,6 +1,7 @@
return function(name, basalt)
local base = basalt.getObject("Object")(name, basalt)
base:setType("Thread")
local objectType = "Thread"
local func
local cRoutine
@@ -8,6 +9,10 @@ return function(name, basalt)
local filter
local object = {
getType = function(self)
return objectType
end,
start = function(self, f)
if (f == nil) then
error("Function provided to thread is nil")

View File

@@ -1,36 +1,33 @@
return function(name, basalt)
local base = basalt.getObject("Object")(name, basalt)
base:setType("Timer")
base:addProperty("Timer", "number", 0, false, function(self, value)
if (value < 0) then
value = 0
end
return value
end)
base:addProperty("Repeat", "number", 1, false, function(self, value)
if(value~=nil)then
if (value < 0) then
value = 0
end
else
value = 0
end
return value
end)
base:combineProperty("Time", "Timer", "Repeat")
local objectType = "Timer"
local timer = 0
local savedRepeats = 0
local repeats = 0
local timerObj
local timerIsActive = false
local object = {
getType = function(self)
return objectType
end,
setTime = function(self, _timer, _repeats)
timer = _timer or 0
savedRepeats = _repeats or 1
return self
end,
getTime = function(self)
return timer
end,
start = function(self)
if(timerIsActive)then
os.cancelTimer(timerObj)
end
local timer, repeatAmount = self:getTime()
repeats = savedRepeats
timerObj = os.startTimer(timer)
timerIsActive = true
self:listenEvent("other_event")
@@ -63,12 +60,10 @@ return function(name, basalt)
return self
end,
eventHandler = function(self, event, tObj, ...)
base.eventHandler(self, event, tObj, ...)
eventHandler = function(self, event, ...)
base.eventHandler(self, event, ...)
if event == "timer" and tObj == timerObj and timerIsActive then
self:sendEvent("timed_event")
local timer = self:getTimer()
local repeats = self:getRepeat()
if (repeats >= 1) then
repeats = repeats - 1
if (repeats >= 1) then
@@ -83,4 +78,4 @@ return function(name, basalt)
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -3,30 +3,18 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
base:setType("Treeview")
local objectType = "Treeview"
base:addProperty("Nodes", "table", {})
base:addProperty("SelectionBackground", "color", colors.black)
base:addProperty("SelectionForeground", "color", colors.lightGray)
base:combineProperty("SelectionColor", "SelectionBackground", "SelectionForeground")
base:addProperty("XOffset", "number", 0)
base:addProperty("YOffset", "number", 0)
base:combineProperty("Offset", "XOffset", "YOffset")
base:addProperty("Scrollable", "boolean", true)
base:addProperty("TextAlign", {"left", "center", "right"}, "left")
base:addProperty("ExpandableSymbol", "char", "\7")
base:addProperty("ExpandableSymbolForeground", "color", colors.lightGray)
base:addProperty("ExpandableSymbolBackground", "color", colors.black)
base:combineProperty("ExpandableSymbolColor", "ExpandableSymbolForeground", "ExpandableSymbolBackground")
base:addProperty("ExpandedSymbol", "char", "\8")
base:addProperty("ExpandedSymbolForeground", "color", colors.lightGray)
base:addProperty("ExpandedSymbolBackground", "color", colors.black)
base:combineProperty("ExpandedSymbolColor", "ExpandedSymbolForeground", "ExpandedSymbolBackground")
base:addProperty("ExpandableSymbolSpacing", "number", 1)
base:addProperty("selectionColorActive", "boolean", true)
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:setZ(5)
base:setZIndex(5)
local function newNode(text, expandable)
text = text or ""
@@ -66,7 +54,9 @@ return function(name, basalt)
end,
setExpanded = function(self, exp)
expanded = exp
if(expandable)then
expanded = exp
end
base:updateDraw()
return node
end,
@@ -89,9 +79,9 @@ return function(name, basalt)
onSelect(node)
end
end,
setExpandable = function(self, _expandable)
expandable = _expandable
setExpandable = function(self, expandable)
expandable = expandable
base:updateDraw()
return node
end,
@@ -139,9 +129,6 @@ return function(name, basalt)
end
local root = newNode("Root", true)
base:addProperty("Root", "table", root, false, function(self, value)
value.setParent(nil)
end)
root:setExpanded(true)
local object = {
@@ -156,6 +143,91 @@ return function(name, basalt)
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,
setXOffset = function(self, x)
return self:setOffset(x, yOffset)
end,
setYOffset = function(self, y)
return self:setOffset(xOffset, y)
end,
getOffset = function(self)
return xOffset, yOffset
end,
getXOffset = function(self)
return xOffset
end,
getYOffset = function(self)
return yOffset
end,
setScrollable = function(self, scroll)
scrollable = scroll
return self
end,
getScrollable = function(self, scroll)
return scrollable
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,
setSelectionBG = function(self, bgCol)
return self:setSelectionColor(bgCol, nil, selectionColorActive)
end,
setSelectionFG = function(self, fgCol)
return self:setSelectionColor(nil, fgCol, selectionColorActive)
end,
getSelectionColor = function(self)
return itemSelectedBG, itemSelectedFG
end,
getSelectionBG = function(self)
return itemSelectedBG
end,
getSelectionFG = function(self)
return 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
@@ -173,7 +245,7 @@ return function(name, basalt)
mouseHandler = function(self, button, x, y)
if base.mouseHandler(self, button, x, y) then
local currentLine = 1 - self:getYOffset()
local currentLine = 1 - yOffset
local obx, oby = self:getAbsolutePosition()
local w, h = self:getSize()
local function checkNodeClick(node, level)
@@ -207,8 +279,6 @@ return function(name, basalt)
scrollHandler = function(self, dir, x, y)
if base.scrollHandler(self, dir, x, y) then
local scrollable = self:getScrollable()
local yOffset = self:getYOffset()
if scrollable then
local _, h = self:getSize()
yOffset = yOffset + dir
@@ -240,7 +310,6 @@ return function(name, basalt)
yOffset = yOffset - 1
end
end
self:setYOffset(yOffset)
self:updateDraw()
end
return true
@@ -251,9 +320,6 @@ return function(name, basalt)
draw = function(self)
base.draw(self)
self:addDraw("treeview", function()
local xOffset, yOffset = self:getOffset()
local itemSelectedBG self:getSelectionBackground()
local itemSelectedFG self:getSelectionForeground()
local currentLine = 1 - yOffset
local lastClickedNode = self:getValue()
local function drawNode(node, level)
@@ -281,8 +347,10 @@ return function(name, basalt)
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -3,31 +3,18 @@ local tHex = require("tHex")
local sub, find, insert = string.sub, string.find, table.insert
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
return function(name, basalt)
local base = basalt.getObject("Object")(name, basalt)
base:setType("VisualObject")
-- Base object
local objectType = "VisualObject" -- not changeable
local ignOffset,isHovered,isClicked,isDragging = false,false,false,false
local isVisible,ignOffset,isHovered,isClicked,isDragging = true,false,false,false,false
local zIndex = 1
local dragStartX, dragStartY = 0, 0
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 = {}
@@ -36,54 +23,35 @@ return function(name, basalt)
local renderObject = {}
base:addProperty("Visible", "boolean", true, false, function(self, val)
self:setProperty("Enabled", val)
end)
base:addProperty("Transparent", "boolean", false)
base:addProperty("Background", "color", colors.black)
base:addProperty("BgSymbol", "char", "")
base:addProperty("BgSymbolColor", "color", colors.red)
base:addProperty("Foreground", "color", colors.white)
base:addProperty("X", "number", 1, false, function(self, val)
local y = self:getProperty("Y")
if (parent ~= nil) then
parent:customEventHandler("basalt_FrameReposition", self, val, y)
local function split(str, d)
local result = {}
if str == "" then
return result
end
self:repositionHandler(val, y)
end)
base:addProperty("Y", "number", 1, false, function(self, val)
local x = self:getProperty("X")
if (parent ~= nil) then
parent:customEventHandler("basalt_FrameReposition", self, x, val)
end
self:repositionHandler(x, val)
end)
base:addProperty("Width", "number", 1, false, function(self, val)
local height = self:getProperty("Height")
if (parent ~= nil) then
parent:customEventHandler("basalt_FrameResize", self, val, height)
end
self:resizeHandler(val, height)
end)
base:addProperty("Height", "number", 1, false, function(self, val)
local width = self:getProperty("Width")
if (parent ~= nil) then
parent:customEventHandler("basalt_FrameResize", self, width, val)
end
self:resizeHandler(width, val)
end)
base:addProperty("IgnoreOffset", "boolean", false, false)
base:combineProperty("Position", "X", "Y")
base:combineProperty("Size", "Width", "Height")
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
base:setProperty("Clicked", false)
base:setProperty("Hovered", false)
base:setProperty("Dragging", false)
base:setProperty("Focused", false)
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)
@@ -91,22 +59,36 @@ return function(name, basalt)
end,
show = function(self)
self:setVisible(true)
isVisible = true
self:updateDraw()
return self
end,
hide = function(self)
self:setVisible(false)
isVisible = false
self:updateDraw()
return self
end,
isVisible = function(self)
return self:getVisible()
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)
parent = newParent
base.setParent(self, newParent, noRemove)
parent = newParent
return self
end,
@@ -117,6 +99,19 @@ return function(name, basalt)
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()
@@ -124,7 +119,100 @@ return function(name, basalt)
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,
setX = function(self, newX)
return self:setPosition(newX, y)
end,
getY = function(self)
return y
end,
setY = function(self, newY)
return self:setPosition(x, newY)
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,
setHeight = function(self, newHeight)
return self:setSize(width, newHeight)
end,
getWidth = function(self)
return width
end,
setWidth = function(self, newWidth)
return self:setSize(newWidth, height)
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
@@ -137,24 +225,21 @@ return function(name, basalt)
return x, y
end,
getRelativePosition = function(self, x, y)
if (x == nil) or (y == nil) then
x, y = 1, 1
end
ignoreOffset = function(self, ignore)
ignOffset = ignore
if(ignore==nil)then ignOffset = true end
return self
end,
if (parent ~= nil) then
local xO, yO = self:getAbsolutePosition()
x = xO - x + 1
y = yO - y + 1
end
return x, y
getIgnoreOffset = function(self)
return ignOffset
end,
isCoordsInObject = function(self, x, y)
if(self:getVisible())and(self:getEnabled())then
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()
local w, h = self:getSize()
if (objX <= x) and (objX + w > x) and (objY <= y) and (objY + h > y) then
return true
end
@@ -231,9 +316,7 @@ return function(name, basalt)
end
isClicked = true
isDragging = true
self:setProperty("Dragging", true)
self:setProperty("Clicked", true)
dragStartX, dragStartY = x, y
dragStartX, dragStartY = x, y
return true
end
end,
@@ -244,8 +327,6 @@ return function(name, basalt)
local objX, objY = self:getAbsolutePosition()
local val = self:sendEvent("mouse_release", button, x - (objX-1), y - (objY-1), x, y)
isClicked = false
self:setProperty("Clicked", false)
self:setProperty("Dragging", false)
end
if(self:isCoordsInObject(x, y))then
local objX, objY = self:getAbsolutePosition()
@@ -256,11 +337,11 @@ return function(name, basalt)
end,
dragHandler = function(self, button, x, y)
if(isDragging)then
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(val==false)then return false end
if(parent~=nil)then
parent:setFocusedChild(self)
end
@@ -268,7 +349,9 @@ return function(name, basalt)
end
if(self:isCoordsInObject(x, y))then
dragStartX, dragStartY = x, y
local objX, objY = self:getAbsolutePosition()
dragStartX, dragStartY = x, y
dragXOffset, dragYOffset = objX - x, objY - y
end
end,
@@ -289,19 +372,17 @@ return function(name, basalt)
local val = self:sendEvent("mouse_hover", x, y, stopped)
if(val==false)then return false end
isHovered = true
self:setProperty("Hovered", 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
self:setProperty("Hovered", false)
end
end,
keyHandler = function(self, key, isHolding)
if(self:isEnabled())and(self:getVisible())then
if(self:isEnabled())and(isVisible)then
if (self:isFocused()) then
local val = self:sendEvent("key", key, isHolding)
if(val==false)then return false end
@@ -311,7 +392,7 @@ return function(name, basalt)
end,
keyUpHandler = function(self, key)
if(self:isEnabled())and(self:getVisible())then
if(self:isEnabled())and(isVisible)then
if (self:isFocused()) then
local val = self:sendEvent("key_up", key)
if(val==false)then return false end
@@ -321,7 +402,7 @@ return function(name, basalt)
end,
charHandler = function(self, char)
if(self:isEnabled())and(self:getVisible())then
if(self:isEnabled())and(isVisible)then
if(self:isFocused())then
local val = self:sendEvent("char", char)
if(val==false)then return false end
@@ -332,15 +413,12 @@ return function(name, basalt)
getFocusHandler = function(self)
local val = self:sendEvent("get_focus")
self:setProperty("Focused", true)
if(val~=nil)then return val end
return true
end,
loseFocusHandler = function(self)
isDragging = false
self:setProperty("Dragging", false)
self:setProperty("Focused", false)
local val = self:sendEvent("lose_focus")
if(val~=nil)then return val end
return true
@@ -376,7 +454,7 @@ return function(name, basalt)
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
if(v.name==name)then
v.active = state
break
end
@@ -397,13 +475,12 @@ return function(name, basalt)
addText = function(self, x, y, text)
local obj = self:getParent() or self
local xPos,yPos = self:getPosition()
local transparent = self:getTransparent()
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(transparent)then
if not(transparency)then
obj:setText(x+xPos-1, y+yPos-1, text)
return
end
@@ -415,50 +492,48 @@ return function(name, basalt)
end
end,
addBg = function(self, x, y, bg, noText)
addBG = function(self, x, y, bg, noText)
local obj = parent or self
local xPos,yPos = self:getPosition()
local transparent = self:getTransparent()
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(transparent)then
obj:setBg(x+xPos-1, y+yPos-1, bg)
if not(transparency)then
obj:setBG(x+xPos-1, y+yPos-1, bg)
return
end
local t = split(bg)
for _,v in pairs(t)do
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)
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, v.value)
obj:setBG(x+xPos-1, y+yPos-1, fg)
end
end
end
end,
addFg = function(self, x, y, fg)
addFG = function(self, x, y, fg)
local obj = parent or self
local xPos,yPos = self:getPosition()
local transparent = self:getTransparent()
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(transparent)then
obj:setFg(x+xPos-1, y+yPos-1, fg)
if not(transparency)then
obj:setFG(x+xPos-1, y+yPos-1, fg)
return
end
local t = split(fg)
for _,v in pairs(t)do
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)
obj:setFG(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
end,
@@ -466,32 +541,31 @@ return function(name, basalt)
addBlit = function(self, x, y, t, fg, bg)
local obj = parent or self
local xPos,yPos = self:getPosition()
local transparent = self:getTransparent()
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(transparent)then
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 _,v in pairs(_text)do
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 _,v in pairs(_bg)do
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)
obj:setBG(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
for _,v in pairs(_fg)do
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)
obj:setFG(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
end,
@@ -530,7 +604,7 @@ return function(name, basalt)
end,
render = function(self)
if (self:getVisible())then
if (isVisible)then
self:redraw()
end
end,
@@ -557,25 +631,16 @@ return function(name, basalt)
draw = function(self)
self:addDraw("base", function()
local w,h = self:getSize()
local bgColor = self:getBackground()
local bgSymbol = self:getBgSymbol()
local bgSymbolColor = self:getBgSymbolColor()
local fgColor = self:getForeground()
if(bgColor~=nil)then
if(bgColor~=false)then
self:addTextBox(1, 1, w, h, " ")
self:addBackgroundBox(1, 1, w, h, bgColor)
end
if(bgSymbol~=nil)and(bgSymbol~="")then
self:addTextBox(1, 1, w, h, bgSymbol)
self:addForegroundBox(1, 1, w, h, bgSymbolColor)
end
if(fgColor~=nil)then
if(fgColor~=false)then
self:addForegroundBox(1, 1, w, h, fgColor)
end
end, 1)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -217,16 +217,10 @@ local lerp = {
local XMLParser = require("xmlParser")
local animationCount = 0
local renderThrottleCACHE
return {
VisualObject = function(base, basalt)
local activeAnimations = {}
local defaultMode = "linear"
if(renderThrottleCACHE==nil)then
renderThrottleCACHE = basalt.getRenderingThrottle()
end
local function getAnimation(self, timerId)
for k,v in pairs(activeAnimations)do
@@ -250,10 +244,6 @@ return {
end
activeAnimations[typ].finished = function()
set(self, v1, v2)
animationCount = animationCount - 1
if(animationCount==0)then
basalt.setRenderingThrottle(renderThrottleCACHE)
end
if(f~=nil)then f(self) end
end
@@ -261,8 +251,6 @@ return {
activeAnimations[typ].progress=0
activeAnimations[typ].duration=duration
activeAnimations[typ].mode=mode
animationCount = animationCount + 1
basalt.setRenderingThrottle(0)
self:listenEvent("other_event")
end

View File

@@ -140,11 +140,12 @@ local function makeText(nSize, sString, nFC, nBC, bBlit)
end
-- The following code is related to basalt and has nothing to do with bigfonts, it creates a plugin which will be added to labels:
local XMLParser = require("xmlParser")
return {
Label = function(base)
local fontsize = 1
local bigfont
local object = {
setFontSize = function(self, newFont)
if(type(newFont)=="number")then
@@ -163,30 +164,51 @@ return {
return self
end,
setText = function(self, text)
base.setText(self, text)
if(fontsize>1)then
bigfont = makeText(fontsize-1, self:getText(), self:getForeground(), self:getBackground() or colors.lightGray)
if(self:getAutoSize())then
self:getBase():setSize(#bigfont[1][1], #bigfont[1]-1)
end
end
return self
end,
getFontSize = function(self)
return fontsize
end,
getSize = function(self)
local w, h = base.getSize(self)
if(fontsize>1)and(self:getAutoSize())then
return fontsize==2 and self:getText():len()*3 or math.floor(self:getText():len() * 8.5), fontsize==2 and h * 2 or math.floor(h)
else
return w, h
end
end,
getWidth = function(self)
local w = base.getWidth(self)
if(fontsize>1)and(self:getAutoSize())then
return fontsize==2 and self:getText():len()*3 or math.floor(self:getText():len() * 8.5)
else
return w
end
end,
getHeight = function(self)
local h = base.getHeight(self)
if(fontsize>1)and(self:getAutoSize())then
return fontsize==2 and h * 2 or math.floor(h)
else
return h
end
end,
draw = function(self)
base.draw(self)
self:addDraw("bigfonts", function()
if(fontsize>1)then
local obx, oby = self:getPosition()
local parent = self:getParent()
local oX, oY = parent:getSize()
local cX, cY = #bigfont[1][1], #bigfont[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:addFg(1, i, bigfont[2][i])
self:addBg(1, i, bigfont[3][i])
self:addFG(1, i, bigfont[2][i])
self:addBG(1, i, bigfont[3][i])
self:addText(1, i, bigfont[1][i])
end
end
@@ -195,4 +217,4 @@ return {
}
return object
end
}
}

View File

@@ -74,7 +74,7 @@ return {
end
if(borderColors["bottom"]~=false)and(borderColors["left"]~=false)then
self:addTextBox(1, h, 1, 1, "\138")
if(bgCol~=false)then self:addForegroundBox(1, h, 1, 1, bgCol) end
if(bgCol~=false)then self:addForegroundBox(0, h, 1, 1, bgCol) end
self:addBackgroundBox(1, h, 1, 1, borderColors["left"])
end
end

View File

@@ -3,28 +3,27 @@ local wrapText = utils.wrapText
return {
basalt = function(basalt)
local mainFrame
local mainFrame = basalt.getMainFrame()
local debugFrame
local debugList
local debugLabel
local debugExitButton
local function createDebuggingFrame()
if(mainFrame==nil)then mainFrame = basalt.getMainFrame() end
local minW = 16
local minH = 6
local maxW = 99
local maxH = 99
local w, h = mainFrame:getSize()
debugFrame = mainFrame:addMovableFrame("basaltDebuggingFrame"):setSize(w-10, h-6):setBackground(colors.black):setForeground(colors.white):setZ(100):hide()
debugFrame:addPane():setSize("{parent.w}", 1):setPosition(1, 1):setBackground(colors.cyan):setForeground(colors.black)
debugFrame:setPosition(-w, h/2-debugFrame:getHeight()/2):setBorder(colors.cyan)
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}")
:setPosition("parent.w", "parent.h")
:setSize(1, 1)
:setText("\133")
:setForeground(colors.black)
:setBackground(colors.cyan)
:setForeground(colors.gray)
:setBackground(colors.black)
:onClick(function() end)
:onDrag(function(self, event, btn, xOffset, yOffset)
local w, h = debugFrame:getSize()
@@ -38,21 +37,21 @@ return {
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()
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}")
:setSize("parent.w - 2", "parent.h - 3")
:setPosition(2, 3)
:setBackground(colors.black)
:setBackground(colors.gray)
:setForeground(colors.white)
:setSelectionColor(colors.black, colors.white)
:setSelectionColor(colors.gray, colors.white)
if(debugLabel==nil)then
debugLabel = mainFrame:addLabel()
:setPosition(1, "{parent.h}")
:setPosition(1, "parent.h")
:setBackground(colors.black)
:setForeground(colors.white)
:setZ(100)
:setZIndex(100)
:onClick(function()
debugFrame:show()
debugFrame:animatePosition(w/2-debugFrame:getWidth()/2, h/2-debugFrame:getHeight()/2, 0.5)

View File

@@ -1,212 +1,124 @@
local protectedNames = {clamp=true, round=true, math=true, colors=true}
local function replace(word)
if(protectedNames[word])then return word end
if word:sub(1, 1):find('%a') and not word:find('.', 1, true) then
return '"' .. word .. '"'
end
return word
end
local function parseString(str)
str = str:gsub("{", "")
str = str:gsub("}", "")
for k,v in pairs(colors)do
if(type(k)=="string")then
str = str:gsub("%f[%w]"..k.."%f[%W]", "colors."..k)
end
end
str = str:gsub("(%s?)([%w.]+)", function(a, b) return a .. replace(b) end)
str = str:gsub("%s?%?", " and ")
str = str:gsub("%s?:", " or ")
str = str:gsub("%.w%f[%W]", ".width")
str = str:gsub("%.h%f[%W]", ".height")
return str
end
local function processString(str, env)
env.math = math
env.colors = colors
env.clamp = function(val, min, max)
return math.min(math.max(val, min), max)
end
env.round = function(val)
return math.floor(val + 0.5)
end
local f = load("return " .. str, "", nil, env)
if(f==nil)then error(str.." - is not a valid dynamic value string") end
return f()
end
local function dynamicValue(object, name, dynamicString, basalt)
local objectGroup = {}
local observers = {}
dynamicString = parseString(dynamicString)
local cachedValue = nil
local needsUpdate = true
local function updateFunc()
needsUpdate = true
end
for v in dynamicString:gmatch("%a+%.%a+")do
local name = v:gsub("%.%a+", "")
local prop = v:gsub("%a+%.", "")
if(objectGroup[name]==nil)then
objectGroup[name] = {}
end
table.insert(objectGroup[name], prop)
end
for k,v in pairs(objectGroup) do
if(k=="self") then
for _, b in pairs(v) do
if(name~=b)then
object:addPropertyObserver(b, updateFunc)
if(b=="clicked")or(b=="dragging")then
object:listenEvent("mouse_click")
object:listenEvent("mouse_up")
end
if(b=="dragging")then
object:listenEvent("mouse_drag")
end
if(b=="hovered")then
--object:listenEvent("mouse_enter")
--object:listenEvent("mouse_exit")
end
table.insert(observers, {obj=object, name=b})
else
error("Dynamic Values - self reference to self")
end
end
end
if(k=="parent") then
for _, b in pairs(v) do
object:getParent():addPropertyObserver(b, updateFunc)
table.insert(observers, {obj=object:getParent(), name=b})
end
end
if(k~="self" and k~="parent")and(protectedNames[k]==nil)then
local obj = object:getParent():getChild(k)
for _, b in pairs(v) do
obj:addPropertyObserver(b, updateFunc)
table.insert(observers, {obj=obj, name=b})
end
end
end
local function calculate()
local env = {}
local parent = object:getParent()
for k,v in pairs(objectGroup)do
local objTable = {}
if(k=="self")then
for _,b in pairs(v)do
objTable[b] = object:getProperty(b)
end
end
if(k=="parent")then
for _,b in pairs(v)do
objTable[b] = parent:getProperty(b)
end
end
if(k~="self")and(k~="parent")and(protectedNames[k]==nil)then
local obj = parent:getChild(k)
if(obj==nil)then
error("Dynamic Values - unable to find object: "..k)
end
for _,b in pairs(v)do
objTable[b] = obj:getProperty(b)
end
end
env[k] = objTable
end
return processString(dynamicString, env)
end
return {
get = function(self)
if(needsUpdate)then
cachedValue = calculate() + 0.5
if(type(cachedValue)=="number")then
cachedValue = math.floor(cachedValue + 0.5)
end
needsUpdate = false
object:updatePropertyObservers(name)
end
return cachedValue
end,
removeObservers = function(self)
for _,v in pairs(observers)do
v.obj:removePropertyObserver(v.name, updateFunc)
end
end,
}
end
local utils = require("utils")
local count = utils.tableCount
return {
Object = function(base, basalt)
local observers = {}
local activeDynValues = {}
VisualObject = function(base, basalt)
local dynObjects = {}
local curProperties = {}
local properties = {x="getX", y="getY", w="getWidth", h="getHeight"}
local function filterDynValues(self, name, value)
if(type(value)=="string")and(value:sub(1,1)=="{")and(value:sub(-1)=="}")then
if(activeDynValues[name]~=nil)then
activeDynValues[name].removeObservers()
end
activeDynValues[name] = dynamicValue(self, name, value, basalt)
value = activeDynValues[name].get
end
return value
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
return {
updatePropertyObservers = function(self, name)
if(observers[name]~=nil)then
for _,v in pairs(observers[name])do
v(self, name)
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
return self
end,
end
setProperty = function(self, name, value, rule)
value = filterDynValues(self, name, value)
base.setProperty(self, name, value, rule)
if(observers[name]~=nil)then
for _,v in pairs(observers[name])do
v(self, name)
end
local parent = self:getParent()
local objects = {}
for k,v in pairs(objectGroup)do
objects[v] = parent:getChild(v)
if(objects[v]==nil)then
error("Dynamic Values - unable to find object: "..v)
end
return self
end,
end
objects["self"] = self
objects["parent"] = parent
addPropertyObserver = function(self, name, func)
name = name:gsub("^%l", string.upper)
if(observers[name]==nil)then
observers[name] = {}
end
table.insert(observers[name], func)
end,
removePropertyObserver = function(self, name, func)
name = name:gsub("^%l", string.upper)
if(observers[name]~=nil)then
for k,v in pairs(observers[name])do
if(v==func)then
table.remove(observers[name], k)
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
}
}

View File

@@ -1,321 +0,0 @@
local tHex = require("tHex")
local function line(x1, y1, x2, y2)
local points = {}
local dx = math.abs(x2 - x1)
local dy = math.abs(y2 - y1)
local sx = (x1 < x2) and 1 or -1
local sy = (y1 < y2) and 1 or -1
local err = dx - dy
while true do
table.insert(points, {x = x1, y = y1})
if (x1 == x2 and y1 == y2) then break end
local e2 = err * 2
if e2 > -dy then
err = err - dy
x1 = x1 + sx
end
if e2 < dx then
err = err + dx
y1 = y1 + sy
end
end
return points
end
local function circle(xPos, yPos, radius, filled)
local points = {}
local function plotPoints(xc, yc, x, y)
table.insert(points, {x = xc + x, y = yc + y})
table.insert(points, {x = xc - x, y = yc + y})
table.insert(points, {x = xc + x, y = yc - y})
table.insert(points, {x = xc - x, y = yc - y})
table.insert(points, {x = xc + y, y = yc + x})
table.insert(points, {x = xc - y, y = yc + x})
table.insert(points, {x = xc + y, y = yc - x})
table.insert(points, {x = xc - y, y = yc - x})
end
local function fillPoints(xc, yc, x, y)
for fillX = -x, x do
table.insert(points, {x = xc + fillX, y = yc + y})
table.insert(points, {x = xc + fillX, y = yc - y})
end
for fillY = -y, y do
table.insert(points, {x = xc + fillY, y = yc + x})
table.insert(points, {x = xc + fillY, y = yc - x})
end
end
local x = 0
local y = radius
local d = 3 - 2 * radius
if filled then
fillPoints(xPos, yPos, x, y)
else
plotPoints(xPos, yPos, x, y)
end
while y >= x do
x = x + 1
if d > 0 then
y = y - 1
d = d + 4 * (x - y) + 10
else
d = d + 4 * x + 6
end
if filled then
fillPoints(xPos, yPos, x, y)
else
plotPoints(xPos, yPos, x, y)
end
end
return points
end
local function ellipse(xPos, yPos, radiusX, radiusY, filled)
local points = {}
local function plotPoints(xc, yc, x, y)
table.insert(points, {x = xc + x, y = yc + y})
table.insert(points, {x = xc - x, y = yc + y})
table.insert(points, {x = xc + x, y = yc - y})
table.insert(points, {x = xc - x, y = yc - y})
end
local function fillPoints(xc, yc, x, y)
for fillX = -x, x do
table.insert(points, {x = xc + fillX, y = yc + y})
table.insert(points, {x = xc + fillX, y = yc - y})
end
end
local x = 0
local y = radiusY
local d1 = (radiusY * radiusY) - (radiusX * radiusX * radiusY) + (0.25 * radiusX * radiusX)
plotPoints(xPos, yPos, x, y)
while ((radiusX * radiusX * (y - 0.5)) > (radiusY * radiusY * (x + 1))) do
if (d1 < 0) then
d1 = d1 + (2 * radiusY * radiusY * x) + (3 * radiusY * radiusY)
else
d1 = d1 + (2 * radiusY * radiusY * x) - (2 * radiusX * radiusX * y) + (2 * radiusX * radiusX)
y = y - 1
end
x = x + 1
if filled then fillPoints(xPos, yPos, x, y) end
end
local d2 = ((radiusY * radiusY) * ((x + 0.5) * (x + 0.5))) + ((radiusX * radiusX) * ((y - 1) * (y - 1))) - (radiusX * radiusX * radiusY * radiusY)
while y > 0 do
y = y - 1
if d2 < 0 then
d2 = d2 + (2 * radiusY * radiusY * x) - (2 * radiusX * radiusX * y) + (radiusX * radiusX)
x = x + 1
else
d2 = d2 - (2 * radiusX * radiusX * y) + (radiusX * radiusX)
end
if filled then fillPoints(xPos, yPos, x, y) end
end
return points
end
local function polygon(points, filled)
local newPoints = {}
local pointsCopy = {}
for i, point in ipairs(points) do
table.insert(pointsCopy, {x = point.x, y = point.y})
end
if pointsCopy[1].x ~= pointsCopy[#pointsCopy].x or pointsCopy[1].y ~= pointsCopy[#pointsCopy].y then
table.insert(pointsCopy, {x = pointsCopy[1].x, y = pointsCopy[1].y})
end
local lines = {}
for i = 1, #pointsCopy - 1 do
local linePoints = line(pointsCopy[i].x, pointsCopy[i].y, pointsCopy[i+1].x, pointsCopy[i+1].y)
for _, point in ipairs(linePoints) do
table.insert(lines, point)
end
end
if filled then
local minX, maxX, minY, maxY = math.huge, -math.huge, math.huge, -math.huge
for _, point in ipairs(pointsCopy) do
minX = math.min(minX, point.x)
maxX = math.max(maxX, point.x)
minY = math.min(minY, point.y)
maxY = math.max(maxY, point.y)
end
local fillPoints = {}
for y = minY, maxY do
for x = minX, maxX do
local numCrossings = 0
for i = 1, #pointsCopy - 1 do
if ((pointsCopy[i].y > y) ~= (pointsCopy[i+1].y > y)) and
(x < (pointsCopy[i+1].x - pointsCopy[i].x) * (y - pointsCopy[i].y) /
(pointsCopy[i+1].y - pointsCopy[i].y) + pointsCopy[i].x) then
numCrossings = numCrossings + 1
end
end
if numCrossings % 2 == 1 then
table.insert(fillPoints, {x = x, y = y})
end
end
end
return fillPoints
end
return lines
end
local function rectangle(xPos, yPos, width, height, filled)
local points = {}
if filled then
for y = yPos, yPos + height - 1 do
for x = xPos, xPos + width - 1 do
table.insert(points, {x = x, y = y})
end
end
else
for x = xPos, xPos + width - 1 do
table.insert(points, {x = x, y = yPos})
table.insert(points, {x = x, y = yPos + height - 1})
end
for y = yPos, yPos + height - 1 do
table.insert(points, {x = xPos, y = y})
table.insert(points, {x = xPos + width - 1, y = y})
end
end
return points
end
local rep,sub = string.rep, string.sub
return {
VisualObject = function(base)
local object = {}
for _,v in pairs({"Text", "Bg", "Fg"})do
object["add"..v.."Line"] = function(self, x1, y1, x2, y2, val)
if(type(val)=="number")then
val = tHex[val]
end
if(#val>1)then
val = sub(val, 1, 1)
end
local points = line(x1, y1, x2, y2)
for _,point in ipairs(points)do
self["add"..v](self, point.x, point.y, val)
end
return self
end
object["add"..v.."Circle"] = function(self, xPos, yPos, radius, filled, val)
if(type(val)=="number")then
val = tHex[val]
end
if(#val>1)then
val = sub(val, 1, 1)
end
local points = circle(xPos, yPos, radius, filled)
for _,point in ipairs(points)do
self["add"..v](self, point.x, point.y, val)
end
return self
end
object["add"..v.."Ellipse"] = function(self, xPos, yPos, radiusX, radiusY, filled, val)
if(type(val)=="number")then
val = tHex[val]
end
if(#val>1)then
val = sub(val, 1, 1)
end
local points = ellipse(xPos, yPos, radiusX, radiusY, filled)
for _,point in ipairs(points)do
self["add"..v](self, point.x, point.y, val)
end
return self
end
object["add"..v.."Polygon"] = function(self, points, filled, val)
if(type(val)=="number")then
val = tHex[val]
end
if(#val>1)then
val = sub(val, 1 ,1)
end
local newPoints = polygon(points, filled)
for _,point in ipairs(newPoints)do
self["add"..v](self, point.x, point.y, val)
end
return self
end
object["add"..v.."Rectangle"] = function(self, xPos, yPos, width, height, filled, val)
if(type(val)=="number")then
val = tHex[val]
end
if(#val>1)then
val = sub(val, 1, 1)
end
local points = rectangle(xPos, yPos, width, height, filled)
for _,point in ipairs(points)do
self["add"..v](self, point.x, point.y, val)
end
return self
end
end
--[[
function object.addInlineBorder(self, x, y, width, height, color, bg)
self:addTextBox(x, y, 1, h, "\149")
self:addBackgroundBox(x, y, 1, h, bgCol)
self:addForegroundBox(x, y, 1, h, borderColors["left"])
self:addTextBox(x, y, x+width-1, 1, "\131")
self:addBackgroundBox(x, y, x+width-1, 1, bgCol)
self:addForegroundBox(x, y, x+width-1, 1, borderColors["top"])
self:addTextBox(x, y, 1, 1, "\151")
self:addBackgroundBox(x, y, 1, 1, bgCol)
self:addForegroundBox(x, y, 1, 1, borderColors["left"])
self:addTextBox(x+width-1, 1, 1, h, "\149")
self:addForegroundBox(x+width-1, 1, 1, h, bgCol)
self:addBackgroundBox(x+width-1, 1, 1, h, borderColors["right"])
self:addTextBox(1, h, x+width-1, 1, "\143")
self:addForegroundBox(1, h, x+width-1, 1, bgCol)
self:addBackgroundBox(1, h, x+width-1, 1, borderColors["bottom"])
self:addTextBox(x+width-1, 1, 1, 1, "\148")
self:addForegroundBox(x+width-1, 1, 1, 1, bgCol)
self:addBackgroundBox(x+width-1, 1, 1, 1, borderColors["right"])
self:addTextBox(x+width-1, h, 1, 1, "\133")
self:addForegroundBox(x+width-1, h, 1, 1, bgCol)
self:addBackgroundBox(x+width-1, h, 1, 1, borderColors["right"])
self:addTextBox(1, h, 1, 1, "\138")
self:addForegroundBox(1, h, 1, 1, bgCol)
self:addBackgroundBox(1, h, 1, 1, borderColors["left"])
end]]
return object
end
}

View File

@@ -5,11 +5,11 @@
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:
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.
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

203
Basalt/plugins/reactive.lua Normal file
View File

@@ -0,0 +1,203 @@
local XMLParser = require("xmlParser")
local Reactive = {}
Reactive.currentEffect = nil
Reactive.observable = function(initialValue)
local value = initialValue
local observerEffects = {}
local get = function()
if (Reactive.currentEffect ~= nil) then
table.insert(observerEffects, Reactive.currentEffect)
table.insert(Reactive.currentEffect.dependencies, observerEffects)
end
return value
end
local set = function(newValue)
value = newValue
local observerEffectsCopy = {}
for index, effect in ipairs(observerEffects) do
observerEffectsCopy[index] = effect
end
for _, effect in ipairs(observerEffectsCopy) do
effect.execute()
end
end
return get, set
end
Reactive.untracked = function(getter)
local parentEffect = Reactive.currentEffect
Reactive.currentEffect = nil
local value = getter()
Reactive.currentEffect = parentEffect
return value
end
Reactive.effect = function(effectFn)
local effect = {dependencies = {}}
local execute = function()
Reactive.clearEffectDependencies(effect)
local parentEffect = Reactive.currentEffect
Reactive.currentEffect = effect
effectFn()
Reactive.currentEffect = parentEffect
end
effect.execute = execute
effect.execute()
end
Reactive.derived = function(computeFn)
local getValue, setValue = Reactive.observable();
Reactive.effect(function()
setValue(computeFn())
end)
return getValue;
end
Reactive.clearEffectDependencies = function(effect)
for _, dependency in ipairs(effect.dependencies) do
for index, backlink in ipairs(dependency) do
if (backlink == effect) then
table.remove(dependency, index)
end
end
end
effect.dependencies = {};
end
local Layout = {
fromXML = function(text)
local nodes = XMLParser.parseText(text)
local script = nil
for index, node in ipairs(nodes) do
if (node.tag == "script") then
script = node.value
table.remove(nodes, index)
break
end
end
return {
nodes = nodes,
script = script
}
end
}
local executeScript = function(script, env)
return load(script, nil, "t", env)()
end
local registerFunctionEvent = function(object, event, script, env)
event(object, function(...)
local success, msg = pcall(load(script, nil, "t", env))
if not success then
error("XML Error: "..msg)
end
end)
end
return {
basalt = function(basalt)
local createObjectsFromXMLNode = function(node, env)
local layout = env[node.tag]
if (layout ~= nil) then
local props = {}
for prop, expression in pairs(node.attributes) do
props[prop] = load("return " .. expression, nil, "t", env)
end
return basalt.createObjectsFromLayout(layout, props)
end
local objectName = node.tag:gsub("^%l", string.upper)
local object = basalt:createObject(objectName, node.attributes["id"])
for attribute, expression in pairs(node.attributes) do
if (attribute:sub(1, 2) == "on") then
registerFunctionEvent(object, object[attribute], expression .. "()", env)
else
local update = function()
local value = load("return " .. expression, nil, "t", env)()
object:setProperty(attribute, value)
end
basalt.effect(update)
end
end
for _, child in ipairs(node.children) do
local childObjects = basalt.createObjectsFromXMLNode(child, env)
for _, childObject in ipairs(childObjects) do
object:addChild(childObject)
end
end
return {object}
end
local object = {
observable = Reactive.observable,
untracked = Reactive.untracked,
effect = Reactive.effect,
derived = Reactive.derived,
layout = function(path)
if (not fs.exists(path)) then
error("Can't open file " .. path)
end
local f = fs.open(path, "r")
local text = f.readAll()
f.close()
return Layout.fromXML(text)
end,
createObjectsFromLayout = function(layout, props)
local env = _ENV
env.props = {}
local updateFns = {}
for prop, getFn in pairs(props) do
updateFns[prop] = basalt.derived(function()
return getFn()
end)
end
setmetatable(env.props, {
__index = function(_, k)
return updateFns[k]()
end
})
if (layout.script ~= nil) then
executeScript(layout.script, env)
end
local objects = {}
for _, node in ipairs(layout.nodes) do
local _objects = createObjectsFromXMLNode(node, env)
for _, object in ipairs(_objects) do
table.insert(objects, object)
end
end
return objects
end
}
return object
end,
Container = function(base, basalt)
local object = {
loadLayout = function(self, path, props)
local wrappedProps = {}
if (props == nil) then
props = {}
end
for prop, value in pairs(props) do
wrappedProps[prop] = function()
return value
end
end
local layout = basalt.layout(path)
local objects = basalt.createObjectsFromLayout(layout, wrappedProps)
for _, object in ipairs(objects) do
self:addChild(object)
end
return self
end
}
return object
end
}

View File

@@ -1,142 +0,0 @@
local Reactive = require("reactivePrimitives")
local XMLParser = require("xmlParser")
local Layout = {
fromXML = function(text)
local nodes = XMLParser.parseText(text)
local script = nil
for index, node in ipairs(nodes) do
if (node.tag == "script") then
script = node.value
table.remove(nodes, index)
break
end
end
return {
nodes = nodes,
script = script
}
end
}
local executeScript = function(script, env)
return load(script, nil, "t", env)()
end
local registerFunctionEvent = function(object, event, script, env)
event(object, function(...)
local success, msg = pcall(function()
Reactive.transaction(load(script, nil, "t", env))
end)
if not success then
error("XML Error: "..msg)
end
end)
end
return {
basalt = function(basalt)
local object = {
observable = Reactive.observable,
derived = Reactive.derived,
effect = Reactive.effect,
transaction = Reactive.transaction,
untracked = Reactive.untracked,
layout = function(path)
if (not fs.exists(path)) then
error("Can't open file " .. path)
end
local f = fs.open(path, "r")
local text = f.readAll()
f.close()
return Layout.fromXML(text)
end,
createObjectsFromXMLNode = function(node, env)
local layout = env[node.tag]
if (layout ~= nil) then
local props = {}
for prop, expression in pairs(node.attributes) do
props[prop] = load("return " .. expression, nil, "t", env)
end
return basalt.createObjectsFromLayout(layout, props)
end
local objectName = node.tag:gsub("^%l", string.upper)
local object = basalt:createObject(objectName, node.attributes["id"])
for attribute, expression in pairs(node.attributes) do
if (attribute:sub(1, 2) == "on") then
registerFunctionEvent(object, object[attribute], expression .. "()", env)
else
Reactive.effect(function()
local value = load("return " .. expression, nil, "t", env)()
if(colors[value]~=nil)then value = colors[value] end
object:setProperty(attribute, value)
end)
end
end
for _, child in ipairs(node.children) do
local childObjects = basalt.createObjectsFromXMLNode(child, env)
for _, childObject in ipairs(childObjects) do
object:addChild(childObject)
end
end
return {object}
end,
createObjectsFromLayout = function(layout, props)
local env = _ENV
env.props = {}
local updateFns = {}
for prop, getFn in pairs(props) do
updateFns[prop] = basalt.derived(function()
return getFn()
end)
end
setmetatable(env.props, {
__index = function(_, k)
return updateFns[k]()
end
})
if (layout.script ~= nil) then
Reactive.transaction(function()
executeScript(layout.script, env)
end)
end
local objects = {}
for _, node in ipairs(layout.nodes) do
local _objects = basalt.createObjectsFromXMLNode(node, env)
for _, object in ipairs(_objects) do
table.insert(objects, object)
end
end
return objects
end
}
return object
end,
Container = function(base, basalt)
local object = {
loadLayout = function(self, path, props)
local wrappedProps = {}
if (props == nil) then
props = {}
end
for prop, value in pairs(props) do
wrappedProps[prop] = function()
return value
end
end
local layout = basalt.layout(path)
local objects = basalt.createObjectsFromLayout(layout, wrappedProps)
for _, object in ipairs(objects) do
self:addChild(object)
end
return self
end
}
return object
end
}

View File

@@ -1,3 +1,5 @@
local XMLParser = require("xmlParser")
return {
VisualObject = function(base)
local shadow = false

View File

@@ -1,132 +0,0 @@
local split = require("utils").splitString
local function copy(t)
local new = {}
for k,v in pairs(t)do
new[k] = v
end
return new
end
local plugin = {
VisualObject = function(base, basalt)
return {
__getElementPathTypes = function(self, types)
if(types~=nil)then
table.insert(types, 1, self:getTypes())
else
types = {self:getTypes()}
end
local parent = self:getParent()
if(parent~=nil)then
return parent:__getElementPathTypes(types)
else
return types
end
end,
init = function(self)
base.init(self)
local template = basalt.getTemplate(self)
local objects = basalt.getObjects()
if(template~=nil)then
for k,v in pairs(template)do
if(objects[k]==nil)then
if(colors[v]~=nil)then
self:setProperty(k, colors[v])
else
self:setProperty(k, v)
end
end
end
end
return self
end,
}
end,
basalt = function()
local baseTemplate = {
default = {
Background = colors.gray,
Foreground = colors.black,
},
BaseFrame = {
Background = colors.lightGray,
Foreground = colors.black,
Button = {
Background = "{self.clicked ? black : gray}",
Foreground = "{self.clicked ? lightGray : black}"
},
Container = {
Background = colors.gray,
Foreground = colors.black,
Button = {
Background = "{self.clicked ? lightGray : black}",
Foreground = "{self.clicked ? black : lightGray}"
},
},
Checkbox = {
Background = colors.gray,
Foreground = colors.black,
Text = "Checkbox"
},
Input = {
Background = "{self.focused ? gray : black}",
Foreground = "{self.focused ? black : lightGray}",
},
},
}
local function addTemplate(newTemplate)
if(type(newTemplate)=="string")then
local file = fs.open(newTemplate, "r")
if(file~=nil)then
local data = file.readAll()
file.close()
baseTemplate = textutils.unserializeJSON(data)
else
error("Could not open template file "..newTemplate)
end
end
if(type(newTemplate)=="table")then
for k,v in pairs(newTemplate)do
baseTemplate[k] = v
end
end
end
local function lookUpTemplate(template, allTypes)
local elementData = copy(baseTemplate.default)
local tLink = template
if(tLink~=nil)then
for _, v in pairs(allTypes)do
for _, b in pairs(v)do
if(tLink[b]~=nil)then
tLink = tLink[b]
for k, v in pairs(tLink) do
elementData[k] = v
end
break
else
for k, v in pairs(baseTemplate.default) do
elementData[k] = v
end
end
end
end
end
return elementData
end
return {
getTemplate = function(element)
return lookUpTemplate(baseTemplate, element:__getElementPathTypes())
end,
addTemplate = addTemplate,
}
end
}
return plugin

View File

@@ -1,87 +1,58 @@
local images = require("images")
local sub = string.sub
local utils = require("utils")
local XMLParser = require("xmlParser")
return {
VisualObject = function(base)
local images = {}
local textureId, infinitePlay = 1, true
local bimg, texture, textureTimerId
local textureMode = "default"
local object = {
addTexture = function(self, path, x, y, w, h, stretch, animate, infinitePlay)
if(type(path)=="function")then
table.insert(images, path)
else
if(type(path)=="table")then
x, y, w, h, stretch, animate, infinitePlay = path.x, path.y, path.w, path.h, path.stretch, path.animate, path.infinitePlay
path = path.path
end
local img = images.loadImageAsBimg(path)
local newEntry = {
image = img,
x = x,
y = y,
w = w,
h = h,
animated = animate,
curTextId = 1,
infinitePlay = infinitePlay,
}
if(stretch)then
newEntry.w = self:getWidth()
newEntry.h = self:getHeight()
newEntry.image = images.resizeBIMG(img, newEntry.w, newEntry.h)
end
table.insert(images, newEntry)
if(animate)then
if(img.animated)then
self:listenEvent("other_event")
local t = img[newEntry.curTextId].duration or img.secondsPerFrame or 0.2
newEntry.timer = os.startTimer(t)
end
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,
removeTexture = function(self, id)
table.remove(images, id)
if(#images==0)then
self:setDrawState("texture-base", false)
end
setTextureMode = function(self, mode)
textureMode = mode or textureMode
self:updateDraw()
return self
end,
clearTextures = function(self)
images = {}
self:setDrawState("texture-base", false)
self:updateDraw()
setInfinitePlay = function(self, state)
infinitePlay = state
return self
end,
eventHandler = function(self, event, timerId, ...)
base.eventHandler(self, event, timerId, ...)
if(event=="timer")then
for _,v in pairs(images)do
if(type(v)=="table")then
if(v.timer==timerId)then
if(v.animated)then
if(v.image[v.curTextId+1]~=nil)then
v.curTextId = v.curTextId + 1
local t = v.image[v.curTextId].duration or v.image.secondsPerFrame or 0.2
v.timer = os.startTimer(t)
self:updateDraw()
else
if(v.infinitePlay)then
v.curTextId = 1
local t = v.image[v.curTextId].duration or v.image.secondsPerFrame or 0.2
v.timer = os.startTimer(t)
self:updateDraw()
end
end
end
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
@@ -91,25 +62,50 @@ return {
draw = function(self)
base.draw(self)
self:addDraw("texture-base", function()
for _,v in pairs(images)do
if(type(v)=="table")then
local tWidth = #v.image[v.curTextId][1][1]
local tHeight = #v.image[v.curTextId][1]
local textureWidth = v.w>tWidth and tWidth or v.w
local textureHeight = v.h>tHeight and tHeight or v.h
for k = 1, textureHeight do
if(v.image[k]~=nil)then
local t, f, b = table.unpack(v.image[k])
self:addBlit(1, k, sub(t, 1, textureWidth), sub(f, 1, textureWidth), sub(b, 1, textureWidth))
end
end
else
if(type(v)=="function")then
v(self)
end
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)
end, 1)
self:setDrawState("texture-base", false)
end
}

View File

@@ -1,3 +1,3 @@
---
Thanks for checking out our wiki, join our discord for more help: [discord.gg/yM7kndJdJJ](discord.gg/yNNnmBVBpE)
Thanks for checking out our wiki, join our discord for more help: [https://discord.gg/yM7kndJdJJ](discord.gg/yNNnmBVBpE)

View File

@@ -37,5 +37,4 @@
- [Timer](objects/Timer.md)
- Guides
- [Introduction to Basalt](guides/introduction.md)
- [Dynamic Values](guides/dynamicvalues.md)
- [XML](guides/xml.md)

View File

@@ -21,7 +21,7 @@ You are now able to access the following list of methods:
|[getVersion](objects/Basalt/getVersion.md)|Returns the Basalt version
|[isKeyDown](objects/Basalt/isKeyDown.md)|Returns if the key is held down
|[log](objects/Basalt/log.md)|Writes something into the log file
|[memory](objects/Basalt/log.md)|Returns the current memory usage of Basalt
|[memory](objects/Basalt/memory.md)|Returns the current memory usage of Basalt
|[onEvent](objects/Basalt/onEvent.md)|Event listener
|[removeFrame](objects/Basalt/removeFrame.md)|Removes a previously created base frame
|[schedule](objects/Basalt/schedule.md)|Schedules a new task
@@ -29,7 +29,7 @@ You are now able to access the following list of methods:
|[setTheme](objects/Basalt/setTheme.md)|Changes the base theme of basalt
|[setMouseDragThrottle](objects/Basalt/setMouseDragThrottle.md)|Changes the mouse drag throttle amount
|[setMouseMoveThrottle](objects/Basalt/setMouseMoveThrottle.md)|CraftOS-PC: Changes the mouse move throttle amount
|[setRenderingThrottle](objects/Basalt/setMouseMoveThrottle.md)|Sets the rendering throttle amount
|[setRenderingThrottle](objects/Basalt/setRenderingThrottle.md)|Sets the rendering throttle amount
|[setVariable](objects/Basalt/setVariable.md)|Sets a variable which you can access via XML
|[stopUpdate / stop](objects/Basalt/stopUpdate.md)|Stops the currently active event and draw listener
|[update](objects/Basalt/update.md)|Starts the event and draw listener once

View File

@@ -11,8 +11,7 @@ Sets the frame's offset, this offset is beeing used to move all children object'
### Returns
1. `number` x position
2. `number` y position
1. `object` The object in use
### Usage

View File

@@ -1,6 +1,6 @@
The Checkbox object is derived from the VisualObject class and allows users to set a boolean value to true or false by clicking on it. Checkboxes are commonly used in forms and settings to enable or disable specific options.
The Checkbox object is derived from the ChangeableObject class and allows users to set a boolean value to true or false by clicking on it. Checkboxes are commonly used in forms and settings to enable or disable specific options.
In addition to the Object and VisualObject methods, checkboxes also have the following method:
In addition to the Object, VisualObject and ChangeableObject methods, checkboxes also have the following method:
| | |
|---|---|

View File

@@ -6,7 +6,7 @@ Sets the specified object as "important" within the container. This means the ob
### Parameters
1. `string` The object to set as important
1. `string|object` The object ID or object to set as important
### Returns

View File

@@ -1,4 +1,4 @@
## setFocusedObject
## updateZIndex
### Description

View File

@@ -0,0 +1,27 @@
## blit
### Description
Sets or modifies text, foreground and background color.
### Parameters
1. `string` text - The text to be placed at the specified position
1. `string` foreground - A string representing the foreground color
1. `string` background - A string representing the background color
2. `number` x - The x-coordinate of the text position.
3. `number` y - The y-coordinate of the text position.
### Returns
1. `object` The object in use
### Usage
* Creates a new image object, adds a frame, and sets the text in the active frame.
```lua
local mainFrame = basalt.createFrame()
local aImage = mainFrame:addImage():addFrame():blit("Hello", "fffff", "00000", 1, 1)
```

View File

@@ -0,0 +1,9 @@
## getOffset
### Description
Returns the current offset
### Returns
1. `number` the offset

View File

@@ -0,0 +1,9 @@
## getTextOffset
### Description
Returns the current text offset
### Returns
1. `number` the text offset

View File

@@ -0,0 +1,22 @@
## setOffset
### Description
Sets the input offset
### Parameters
1. `number` offset - The offset you want it to be
### Returns
1. `object` The object in use
### Usage
* Creates a default input and changes the offset to 2
```lua
local mainFrame = basalt.createFrame()
local aInput = mainFrame:addInput():setOffset(2)
```

View File

@@ -0,0 +1,22 @@
## setTextOffset
### Description
Sets the input text offset
### Parameters
1. `number` text offset - The offset you want it to be
### Returns
1. `object` The object in use
### Usage
* Creates a default input and changes the text offset to 2
```lua
local mainFrame = basalt.createFrame()
local aInput = mainFrame:addInput():setTextOffset(2)
```

View File

@@ -2,7 +2,6 @@ A Label object is used to display simple text on the interface.
In addition to the Object and VisualObject methods, Label objects have the following methods:
[Object](objects/Object.md) methods also apply for labels.
| | |
|---|---|

View File

@@ -12,13 +12,13 @@ In addition to the Object and VisualObject methods, Textfield objects have the f
|[getTextCursor](objects/Textfield/getTextCursor.md)|Returns the current text cursor position
|[addKeywords](objects/Textfield/addKeywords.md)|Adds syntax highlighting keywords
|[addRule](objects/Textfield/addRule.md)|Adds a custom syntax highlighting rule
|[editRule](objects/Textfield/addRule.md)|Edits an existing syntax highlighting rule
|[removeRule](objects/Textfield/addRule.md)|Removes an existing syntax highlighting rule
|[getOffset](objects/Textfield/addRule.md)|Returns the current offset inside the Textfield
|[setOffset](objects/Textfield/addRule.md)|Changes the offset inside the Textfield
|[clear](objects/Textfield/addRule.md)|Clears the Textfield content
|[setSelection](objects/Textfield/addRule.md)|Sets the selection color (text color and background color)
|[getSelection](objects/Textfield/addRule.md)|Returns the current selection color
|[editRule](objects/Textfield/editRule.md)|Edits an existing syntax highlighting rule
|[removeRule](objects/Textfield/removeRule.md)|Removes an existing syntax highlighting rule
|[getOffset](objects/Textfield/getOffset.md)|Returns the current offset inside the Textfield
|[setOffset](objects/Textfield/setOffset.md)|Changes the offset inside the Textfield
|[clear](objects/Textfield/clear.md)|Clears the Textfield content
|[setSelection](objects/Textfield/setSelection.md)|Sets the selection color (text color and background color)
|[getSelection](objects/Textfield/getSelection.md)|Returns the current selection color
In version 1.7, Textfields now allow the user to select text with the mouse. The setSelection method is used to choose the text color and background color for selected text.

View File

@@ -0,0 +1,23 @@
## clear
### Description
Clears the entire content of a Textfield object, removing all text currently displayed within it.
### Returns
1. `object ` The object in use
### Usage
```lua
local basalt = require("basalt")
local mainFrame = basalt.createFrame()
local aTextfield = mainFrame:addTextfield()
-- Assume there is some content in the Textfield
aTextfield:clear() -- Clear the entire content
basalt.autoUpdate()
```

View File

@@ -0,0 +1,30 @@
## addRule
### Description
Edits an existing rule for special coloring in a Textfield object. This allows you to modify the color and/or background color applied to text matching a specific pattern.
### Parameteres
1. `string` pattern - The Lua pattern used to match the text you want to edit the coloring for.
2. `number|color` textColor - The new color you want to apply to the text matching the pattern.
3. `number|color` backgroundColor - (optional) The new background color you want to apply to the text matching the pattern.
### Returns
1. `object` The object in use
### Usage
* Modifies the color of all numbers in a Textfield object.
```lua
local basalt = require("basalt")
local mainFrame = basalt.createFrame()
local aTextfield = mainFrame:addTextfield()
aTextfield:editRule("%d", colors.red) -- Changes the color of numbers to red
basalt.autoUpdate()
```

View File

@@ -0,0 +1,26 @@
## getOffset
### Description
Retrieves the current offset within a Textfield object, providing information about the current viewable portion of the text.
### Returns
1. `number` The current horizontal offset within the Textfield.
2. `number` The current vertical offset within the Textfield.
### Usage
```lua
local basalt = require("basalt")
local mainFrame = basalt.createFrame()
local aTextfield = mainFrame:addTextfield()
-- Assume the Textfield has been scrolled previously
local xOffset, yOffset = aTextfield:getOffset()
basalt.debug("Horizontal Offset: "..xOffset)
basalt.debug("Vertical Offset: "..yOffset)
basalt.autoUpdate()
```

View File

@@ -0,0 +1,10 @@
## setSelection
### Description
Returns the colors when selecting a text.
### Returns
1. `number|color` foreground color - The text color.
2. `number|color` background color - ´The background color.

View File

@@ -0,0 +1,28 @@
## removeRule
### Description
Removes an existing rule for special coloring in a Textfield object. This allows you to remove the coloring applied to text matching a specific pattern.
### Parameteres
1. `string` pattern - The Lua pattern used to match the text for which the rule was applied.
### Returns
1. `object` The object in use
### Usage
* Removes the rule for coloring all numbers in a Textfield object
```lua
local basalt = require("basalt")
local mainFrame = basalt.createFrame()
local aTextfield = mainFrame:addTextfield()
aTextfield:removeRule("%d") -- Removes the rule for coloring numbers
basalt.autoUpdate()
```

View File

@@ -0,0 +1,28 @@
## setOffset
### Description
Sets the offset within a Textfield object, allowing you to adjust the viewable portion of the text.
### Parameteres
1. `number` xOffset - The horizontal offset to set within the Textfield
2. `number` yOffset - The vertical offset to set within the Textfield
### Returns
1. `object` The object in use
### Usage
```lua
local basalt = require("basalt")
local mainFrame = basalt.createFrame()
local aTextfield = mainFrame:addTextfield()
-- Scroll 10 units down vertically
aTextfield:setOffset(0, 10)
basalt.autoUpdate()
```

View File

@@ -0,0 +1,27 @@
## setSelection
### Description
Changes the color when selecting text.
### Parameteres
1. `number|color` foreground color - The text color.
2. `number|color` background color - ´The background color.
### Returns
1. `object` The object in use
### Usage
```lua
local basalt = require("basalt")
local mainFrame = basalt.createFrame()
local aTextfield = mainFrame:addTextfield()
aTextfield:setSelection(colors.white, colors.blue)
basalt.autoUpdate()
```

View File

@@ -1,291 +0,0 @@
local bot_id = "" -- put the bot id between the ""!
local servers = { -- setup the server/channels here, look at the example.
[""] = {
"",
},
--[[ Example:
["SERVER_ID"] = {
"CHANNEL_ID",
"CHANNEL_ID",
"CHANNEL_ID",
},
["SERVER_ID"] = {
"CHANNEL_ID",
"CHANNEL_ID",
"CHANNEL_ID",
},
]]
}
if(bot_id=="")then
error("Please setup the bot id and servers/channels first!")
end
--Basalt configurated installer
local filePath = "basalt.lua" --here you can change the file path default: basalt.lua
if not(fs.exists(filePath))then
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
end
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
local main = basalt.createFrame():setBackground(colors.lightGray)
local loginFrame = main:addFrame():setBackground(colors.lightGray)
local messageFrameList = main:addFrame():setPosition("parent.w+1", 1):setBackground(colors.black):setScrollable(true):setImportantScroll(true)
local refreshRate = 2
local messageFrames = {}
local availableGuilds = {}
local channel_id = ""
for k,v in pairs(servers)do
if(v[1]~=nil)then
channel_id = v[1]
end
break
end
local function getAllGuilds(bot)
local content = http.get("https://discord.com/api/users/@me/guilds", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
if(content~=nil)then
return textutils.unserializeJSON(content.readAll())
end
end
local function getAllChannels(bot, guild)
local content = http.get("https://discord.com/api/guilds/"..guild.."/channels", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
if(content~=nil)then
local t = {}
for k,v in pairs(textutils.unserializeJSON(content.readAll()))do
table.insert(t, v.position, v)
end
return t
end
end
local splitString = function(str, sep)
if sep == nil then
sep = "%s"
end
local t={}
for v in string.gmatch(str, "([^"..sep.."]+)") do
table.insert(t, v)
end
if(#t==0)then table.insert(t,str) end
return t
end
local function createText(str, width)
local uniqueLines = splitString(str, "\n")
local lines = {}
for k,v in pairs(uniqueLines)do
local line = ""
local words = splitString(v, " ")
for a,b in pairs(words)do
if(#line+#b <= width)then
line = line=="" and b or line.." "..b
if(a==#words)then table.insert(lines, line) end
else
table.insert(lines, line)
line = b:sub(1,width)
if(a==#words)then table.insert(lines, line) end
end
end
end
return lines
end
local maxOffset = 0
local autoOffset = true
local function newMessage(position, msg, username, sendTime)
local lines = createText(msg, messageFrameList:getWidth()-5)
if(messageFrames[position]==nil)then
if(messageFrames[position-1]~=nil)then
messageFrames[position] = messageFrameList:addFrame("message"..tostring(position)):setPosition(2, "message"..(position-1)..".y + message"..(position-1)..".h")
else
messageFrames[position] = messageFrameList:addFrame("message"..tostring(position)):setPosition(2, 1)
end
messageFrames[position]:addLabel("title")
messageFrames[position]:addLabel("body")
end
maxOffset = maxOffset + #lines+3
if(autoOffset)then
messageFrameList:setOffset(0, maxOffset - messageFrameList:getHeight()+1)
end
messageFrames[position]:setSize("parent.w-1", #lines+3):setBackground(colors.black)
messageFrames[position]:getObject("title"):setSize("parent.w-2", 1):setPosition(2,1):setText(username):setForeground(colors.lightGray):setBackground(colors.gray)
messageFrames[position]:getObject("body"):setSize("parent.w-2", #lines+1):setPosition(2,3):setText(msg):setForeground(colors.lightGray)
end
local function updateDiscordMessages(channel, bot)
if(channel~=nil)and(bot~=nil)then
currentMessages = {}
local content = http.get("https://discord.com/api/channels/"..channel.."/messages?limit=25", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
if(content~=nil)then
local t = textutils.unserializeJSON(content.readAll())
local tR = {}
for i=#t, 1, -1 do
tR[#tR+1] = t[i]
end
for k,v in pairs(tR)do
newMessage(k, v.content, v.author.username, v.time)
end
end
end
end
local animations = {}
local function offsetAnimation(obj, x, y, t)
if(animations[obj:getName()]~=nil)then animations[obj:getName()]:cancel() end
animations[obj:getName()] = main:addAnimation():setAutoDestroy(true):setObject(obj):offset(x, y, t or 1):play()
end
local function positionAnimation(obj, x, y, t)
if(animations[obj:getName()]~=nil)then animations[obj:getName()]:cancel() end
animations[obj:getName()] = main:addAnimation():setAutoDestroy(true):setObject(obj):move(x, y, t or 1):play()
end
local sideBar = messageFrameList:addFrame():setPosition(-18, 1):setSize(20, "parent.h"):setZIndex(17):ignoreOffset():setScrollable(true):setImportantScroll(true)
sideBar:addButton():setText("Back"):setForeground(colors.lightGray):setBackground(colors.black):setPosition(3,2):setSize("parent.w - 4", 3):onClick(function()
offsetAnimation(main, 0, 0)
positionAnimation(sideBar, -18, 1)
end)
sideBar:addLabel():setText("Channels:"):setForeground(colors.black):setPosition(2,6)
sideBar:onClick(function(self, event)
if(event=="mouse_click")then
positionAnimation(self, 1, 1)
messageFrameList:setImportantScroll(false)
end
end)
sideBar:onLoseFocus(function()
positionAnimation(sideBar, -18, 1)
messageFrameList:setImportantScroll(true)
end)
local newTextFrame = messageFrameList:addFrame():setSize("parent.w - 4", 10):setPosition(3, 1):setZIndex(16):ignoreOffset():setBackground(colors.gray):setAnchor("bottomLeft")
local msgInfo = newTextFrame:addLabel():setText("Click here to write a message")
local messageField = newTextFrame:addTextfield():setSize("parent.w-2", "parent.h-4"):setPosition(2,3):setBackground(colors.lightGray)
newTextFrame:onClick(function(self, event)
if(event=="mouse_click")then
positionAnimation(self, 3, -8, 0.5)
messageFrameList:setImportantScroll(false)
msgInfo:setText("New Message:")
end
end)
messageFrameList:onScroll(function()
local xO, yO = messageFrameList:getOffset()
messageFrameList:getMaxScroll()
if(yO==messageFrameList:getMaxScroll())then
autoOffset = true
else
autoOffset = false
end
end)
local function messageBoxLoseFocus()
positionAnimation(newTextFrame, 3, 1, 0.5)
messageFrameList:setImportantScroll(true)
msgInfo:setText("Click here to write a message")
messageField:clear()
end
newTextFrame:addButton():setText("Cancel"):setAnchor("bottomLeft"):setBackground(colors.black):setForeground(colors.lightGray):setSize(12,1):setPosition(2,1):onClick(function()
messageBoxLoseFocus()
end)
newTextFrame:onLoseFocus(messageBoxLoseFocus)
loginFrame:addLabel():setAnchor("center"):setPosition(-2, -1):setText("Username:")
local nameInput = loginFrame:addInput():setAnchor("center"):setPosition(3,0):setBackground(colors.black):setForeground(colors.lightGray):setSize(16,1):setDefaultText("Username...", colors.gray)
local serverList = loginFrame:addList():setPosition(3, 6):setSize(16, 10)
local channelRadio = sideBar:addRadio():setForeground(colors.black):setBackground(colors.gray):setSelectedItem(colors.gray, colors.lightGray):setActiveSymbol(" ")
local channelObjects = {}
local updateChannels = basalt.shedule(function()
if(bot_id~=nil)then
for k,v in pairs(channelObjects)do
sideBar:removeObject(v)
end
channelObjects = {}
if(serverList:getValue().args~=nil)then
local y = 8
local maxScroll = 2
for k,v in pairs(servers[serverList:getValue().args[1]])do
local content = http.get("https://discord.com/api/channels/"..v, {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot_id})
local channel = textutils.unserializeJSON(content.readAll())
if(channel~=nil)then
channelRadio:addItem("#"..channel.name,1, y, nil,nil,v)
y = y + 1
maxScroll = maxScroll + 1
end
end
end
end
end)
serverList:onChange(updateChannels)
basalt.shedule(function()
if(bot_id~=nil)then
for k,v in pairs(servers)do
local content = http.get("https://discord.com/api/guilds/"..k, {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot_id})
local guild = textutils.unserializeJSON(content.readAll())
if(guild~=nil)then
serverList:addItem(guild.name,nil,nil,k)
end
end
end
end)()
updateChannels()
channelRadio:onChange(function(self)
local val = self:getValue()
if(val~=nil)and(val.args[1]~=nil)then
channel_id = val.args[1]
end
end)
loginFrame:addButton():setAnchor("bottomRight"):setPosition(-10, -2):setSize(11,3):setText("Login"):onClick(function()
offsetAnimation(main, main:getWidth(), 0)
end)
loginFrame:addLabel():setPosition(3, 5):setText("Servers:")
local function sendDiscordMessage(msg, channel, bot)
if(channel~=nil)and(bot~=nil)then
if(nameInput:getValue()~="")then
msg = string.gsub(msg, "\n", "\\n")
http.post("https://discord.com/api/channels/"..channel.."/messages", '{ "content": "['..nameInput:getValue()..']: '..msg..'" }', {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
end
end
end
newTextFrame:addButton():setText("Send"):setAnchor("bottomRight"):setBackground(colors.black):setForeground(colors.lightGray):setSize(12,1):setPosition(-11,1)
:onClick(function()
local msg = table.concat(messageField:getLines(), "\n")
if(#msg>0)then
sendDiscordMessage(msg, channel_id, bot_id)
end
messageBoxLoseFocus()
end)
local function refreshMessages()
while true do
maxOffset = 0
updateDiscordMessages(channel_id, bot_id)
maxOffset = maxOffset - messageFrameList:getHeight()+1
messageFrameList:setMaxScroll(maxOffset)
sleep(refreshRate)
end
end
local thread = main:addThread():start(refreshMessages)
basalt.autoUpdate()

View File

@@ -1,51 +0,0 @@
-- This is a example on how to use progressbars for energy. I used the Mekanism Ultimate Energy Cube.
--Basalt configurated installer
local filePath = "basalt.lua" --here you can change the file path default: basalt
if not(fs.exists(filePath))then
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
end
local basalt = require(filePath:gsub(".lua", ""))
local energyCube = peripheral.find("ultimateEnergyCube")
local main = basalt.createFrame()
local progressText = main:addLabel()
:setText(0)
:setForeground(colors.gray)
:setBackground(false)
:setPosition(10, 3)
:setZIndex(6)
local energyProgress = main:addProgressbar()
:setSize(20,3)
:setPosition(2,2)
:setBackground(colors.black)
:setProgressBar(colors.green)
energyProgress:onChange(function()
local energy = tostring(energyCube.getEnergy())
progressText:setText(energy)
progressText:setPosition(energyProgress:getWidth()/2+1 - math.floor(energy:len()/2), 3)
end)
local function checkCurrentEnergy()
while true do
energyCube = peripheral.find("ultimateEnergyCube")
if(energyCube~=nil)then
local energyCalculation = energyCube.getEnergy() / energyCube.getMaxEnergy() * 100
energyProgress:setProgress(energyCalculation)
else
energyProgress:setProgress(0)
os.sleep(3)
end
os.sleep(1)
end
end
main:addThread():start(checkCurrentEnergy)
basalt.autoUpdate()

View File

@@ -1,49 +0,0 @@
--Basalt configurated installer
local filePath = "basalt.lua" --here you can change the file path default: basalt
if not(fs.exists(filePath))then
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
end
-- toastonrye's example: Redstone Analog Output
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
local w, h = term.getSize() -- dimensions to use when drawing the sub frame
local main = basalt.createFrame()
:show()
:setBackground(colours.blue) -- using colours to easily determine what frame I'm in
local sub = main:addFrame()
:setPosition(2,2)
:setSize(w-2,h-2)
:setBackground(colours.lightBlue)
local rFrame = sub:addFrame("redstoneFrame")
:setPosition(1,1)
:setSize(25,5)
:setMovable(true)
:setBackground(colours.red)
-- Redstone Analog Output
local redstoneAnalog = rFrame:addLabel() -- label that displays the value of the slider & Redstone output
:setPosition(18,3):setText("1")
redstone.setAnalogOutput("left", 1) -- initialize the redstone output to 1, to match the above label
rFrame:addLabel() -- draw a label on the frame
:setText("Redstone Analog Output")
:setPosition(1,2)
rFrame:addSlider()
:setPosition(1,3)
:onChange(function(self) -- when a player interacts with the slider, update the variable redstoneAnalog
redstoneAnalog:setText(self:getValue())
end)
:setMaxValue(15) -- max value of the slider, default 8. Redstone has 15 levels (16 including 0)
:setSize(15,1) -- draw the slider to this size, without this redstoneAnalog value can have decimals
redstoneAnalog:onChange(function(self) -- when the slider value changes, change the Redstone output to match
redstone.setAnalogOutput("left", tonumber(self:getValue()))
basalt.debug(self:getValue())
end)
basalt.autoUpdate()

View File

@@ -1,38 +0,0 @@
-- Hello, here is a small example on how to create resizeable frames, the default anchor (where you have to click on) will be bottom right.
local basalt = require("basalt")
local main = basalt.createFrame()
local sub = main:addFrame() -- the frame we want to resize
:setPosition(3,3)
:setSize(25,8)
:setMovable()
:setBorder(colors.black)
sub:addLabel() -- the new way to create a bar on the top
:setText("Topbar")
:setSize("parent.w",1)
:setBackground(colors.black)
:setForeground(colors.lightGray)
sub:addButton()
:setAnchor("bottomRight")
:setPosition(1, 1)
:setText("/")
:setSize(1,1)
:onDrag(function(self, button, x, y, xOffset, yOffset)
local w, h = sub:getSize()
if(w-xOffset>5)and(h-yOffset>3)then -- dont allow it to be smaller than w5 and h3
sub:setSize(-xOffset, -yOffset, true) -- x-/yOffset is always -1 0 or 1, true means add the value to the current size instead of set it
end
end)
sub:addButton() -- just a random button to show dynamic values
:setPosition(2,3)
:setBackground(colors.black)
:setForeground(colors.lightGray)
:setSize("parent.w-2", 3) -- parent.w means get the parent's width which is the sub frame in this case, -2 means remove 2 from it's result. You could also use * / % or even math.random(12)
basalt.autoUpdate()