- Dyn Values Update
- Template Update
- Property System
- Texture System Update
This commit is contained in:
Robert Jelic
2023-06-15 18:22:43 +02:00
parent 8f370a0106
commit 4d2aad4155
41 changed files with 2007 additions and 2096 deletions

View File

@@ -1,6 +1,4 @@
local tHex = require("tHex")
local utils = require("utils")
local split = utils.splitString
local sub,rep = string.sub,string.rep
return function(drawTerm)
@@ -42,20 +40,14 @@ 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 newCacheT, newCacheFG, newCacheBG
local startN = x < 1 and 1 - x + 1 or 1
local endN = x + #t > width and width - x + 1 or #t
local oldCacheT, oldCacheFG, oldCacheBG = cacheT[y], cacheFG[y], cacheBG[y]
local startN, endN = 1, #t
if x < 1 then
startN = 1 - x + 1
endN = width - x + 1
elseif x + #t > width then
endN = width - x + 1
end
newCacheT = sub(oldCacheT, 1, x - 1) .. sub(t, startN, endN)
newCacheFG = sub(oldCacheFG, 1, x - 1) .. sub(fg, startN, endN)
newCacheBG = sub(oldCacheBG, 1, x - 1) .. sub(bg, startN, endN)
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)
if x + #t <= width then
newCacheT = newCacheT .. sub(oldCacheT, x + #t, width)
@@ -94,7 +86,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
@@ -119,7 +111,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
@@ -144,32 +136,6 @@ 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
@@ -180,17 +146,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)
@@ -199,13 +165,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,3 +1,5 @@
local tableCount = require("utils").tableCount
return function()
local events = {}
@@ -18,7 +20,7 @@ return function()
end,
getEventCount = function(self, _event)
return events[_event]~=nil and #events[_event] or 0
return _event~=nil and events[_event]~=nil and tableCount(events[_event]) or tableCount(events)
end,
getEvents = function(self)

View File

@@ -9,8 +9,9 @@ local wrapText = utils.wrapText
local count = utils.tableCount
local moveThrottle = 300
local dragThrottle = 0
local renderingThrottle = 0
local renderingThrottle = 50
local newObjects = {}
local mousePos = {0, 0}
local baseTerm = term.current()
local version = "1.7.0"
@@ -19,6 +20,7 @@ local projectDirectory = fs.getDir(table.pack(...)[2] or "")
local activeKey, frames, monFrames, variables, schedules = {}, {}, {}, {}, {}
local mainFrame, activeFrame, focusedObject, updaterActive
local renderingTimer = nil
local basalt = {}
@@ -82,11 +84,39 @@ 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,
@@ -239,7 +269,6 @@ local function mouseDragEvent(_, b, x, y)
end
local renderingTimer = nil
local function renderingUpdateTimer()
renderingTimer = nil
drawFrames()
@@ -269,6 +298,10 @@ 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()
@@ -379,9 +412,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
@@ -433,6 +466,9 @@ basalt = {
end
return objectNames
end,
getMousePosition = function()
return mousePos[1], mousePos[2]
end,
setVariable = setVariable,
getVariable = getVariable,
@@ -467,14 +503,9 @@ basalt = {
return false
end,
setRenderingThrottle = function(amount)
if(amount<=0)then
renderingThrottle = 0
else
renderingTimer = nil
renderingThrottle = amount
end
end,
setRenderingThrottle = setRenderingThrottle,
getRenderingThrottle = getRenderingThrottle,
setMouseDragThrottle = function(amount)
if(amount<=0)then
@@ -559,7 +590,6 @@ basalt = {
createFrame = createFrame,
addMonitor = function(name)
InitializeBasalt()
for _, v in pairs(frames) do
if (v:getName() == name) then
return nil

View File

@@ -5,9 +5,7 @@ local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("Container")(name, basalt)
local objectType = "BaseFrame"
local xOffset, yOffset = 0, 0
base:setType("BaseFrame")
local colorTheme = {}
@@ -18,49 +16,27 @@ return function(name, basalt)
local xCursor, yCursor, cursorBlink, cursorColor = 1, 1, false, colors.white
local object = {
getType = function()
return objectType
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
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)
end
end)
base:setSize(termObject.getSize())
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,
setPalette = function(self, col, ...)
if(self==basalt.getActiveFrame())then
if(type(col)=="string")then
local col = colors[col]
col = colors[col]
colorTheme[math.log(col, 2)] = ...
termObject.setPaletteColor(col, ...)
elseif(type(col)=="table")then
@@ -84,18 +60,6 @@ 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)
@@ -151,20 +115,6 @@ 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()
@@ -216,7 +166,7 @@ return function(name, basalt)
end
end
for _,v in pairs({"setBG", "setFG", "setText"}) do
for _,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,62 +4,29 @@ local tHex = require("tHex")
return function(name, basalt)
-- Button
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Button"
local textHorizontalAlign = "center"
local textVerticalAlign = "center"
local text = "Button"
base:setType("Button")
base:setSize(12, 3)
base:setZIndex(5)
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")
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)
@@ -68,7 +35,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,26 +1,21 @@
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
-- Base object
local objectType = "ChangeableObject"
base:setType("ChangeableObject")
local value
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)
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
@@ -29,10 +24,6 @@ return function(name, basalt)
end
return self
end,
valueChangedHandler = function(self)
self:sendEvent("value_changed", value)
end,
}
object.__index = object

View File

@@ -4,13 +4,18 @@ local tHex = require("tHex")
return function(name, basalt)
-- Checkbox
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Checkbox"
base:setType("Checkbox")
base:setZIndex(5)
base:setZ(5)
base:setValue(false)
base:setSize(1, 1)
local symbol,inactiveSymbol,text,textPos = "\42"," ","","right"
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 object = {
load = function(self)
@@ -18,58 +23,6 @@ return function(name, basalt)
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,
@@ -92,10 +45,13 @@ 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,9 +1,10 @@
local utils = require("utils")
local tableCount = utils.tableCount
local rpairs = utils.rpairs
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Container"
base:setType("Container")
local children = {}
@@ -66,7 +67,7 @@ return function(name, basalt)
return
end
objId = objId + 1
local zIndex = element:getZIndex()
local zIndex = element:getZ()
table.insert(children, {element = element, zIndex = zIndex, objId = objId})
sorted = false
element:setParent(self, true)
@@ -95,11 +96,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)
@@ -110,7 +111,8 @@ return function(name, basalt)
objId = 0
evId = 0
focusedChild = nil
if parent ~= nil then parent:removeEvents(self) end
parent:removeEvents(self)
self:updateEvents()
end
local function updateZIndex(self, element, newZ)
@@ -145,7 +147,10 @@ return function(name, basalt)
end
if(tableCount(events[a])<=0)then
if(parent~=nil)then
parent:removeEvent(a, self)
if(self:getEventSystem().getEventCount(a)<=0)then
parent:removeEvent(a, self)
self:updateEvents()
end
end
end
end
@@ -167,7 +172,7 @@ return function(name, basalt)
if (getEvent(self, event, element:getName()) ~= nil) then
return
end
local zIndex = element:getZIndex()
local zIndex = element:getZ()
evId = evId + 1
if(events[event]==nil)then events[event] = {} end
table.insert(events[event], {element = element, zIndex = zIndex, evId = evId})
@@ -195,18 +200,10 @@ return function(name, basalt)
end
container = {
getType = function()
return objectType
end,
getBase = function(self)
return base
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
setSize = function(self, ...)
base.setSize(self, ...)
self:customEventHandler("basalt_FrameResize")
@@ -309,6 +306,23 @@ return function(name, basalt)
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,
getDeepChildren = getDeepChild,

View File

@@ -3,31 +3,21 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("List")(name, basalt)
local objectType = "Dropdown"
base:setType("Dropdown")
base:setSize(12, 1)
base:setZIndex(6)
base:setZ(6)
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
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 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)
@@ -35,84 +25,49 @@ 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(autoSize)then
dropdownW = math.max(dropdownW, #t)
dropdownH = dropdownH + 1
if(self:getAutoSize())then
local dropdownW, dropdownH = self:getDropdownSize()
self:setDropdownSize(math.max(dropdownW, #t), dropdownH + 1)
end
return self
end,
removeItem = function(self, index)
base.removeItem(self, index)
if(autoSize)then
local list = self:getAll()
if(self:getAutoSize())then
local dropdownW, dropdownH = self:getDropdownSize()
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 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
return self:getOpened()
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 + yOffset] ~= nil) then
if (list[n + offset] ~= nil) then
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
self:setValue(list[n + yOffset])
self:setValue(list[n + offset])
self:selectHandler()
self:updateDraw()
local val = self:sendEvent("mouse_click", self, "mouse_click", button, x, y)
if(val==false)then return val end
@@ -131,29 +86,32 @@ return function(name, basalt)
end
local base = base:getBase()
if (base.mouseHandler(self, button, x, y)) then
isOpened = not isOpened
self:setOpened(not isOpened)
self:getParent():setImportant(self)
self:updateDraw()
return true
else
if(isOpened)then
self:updateDraw()
isOpened = false
self:setOpened(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 + yOffset] ~= nil) then
if (list[n + offset] ~= nil) then
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
isOpened = false
self:setOpened(false)
self:updateDraw()
local val = self:sendEvent("mouse_up", self, "mouse_up", button, x, y)
if(val==false)then return val end
@@ -168,11 +126,13 @@ return function(name, basalt)
dragHandler = function(self, btn, x, y)
if(base.dragHandler(self, btn, x, y))then
isOpened = true
self:setOpened(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
@@ -187,19 +147,21 @@ return function(name, basalt)
if(#self:getAll() <= dropdownH)then return false end
local list = self:getAll()
yOffset = yOffset + dir
if (yOffset < 0) then
yOffset = 0
local offset = self:getOffset() + dir
if (offset < 0) then
offset = 0
end
if (dir == 1) then
if (#list > dropdownH) then
if (yOffset > #list - dropdownH) then
yOffset = #list - dropdownH
if (offset > #list - dropdownH) then
offset = #list - dropdownH
end
else
yOffset = math.min(#list - 1, 0)
offset = 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()
@@ -211,11 +173,16 @@ 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))
@@ -224,17 +191,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 + yOffset] ~= nil) then
local t =utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align)
if (list[n + yOffset] == val) then
if (list[n + offset] ~= nil) then
local t =utils.getTextHorizontalAlign(list[n + offset].text, dropdownW, align)
if (list[n + offset] == 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 + yOffset].fgCol]:rep(#t), tHex[list[n + yOffset].bgCol]:rep(#t))
self:addBlit(1, n+1, t, tHex[list[n + offset].fgCol]:rep(#t), tHex[list[n + offset].bgCol]:rep(#t))
end
else
self:addBlit(1, n+1, t, tHex[list[n + yOffset].fgCol]:rep(#t), tHex[list[n + yOffset].bgCol]:rep(#t))
self:addBlit(1, n+1, t, tHex[list[n + offset].fgCol]:rep(#t), tHex[list[n + offset].bgCol]:rep(#t))
end
end
end

View File

@@ -1,39 +1,14 @@
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 = {
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,
getBaseSize = function(self)
return baseWidth, baseHeight
end,
@@ -61,15 +36,29 @@ end
return function(name, basalt)
local base = basalt.getObject("ScrollableFrame")(name, basalt)
local objectType = "Flexbox"
base:setType("Flexbox")
local updateLayout = false
base:addProperty("FlexDirection", {"row", "column"}, "row", nil, function(self, direction)
if(direction=="row")then
self:setScrollDirection("horizontal")
elseif(direction=="column")then
self:setScrollDirection("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 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,
@@ -79,10 +68,15 @@ return function(name, basalt)
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,
})
lineBreakFakeObject:setFlexBasis(0):setFlexGrow(0):setFlexShrink(0)
local function sortChildren(self)
local direction = self:getDirection()
local spacing = self:getSpacing()
local wrap = self:getWrap()
if(wrap=="nowrap")then
sortedChildren = {}
local index = 1
@@ -146,6 +140,9 @@ 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
@@ -234,6 +231,9 @@ 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
@@ -324,7 +324,7 @@ return function(name, basalt)
local function applyLayout(self)
sortChildren(self)
if direction == "row" then
if self:getDirection() == "row" then
for _,v in pairs(sortedChildren)do
calculateRow(self, v)
end
@@ -337,58 +337,6 @@ 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()
@@ -431,4 +379,3 @@ return function(name, basalt)
object.__index = object
return setmetatable(object, base)
end

View File

@@ -4,56 +4,21 @@ local max,min,sub,rep,len = math.max,math.min,string.sub,string.rep,string.len
return function(name, basalt)
local base = basalt.getObject("Container")(name, basalt)
local objectType = "Frame"
base:setType("Frame")
local parent
local updateRender = true
local xOffset, yOffset = 0, 0
base:setSize(30, 10)
base:setZIndex(10)
base:setZ(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,
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, ...)
base.setParent(self, p, ...)
parent = p
@@ -103,7 +68,7 @@ return function(name, basalt)
end,
}
for k,v in pairs({"drawBackgroundBox", "drawForegroundBox", "drawTextBox"})do
for _,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()
@@ -115,7 +80,7 @@ return function(name, basalt)
end
end
for k,v in pairs({"setBG", "setFG", "setText"})do
for _,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,50 +1,24 @@
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Graph"
local base = basalt.getObject("VisualObject")(name, basalt)
base:setType("Graph")
base:setZIndex(5)
base:setZ(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()
@@ -55,48 +29,6 @@ return function(name, basalt)
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()
@@ -106,9 +38,14 @@ 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 bgCol, fgCol = self:getBackground(), self:getForeground()
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 range = maxValue - minValue
local prev_x, prev_y

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)
local objectType = "Image"
base:setType("Image")
local bimgLibrary = bimg()
local bimgFrame = bimgLibrary.getFrameObject(1)
@@ -16,11 +16,14 @@ return function(name, basalt)
local animTimer
local usePalette = false
local autoSize = true
local x, y = 1, 1
local xOffset, yOffset = 0, 0
base:addProperty("XOffset", "number", 0)
base:addProperty("YOffset", "number", 0)
base:combineProperty("Offset", "XOffset", "YOffset")
base:setSize(24, 8)
base:setZIndex(2)
base:setZ(2)
local function getPalette()
local p = {}
@@ -53,51 +56,12 @@ 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)
@@ -145,7 +109,7 @@ return function(name, basalt)
loadImage = function(self, path)
if(fs.exists(path))then
local newBimg = images.loadImageAsBimg(path)
local newBimg = images.loadBIMG(path)
bimgLibrary = bimg(newBimg)
activeFrame = 1
bimgFrame = bimgLibrary.getFrameObject(1)
@@ -334,10 +298,11 @@ return function(name, basalt)
end
if(usePalette)then
self:getParent():setPalette(getPalette(activeFrame))
self:getParent():setPalette(getPalette())
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,21 +4,26 @@ local tHex = require("tHex")
return function(name, basalt)
-- Input
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Input"
base:setType("Input")
local inputType = "text"
local inputLimit = 0
base:setZIndex(5)
base:setZ(5)
base:setValue("")
base:setSize(12, 1)
local textX = 1
local wIndex = 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 defaultText = ""
local defaultBGCol = colors.black
local defaultFGCol = colors.lightGray
local showingText = defaultText
local internalValueChange = false
local object = {
@@ -30,73 +35,13 @@ 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
textX = tostring(val):len() + 1
wIndex = math.max(1, textX-self:getWidth()+1)
local textX = tostring(val):len() + 1
local wIndex = math.max(1, textX-self:getWidth()+1)
self:setOffset(wIndex)
self:setCursorPosition(textX)
if(self:isFocused())then
local parent = self:getParent()
local obx, oby = self:getPosition()
@@ -107,39 +52,23 @@ 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 obx, oby = self:getPosition()
local defaultText = self:getDefaultText()
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 = defaultText
if(defaultText~="")then
showingText = self:getDefaultText()
if(showingText~="")then
self:updateDraw()
end
parent:setCursor(false)
@@ -150,9 +79,11 @@ 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(base.getValue())
local text = tostring(self:getValue())
if (textX > 1) then
self:setValue(text:sub(1, textX - 2) .. text:sub(textX, text:len()))
textX = math.max(textX - 1, 1)
@@ -165,7 +96,7 @@ return function(name, basalt)
parent:clearFocusedChild(self)
end
if (key == keys.right) then
local tLength = tostring(base.getValue()):len()
local tLength = tostring(self:getValue()):len()
textX = textX + 1
if (textX > tLength) then
@@ -189,9 +120,18 @@ return function(name, basalt)
textX = math.max(textX, 1)
wIndex = math.max(wIndex, 1)
end
local obx, oby = self:getPosition()
local val = tostring(base.getValue())
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)
self:updateDraw()
internalValueChange = false
return true
@@ -201,8 +141,12 @@ 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 = base.getValue()
local text = tostring(self:getValue())
local inputType = self:getInputType()
local inputLimit = self:getInputLimit()
if (text:len() < inputLimit or inputLimit <= 0) then
if (inputType == "number") then
local cache = text
@@ -210,7 +154,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(base.getValue()) == nil) then
if (tonumber(self:getValue()) == nil) then
self:setValue(cache)
textX = textX - 1
end
@@ -223,9 +167,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()
@@ -235,12 +179,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 w, h = self:getSize()
local wIndex = self:getOffset()
local textX = self:getCursorPosition()
textX = x - obx + wIndex
local text = base.getValue()
local text = tostring(self:getValue())
if (textX > text:len()) then
textX = text:len() + 1
end
@@ -250,7 +194,8 @@ return function(name, basalt)
wIndex = 1
end
end
parent:setCursor(true, ax + textX - wIndex, ay+math.max(math.ceil(h/2-1, 1)), self:getForeground())
self:setOffset(wIndex)
self:setCursorPosition(textX)
return true
end
end,
@@ -270,7 +215,24 @@ return function(name, basalt)
eventHandler = function(self, event, paste, ...)
base.eventHandler(self, event, paste, ...)
if(event=="paste")then
self:setValue(self:getValue()..paste)
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,
@@ -280,16 +242,24 @@ return function(name, basalt)
local parent = self:getParent()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
local wIndex = self:getOffset()
local textX = self:getCursorPosition()
local defaultBGCol = self:getDefaultBackground()
local defaultFGCol = self:getDefaultForeground()
local inputType = self:getInputType()
local val = tostring(base.getValue())
local verticalAlign = utils.getTextVerticalAlign(h, "center")
local val = tostring(self:getValue() or "")
local bCol = self:getBackground()
local fCol = self:getForeground()
local text
if (val:len() <= 0) then
text = showingText
bCol = defaultBGCol or bCol
fCol = defaultFGCol or fCol
if not(self:isFocused())then
text = showingText
bCol = defaultBGCol or bCol
fCol = defaultFGCol or fCol
end
end
text = showingText

View File

@@ -1,123 +1,65 @@
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)
local objectType = "Label"
base:setType("Label")
base:setZIndex(3)
base:setZ(3)
base:setSize(5, 1)
base:setBackground(false)
local fgChanged = false
local autoSize = true
local text, textAlign = "Label", "left"
base:addProperty("text", "string", "Label", nil, function(self, value)
local autoSize = self:getAutoSize()
if(autoSize)then
local t = wrapText(value, #value)
local newW, newH = 1,1
for _,v in pairs(t)do
newH = newH+1
newW = math.max(newW, v:len())
end
self:setSize(newW, newH)
self:setAutoSize(true)
end
end)
base:addProperty("autoSize", "boolean", true)
base:addProperty("textAlign", {"left", "center", "right"}, "left")
local object = {
--- Returns the object type.
--- @return string
getType = function(self)
return objectType
init = function(self)
base.init(self)
local parent = self:getParent()
self:setBackground(nil)
self:setForeground(parent:getForeground())
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,
setForeground = function(self, col)
base.setForeground(self, col)
fgChanged = true
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)
autoSize = false
self:setAutoSize(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()
if not(fgChanged)then
self:setForeground(parent:getForeground())
end
end
}
object.__index = object

View File

@@ -3,22 +3,23 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "List"
base:setType("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:setZIndex(5)
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)
local object = {
init = function(self)
local parent = self:getParent()
self:listenEvent("mouse_click")
self:listenEvent("mouse_drag")
self:listenEvent("mouse_scroll")
@@ -29,27 +30,6 @@ 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
@@ -73,16 +53,6 @@ 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)
@@ -143,69 +113,29 @@ 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()
yOffset = yOffset + dir
if (yOffset < 0) then
yOffset = 0
offset = offset + dir
if (offset < 0) then
offset = 0
end
if (dir >= 1) then
if (#list > h) then
if (yOffset > #list - h) then
yOffset = #list - h
if (offset > #list - h) then
offset = #list - h
end
if (yOffset >= #list) then
yOffset = #list - 1
if (offset >= #list) then
offset = #list - 1
end
else
yOffset = yOffset - 1
offset = offset - 1
end
end
self:setOffset(offset)
self:updateDraw()
end
return true
@@ -218,10 +148,11 @@ 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 + yOffset] ~= nil) then
if (list[n + offset] ~= nil) then
if (obx <= x) and (obx + w > x) and (oby + n - 1 == y) then
self:setValue(list[n + yOffset])
self:setValue(list[n + offset])
self:selectHandler()
self:updateDraw()
end
@@ -258,16 +189,21 @@ 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 + 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
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
fg, bg = itemSelectedFG, itemSelectedBG
end
self:addText(1, n, t:sub(1,w))
self:addBG(1, n, tHex[bg]:rep(w))
self:addFG(1, n, tHex[fg]:rep(w))
self:addText(1, n, t:sub(1, w))
self:addFg(1, n, tHex[fg]:rep(w))
self:addBg(1, n, tHex[bg]: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)
local objectType = "Menubar"
base:setType("Menubar")
local object = {}
base:setSize(30, 1)
base:setZIndex(5)
base:setZ(5)
local itemOffset = 0
local space, outerSpace = 1, 1
local scrollable = true
base:addProperty("ItemOffset", "number", 0)
base:addProperty("Space", "number", 1)
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,52 +25,29 @@ 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:sendEvent(event, self, event, 0, x, y, list[n])
self:selectHandler()
end
xPos = xPos + list[n].text:len() + space * 2
end
@@ -82,7 +59,9 @@ 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
@@ -93,6 +72,7 @@ return function(name, basalt)
if (itemOffset > mScroll) then
itemOffset = mScroll
end
self:setItemOffset(itemOffset)
self:updateDraw()
end
return true
@@ -103,12 +83,13 @@ 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,54 +4,37 @@ local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("BaseFrame")(name, basalt)
local objectType = "MonitorFrame"
base: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)
base:setTerm(nil)
local isMonitorGroup = false
local monGroup
local object = {
getType = function()
return objectType
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
getBase = function(self)
return base
end,
setMonitor = function(self, newMon)
if(type(newMon)=="string")then
local mon = peripheral.wrap(newMon)
if(mon~=nil)then
self:setTerm(mon)
end
elseif(type(newMon)=="table")then
self:setTerm(newMon)
end
return self
end,
setMonitorGroup = function(self, monGrp)
monGroup = basaltMon(monGrp)
self:setTerm(monGroup)
isMonitorGroup = true
return self
end,
render = function(self)
if(self:getTerm()~=nil)then
base.render(self)
end
end,
}
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,33 +2,15 @@ local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("Frame")(name, basalt)
local objectType = "MovableFrame"
base:setType("MovableFrame")
local parent
local dragXOffset, dragYOffset, isDragging = 0, 0, false
local renderThrottle = basalt.getRenderingThrottle()
local dragMap = {
{x1 = 1, x2 = "width", y1 = 1, y2 = 1}
}
base:addProperty("DraggingMap", "table", {{x1 = 1, x2 = "width", y1 = 1, y2 = 1}})
local object = {
getType = function()
return objectType
end,
setDraggingMap = function(self, t)
dragMap = t
return self
end,
getDraggingMap = function(self)
return dragMap
end,
isType = function(self, t)
return objectType==t or (base.isType~=nil and base.isType(t)) or false
end,
getBase = function(self)
return base
end,
@@ -65,10 +47,13 @@ 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
@@ -81,6 +66,7 @@ return function(name, basalt)
mouseUpHandler = function(self, ...)
isDragging = false
basalt.setRenderingThrottle(0)
return base.mouseUpHandler(self, ...)
end,

View File

@@ -1,5 +1,6 @@
local basaltEvent = require("basaltEvent")
local utils = require("utils")
local split = utils.splitString
local uuid = utils.uuid
local unpack,sub = table.unpack,string.sub
@@ -9,52 +10,191 @@ return function(name, basalt)
assert(basalt~=nil, "Unable to find basalt instance! ID: "..name)
-- Base object
local objectType = "Object" -- not changeable
local isEnabled,initialized = true,false
local initialized = 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(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(not isValid)then
if(type(typ)=="table")then
typ = table.concat(typ, ", ")
end
error(self:getType()..": Invalid type for property "..name.."! Expected "..typ..", got "..type(value))
end
return value
end
end
local parent
local object
local object = {
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,
getParent = function(self)
return parent
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
end,
setParent = function(self, newParent, noRemove)
@@ -62,14 +202,15 @@ 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)
@@ -93,22 +234,18 @@ return function(name, basalt)
return self
end,
getZIndex = function(self)
return 1
end,
enable = function(self)
isEnabled = true
self:setProperty("Enabled", true)
return self
end,
disable = function(self)
isEnabled = false
self:setProperty("Enabled", false)
return self
end,
isEnabled = function(self)
return isEnabled
return self:getProperty("Enabled")
end,
remove = function(self)
@@ -282,6 +419,24 @@ 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,15 +1,11 @@
return function(name, basalt)
-- Pane
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Pane"
base:setType("Pane")
base:setSize(25, 10)
local object = {
getType = function(self)
return objectType
end,
}
local object = {}
object.__index = object
return setmetatable(object, base)

View File

@@ -5,10 +5,11 @@ local sub = string.sub
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Program"
base:setType("Program")
local object
local cachedPath
local enviroment = {}
base:addProperty("Path", "string", nil)
base:addProperty("Enviroment", "table", nil)
local function createBasaltWindow(x, y, width, height)
local xCursor, yCursor = 1, 1
@@ -346,7 +347,7 @@ return function(name, basalt)
return basaltwindow
end
base:setZIndex(5)
base:setZ(5)
base:setSize(30, 12)
local pWindow = createBasaltWindow(1, 1, 30, 12)
local curProcess
@@ -405,23 +406,19 @@ 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)
@@ -431,32 +428,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)
@@ -477,7 +474,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, ...)
@@ -495,7 +492,7 @@ return function(name, basalt)
end
parent:removeEvents(self)
return self
end;
end,
pause = function(self, p)
paused = p or (not paused)
@@ -508,11 +505,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
@@ -525,16 +522,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
@@ -545,7 +542,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
@@ -684,10 +681,6 @@ 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,
@@ -698,7 +691,6 @@ return function(name, basalt)
self:registerEvent("program_error", v)
end
end
local parent = self:getParent()
self:listenEvent("other_event")
return self
end,
@@ -709,7 +701,6 @@ 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,96 +1,30 @@
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Progressbar"
base:setType("ProgressBar")
local progress = 0
base:setZIndex(5)
base:setZ(5)
base:setValue(false)
base:setSize(25, 3)
local activeBarColor = colors.black
local activeBarSymbol = ""
local activeBarSymbolCol = colors.white
local bgBarSymbol = ""
local direction = 0
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", "char", "")
base:addProperty("ActiveBarColor", "color", colors.black)
base:addProperty("ActiveBarSymbolColor", "color", colors.white)
base:combineProperty("ProgressBar", "ActiveBarColor", "ActiveBarSymbol", "ActiveBarSymbolColor")
base:addProperty("BackgroundSymbol", "char", "")
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
@@ -103,28 +37,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 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)
local p = self:getProperties()
local activeBarColor, activeBarSymbol, activeBarSymbolCol = self:getProgressBar()
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)
else
self:addBackgroundBox(1, 1, math.ceil( w / 100 * progress), h, activeBarColor)
self:addForegroundBox(1, 1, math.ceil(w / 100 * progress), h, activeBarSymbolCol)
self:addTextBox(1, 1, math.ceil(w / 100 * progress), h, activeBarSymbol)
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)
end
end)
end,

View File

@@ -3,25 +3,26 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("List")(name, basalt)
local objectType = "Radio"
base:setType("Radio")
base:setSize(1, 1)
base:setZIndex(5)
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")
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 })
@@ -47,58 +48,6 @@ 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()
@@ -106,6 +55,7 @@ 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
@@ -119,6 +69,9 @@ 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,13 +1,30 @@
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)
local objectType = "ScrollableFrame"
local parent
base:setType("ScrollableFrame")
local direction = 0
local manualScrollAmount = 0
local calculateScrollAmount = true
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 function getHorizontalScrollAmount(self)
local amount = 0
@@ -59,36 +76,51 @@ return function(name, basalt)
local function scrollHandler(self, dir)
local xO, yO = self:getOffset()
local scrollAmn
if(direction==1)then
local direction = self:getDirection()
local calculateScrollAmount = self:getAutoCalculate()
local manualScrollAmount = self:getScrollAmount()
local scrollSpeed = self:getScrollSpeed()
if(direction=="horizontal")then
scrollAmn = calculateScrollAmount and getHorizontalScrollAmount(self) or manualScrollAmount
self:setOffset(min(scrollAmn, max(0, xO + dir)), yO)
elseif(direction==0)then
self:setOffset(min(scrollAmn, max(0, xO + dir * scrollSpeed)), yO)
elseif(direction=="vertical")then
scrollAmn = calculateScrollAmount and getVerticalScrollAmount(self) or manualScrollAmount
self:setOffset(xO, min(scrollAmn, max(0, yO + dir)))
self:setOffset(xO, min(scrollAmn, max(0, yO + dir * scrollSpeed)))
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 = {
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,
@@ -97,17 +129,16 @@ return function(name, basalt)
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")
end,
setParent = function(self, p, ...)
base.setParent(self, p, ...)
parent = p
return self
self:listenEvent("mouse_drag")
self:listenEvent("mouse_click")
self:listenEvent("mouse_up")
end,
scrollHandler = function(self, dir, x, y)
@@ -119,7 +150,7 @@ 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
@@ -133,13 +164,90 @@ return function(name, basalt)
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("scrollableFrame", function()
if(calculateScrollAmount)then
scrollHandler(self, 0)
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
end
end, 0)
end)
end,
}

View File

@@ -2,33 +2,43 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Scrollbar"
base:setType("Scrollbar")
base:setZIndex(2)
base:setZ(2)
base:setSize(1, 8)
base:setBackground(colors.lightGray, "\127", colors.gray)
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)
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
symbolSize = math.max((barType == "vertical" and h or w-(#symbol)) - (scrollAmount-1), 1)
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))
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, button, x, y)
local function mouseEvent(self, _, 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
@@ -40,99 +50,31 @@ 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)
@@ -163,6 +105,9 @@ 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()
@@ -193,18 +138,17 @@ return function(name, basalt)
draw = function(self)
base.draw(self)
self:addDraw("scrollbar", function()
local parent = self:getParent()
local w,h = self:getSize()
local bgCol,fgCol = self:getBackground(), self:getForeground()
if (barType == "horizontal") then
local p = self:getProperties()
local w, h = p.Width, p.Height
if (p.BarType == "horizontal") then
for n = 0, h - 1 do
self:addBlit(index, 1 + n, symbol:rep(symbolSize), tHex[symbolFG]:rep(#symbol*symbolSize), tHex[symbolBG]:rep(#symbol*symbolSize))
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))
end
elseif (barType == "vertical") then
elseif (p.BarType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self:addBlit(1, index + curIndexOffset, symbol:rep(math.max(#symbol, w)), tHex[symbolFG]:rep(math.max(#symbol, w)), tHex[symbolBG]:rep(math.max(#symbol, w)))
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)))
end
end
end

View File

@@ -2,24 +2,29 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Slider"
base:setType("Slider")
base:setSize(12, 1)
base:setValue(1)
base:setBackground(false, "\140", colors.black)
local barType = "horizontal"
local symbol = " "
local symbolFG = colors.black
local symbolBG = colors.gray
local maxValue = 12
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 index = 1
local symbolSize = 1
local function mouseEvent(self, button, x, y)
local function mouseEvent(self, _, 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))
@@ -30,32 +35,27 @@ return function(name, basalt)
end
local object = {
getType = function(self)
return objectType
init = function(self)
base.init(self)
base:setBgSymbol("\140")
base:setBgSymbolColor(colors.black)
base:setBackground(nil)
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,35 +66,6 @@ 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)
@@ -118,6 +89,9 @@ 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()
@@ -131,21 +105,27 @@ 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, 1, 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
self:addText(index, oby, symbol:rep(symbolSize))
if(symbolBG~=false)then self:addBg(index, 1, tHex[symbolBG]:rep(#symbol*symbolSize)) end
if(symbolFG~=false)then self:addFg(index, 1, tHex[symbolFG]:rep(#symbol*symbolSize)) end
end
if (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self:addBlit(1, 1+n+curIndexOffset, symbol, tHex[symbolColor], tHex[symbolColor])
self:addBlit(1, 1+n+curIndexOffset, symbol, tHex[symbolFG], tHex[symbolFG])
end
else
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
self:addBlit(1, 1+n, bgSymbol, tHex[fgCol], tHex[bgCol])
self:addBlit(1, 1+n, " ", tHex[fgCol], tHex[bgCol])
end
end
end

View File

@@ -1,48 +1,16 @@
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Switch"
base:setType("Switch")
base:setSize(4, 1)
base:setValue(false)
base:setZIndex(5)
base:setZ(5)
local bgSymbol = colors.black
local inactiveBG = colors.red
local activeBG = colors.green
base:addProperty("SymbolColor", "color", colors.black)
base:addProperty("ActiveBackground", "color", colors.green)
base:addProperty("InactiveBackground", "color", colors.red)
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,
@@ -58,8 +26,9 @@ return function(name, basalt)
draw = function(self)
base.draw(self)
self:addDraw("switch", function()
local parent = self:getParent()
local bgCol,fgCol = self:getBackground(), self:getForeground()
local activeBG = self:getActiveBackground()
local inactiveBG = self:getInactiveBackground()
local bgSymbol = self:getSymbolColor()
local w,h = self:getSize()
if(self:getValue())then
self:addBackgroundBox(1, 1, w, h, activeBG)

View File

@@ -4,8 +4,7 @@ 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)
local objectType = "Textfield"
local hIndex, wIndex, textX, textY = 1, 1, 1, 1
base:setType("Textfield")
local lines = { "" }
local bgLines = { "" }
@@ -15,10 +14,18 @@ return function(name, basalt)
local startSelX,endSelX,startSelY,endSelY
local selectionBG,selectionFG = colors.lightBlue,colors.black
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")
base:setSize(30, 12)
base:setZIndex(5)
base:setZ(5)
local function isSelected()
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
@@ -76,11 +83,28 @@ return function(name, basalt)
end
end
textX, textY = sx, sy
self:setTextPosition(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
@@ -98,8 +122,21 @@ 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 textY
l = l or self:getTextYPosition()
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
@@ -118,7 +155,7 @@ return function(name, basalt)
end
for k,v in pairs(keyWords)do
for _,b in pairs(v)do
local pos = stringGetPositions(lines[l], b)
local pos = stringGetKeywordPositions(lines[l], b)
if(#pos>0)then
for x=1,#pos/2 do
local xP = x*2 - 1
@@ -139,10 +176,6 @@ return function(name, basalt)
end
local object = {
getType = function(self)
return objectType
end;
setBackground = function(self, bg)
base.setBackground(self, bg)
updateAllColors(self)
@@ -155,32 +188,6 @@ 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,
@@ -201,7 +208,8 @@ return function(name, basalt)
bgLines = {""}
fgLines = {""}
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
hIndex, wIndex, textX, textY = 1, 1, 1, 1
self:setTextPosition(1, 1)
self:setOffset(1, 1)
self:updateDraw()
return self
end,
@@ -236,18 +244,18 @@ return function(name, basalt)
if(keyWords[color]==nil)then
keyWords[color] = {}
end
for k,v in pairs(tab)do
for _,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
@@ -290,40 +298,22 @@ return function(name, basalt)
return self
end,
getTextCursor = function(self)
return textX, textY
getLineCount = function(self)
return #lines
end,
getOffset = function(self)
return wIndex, hIndex
getLineLength = function(self, index)
return lines[index]:len()
end,
setOffset = function(self, xOff, yOff)
wIndex = xOff or wIndex
hIndex = yOff or hIndex
self:updateDraw()
return self
end,
getXOffset = function(self)
return wIndex
end,
setXOffset = function(self, xOff)
return self:setOffset(xOff, nil)
end,
getYOffset = function(self)
return hIndex
end,
setYOffset = function(self, yOff)
return self:setOffset(nil, yOff)
end,
getSelectedContent = getSelectedContent,
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,
@@ -337,6 +327,8 @@ 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
@@ -540,6 +532,8 @@ 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
@@ -553,6 +547,9 @@ 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())
@@ -577,6 +574,8 @@ 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,6 +587,8 @@ 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
@@ -605,6 +606,8 @@ 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
@@ -619,6 +622,8 @@ 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)
@@ -628,6 +633,7 @@ 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
@@ -643,6 +649,8 @@ 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
@@ -662,6 +670,8 @@ 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
@@ -670,6 +680,7 @@ 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
@@ -691,6 +702,11 @@ 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())
@@ -701,6 +717,8 @@ 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
@@ -711,9 +729,9 @@ return function(name, basalt)
base.draw(self)
self:addDraw("textfield", function()
local w, h = self:getSize()
local bgColor = tHex[self:getBackground()]
local fgColor = tHex[self:getForeground()]
local wIndex, hIndex = self:getOffset()
local selectionBG = self:getSelectionBackground()
local selectionFG = self:getSelectionForeground()
for n = 1, h do
local text = ""
local bg = ""
@@ -725,12 +743,12 @@ return function(name, basalt)
end
text = sub(text, wIndex, w + wIndex - 1)
bg = rep(bgColor, w)
fg = rep(fgColor, w)
bg = sub(bg, wIndex, w + wIndex - 1)
fg = sub(fg, wIndex, w + wIndex - 1)
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
@@ -751,8 +769,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)

View File

@@ -1,7 +1,6 @@
return function(name, basalt)
local base = basalt.getObject("Object")(name, basalt)
local objectType = "Thread"
base:setType("Thread")
local func
local cRoutine
@@ -9,10 +8,6 @@ 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,33 +1,34 @@
return function(name, basalt)
local base = basalt.getObject("Object")(name, basalt)
local objectType = "Timer"
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 < 0) then
value = 0
end
return value
end)
base:combineProperty("Time", "Timer", "Repeat")
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
repeats = savedRepeats
local timer, repeatAmount = self:getTime()
repeats = repeatAmount
timerObj = os.startTimer(timer)
timerIsActive = true
self:listenEvent("other_event")
@@ -64,6 +65,7 @@ return function(name, basalt)
base.eventHandler(self, event, ...)
if event == "timer" and tObj == timerObj and timerIsActive then
self:sendEvent("timed_event")
local timer = self:getTimer()
if (repeats >= 1) then
repeats = repeats - 1
if (repeats >= 1) then

View File

@@ -3,18 +3,30 @@ local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Treeview"
base:setType("Treeview")
local nodes = {}
local itemSelectedBG = colors.black
local itemSelectedFG = colors.lightGray
local selectionColorActive = true
local textAlign = "left"
local xOffset, yOffset = 0, 0
local scrollable = true
base: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)
base:setSize(16, 8)
base:setZIndex(5)
base:setZ(5)
local function newNode(text, expandable)
text = text or ""
@@ -129,6 +141,9 @@ 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 = {
@@ -143,91 +158,6 @@ 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
@@ -245,7 +175,7 @@ return function(name, basalt)
mouseHandler = function(self, button, x, y)
if base.mouseHandler(self, button, x, y) then
local currentLine = 1 - yOffset
local currentLine = 1 - self:getYOffset()
local obx, oby = self:getAbsolutePosition()
local w, h = self:getSize()
local function checkNodeClick(node, level)
@@ -279,6 +209,8 @@ 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
@@ -310,6 +242,7 @@ return function(name, basalt)
yOffset = yOffset - 1
end
end
self:setYOffset(yOffset)
self:updateDraw()
end
return true
@@ -320,6 +253,9 @@ 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)
@@ -347,8 +283,6 @@ return function(name, basalt)
end
end)
end,
}
object.__index = object

View File

@@ -3,18 +3,31 @@ 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 object
local objectType = "VisualObject" -- not changeable
base:setType("VisualObject")
local isVisible,ignOffset,isHovered,isClicked,isDragging = true,false,false,false,false
local zIndex = 1
local ignOffset,isHovered,isClicked,isDragging = false,false,false,false
local x, y, width, height = 1,1,1,1
local dragStartX, dragStartY, dragXOffset, dragYOffset = 0, 0, 0, 0
local dragStartX, dragStartY = 0, 0
local bgColor,fgColor, transparency = colors.black, colors.white, false
local parent
local preDrawQueue = {}
@@ -23,72 +36,77 @@ return function(name, basalt)
local renderObject = {}
local function split(str, d)
local result = {}
if str == "" then
return result
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)
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
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")
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)
return basalt
end,
show = function(self)
isVisible = true
self:updateDraw()
self:setVisible(true)
return self
end,
hide = function(self)
isVisible = false
self:updateDraw()
self:setVisible(false)
return self
end,
isVisible = function(self)
return isVisible
end,
setVisible = function(self, _isVisible)
isVisible = _isVisible or not isVisible
self:updateDraw()
return self
end,
setTransparency = function(self, _transparency)
transparency = _transparency~= nil and _transparency or true
self:updateDraw()
return self
return self:getVisible()
end,
setParent = function(self, newParent, noRemove)
base.setParent(self, newParent, noRemove)
parent = newParent
base.setParent(self, newParent, noRemove)
return self
end,
@@ -99,19 +117,6 @@ 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()
@@ -119,100 +124,7 @@ 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
@@ -225,18 +137,21 @@ return function(name, basalt)
return x, y
end,
ignoreOffset = function(self, ignore)
ignOffset = ignore
if(ignore==nil)then ignOffset = true end
return self
end,
getRelativePosition = function(self, x, y)
if (x == nil) or (y == nil) then
x, y = 1, 1
end
getIgnoreOffset = function(self)
return ignOffset
if (parent ~= nil) then
local xO, yO = self:getAbsolutePosition()
x = xO - x + 1
y = yO - y + 1
end
return x, y
end,
isCoordsInObject = function(self, x, y)
if(isVisible)and(self:isEnabled())then
if(self:getVisible())and(self:getEnabled())then
if(x==nil)or(y==nil)then return false end
local objX, objY = self:getAbsolutePosition()
local w, h = self:getSize()
@@ -316,6 +231,8 @@ return function(name, basalt)
end
isClicked = true
isDragging = true
self:setProperty("Dragging", true)
self:setProperty("Clicked", true)
dragStartX, dragStartY = x, y
return true
end
@@ -327,6 +244,8 @@ 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()
@@ -349,9 +268,7 @@ return function(name, basalt)
end
if(self:isCoordsInObject(x, y))then
local objX, objY = self:getAbsolutePosition()
dragStartX, dragStartY = x, y
dragXOffset, dragYOffset = objX - x, objY - y
end
end,
@@ -372,17 +289,19 @@ 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(isVisible)then
if(self:isEnabled())and(self:getVisible())then
if (self:isFocused()) then
local val = self:sendEvent("key", key, isHolding)
if(val==false)then return false end
@@ -392,7 +311,7 @@ return function(name, basalt)
end,
keyUpHandler = function(self, key)
if(self:isEnabled())and(isVisible)then
if(self:isEnabled())and(self:getVisible())then
if (self:isFocused()) then
local val = self:sendEvent("key_up", key)
if(val==false)then return false end
@@ -402,7 +321,7 @@ return function(name, basalt)
end,
charHandler = function(self, char)
if(self:isEnabled())and(isVisible)then
if(self:isEnabled())and(self:getVisible())then
if(self:isFocused())then
local val = self:sendEvent("char", char)
if(val==false)then return false end
@@ -413,12 +332,15 @@ 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
@@ -475,12 +397,13 @@ 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(transparency)then
if not(transparent)then
obj:setText(x+xPos-1, y+yPos-1, text)
return
end
@@ -492,48 +415,50 @@ 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(transparency)then
obj:setBG(x+xPos-1, y+yPos-1, bg)
if not(transparent)then
obj:setBg(x+xPos-1, y+yPos-1, bg)
return
end
local t = split(bg)
for k,v in pairs(t)do
for _,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, fg)
obj:setBg(x+xPos-1, y+yPos-1, v.value)
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(transparency)then
obj:setFG(x+xPos-1, y+yPos-1, fg)
if not(transparent)then
obj:setFg(x+xPos-1, y+yPos-1, fg)
return
end
local t = split(fg)
for k,v in pairs(t)do
for _,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,
@@ -541,31 +466,32 @@ 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(transparency)then
if not(transparent)then
obj:blit(x+xPos-1, y+yPos-1, t, fg, bg)
return
end
local _text = split(t, "\0")
local _fg = split(fg)
local _bg = split(bg)
for k,v in pairs(_text)do
for _,v in pairs(_text)do
if(v.value~="")or(v.value~="\0")then
obj:setText(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
for k,v in pairs(_bg)do
for _,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 k,v in pairs(_fg)do
for _,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,
@@ -604,7 +530,7 @@ return function(name, basalt)
end,
render = function(self)
if (isVisible)then
if (self:getVisible())then
self:redraw()
end
end,
@@ -631,16 +557,25 @@ return function(name, basalt)
draw = function(self)
self:addDraw("base", function()
local w,h = self:getSize()
if(bgColor~=false)then
local bgColor = self:getBackground()
local bgSymbol = self:getBgSymbol()
local bgSymbolColor = self:getBgSymbolColor()
local fgColor = self:getForeground()
if(bgColor~=nil)then
self:addTextBox(1, 1, w, h, " ")
self:addBackgroundBox(1, 1, w, h, bgColor)
end
if(fgColor~=false)then
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
self:addForegroundBox(1, 1, w, h, fgColor)
end
end, 1)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -217,10 +217,16 @@ 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
@@ -244,6 +250,10 @@ 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
@@ -251,6 +261,8 @@ 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

@@ -164,22 +164,6 @@ return {
return self
end,
setBackground = function(self, newColor)
base.setBackground(self, newColor)
if(fontsize>1)then
self:setFontSize(fontsize)
end
return self
end,
setForeground = function(self, newColor)
base.setForeground(self, newColor)
if(fontsize>1)then
self:setFontSize(fontsize)
end
return self
end,
getFontSize = function(self)
return fontsize
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(0, h, 1, 1, bgCol) end
if(bgCol~=false)then self:addForegroundBox(1, h, 1, 1, bgCol) end
self:addBackgroundBox(1, h, 1, 1, borderColors["left"])
end
end

View File

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

View File

@@ -1,124 +1,209 @@
local utils = require("utils")
local count = utils.tableCount
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()
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
return {
VisualObject = function(base, basalt)
local dynObjects = {}
local curProperties = {}
local properties = {x="getX", y="getY", w="getWidth", h="getHeight"}
Object = function(base, basalt)
local observers = {}
local activeDynValues = {}
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
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
end
local function createDynamicValue(self, key, val)
local objectGroup = {}
local properties = properties
for a,b in pairs(properties)do
for v in val:gmatch("%a+%."..a)do
local name = v:gsub("%."..a, "")
if(name~="self")and(name~="parent")then
table.insert(objectGroup, name)
return {
updatePropertyObservers = function(self, name)
if(observers[name]~=nil)then
for _,v in pairs(observers[name])do
v(self, name)
end
end
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
end
objects["self"] = self
objects["parent"] = parent
dynObjects[key] = function()
local mainVal = val
for a,b in pairs(properties)do
for v in val:gmatch("%w+%."..a) do
local obj = objects[v:gsub("%."..a, "")]
if(obj~=nil)then
mainVal = mainVal:gsub(v, obj[b](obj))
else
error("Dynamic Values - unable to find object: "..v)
end
end
end
curProperties[key] = math.floor(stringToNumber(mainVal)+0.5)
end
dynObjects[key]()
end
local function updatePositions(self)
if(count(dynObjects)>0)then
for k,v in pairs(dynObjects)do
v()
end
local properties = {x="getX", y="getY", w="getWidth", h="getHeight"}
for k,v in pairs(properties)do
if(dynObjects[k]~=nil)then
if(curProperties[k]~=self[v](self))then
if(k=="x")or(k=="y")then
base.setPosition(self, curProperties["x"] or self:getX(), curProperties["y"] or self:getY())
end
if(k=="w")or(k=="h")then
base.setSize(self, curProperties["w"] or self:getWidth(), curProperties["h"] or self:getHeight())
end
end
end
end
end
end
local object = {
updatePositions = updatePositions,
createDynamicValue = createDynamicValue,
setPosition = function(self, xPos, yPos, rel)
curProperties.x = xPos
curProperties.y = yPos
if(type(xPos)=="string")then
createDynamicValue(self, "x", xPos)
else
dynObjects["x"] = nil
end
if(type(yPos)=="string")then
createDynamicValue(self, "y", yPos)
else
dynObjects["y"] = nil
end
base.setPosition(self, curProperties.x, curProperties.y, rel)
return self
end,
setSize = function(self, w, h, rel)
curProperties.w = w
curProperties.h = h
if(type(w)=="string")then
createDynamicValue(self, "w", w)
else
dynObjects["w"] = nil
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
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)
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)
end
end
end
end,
}
return object
end
}

View File

@@ -0,0 +1,321 @@
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

@@ -0,0 +1,135 @@
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}",
defaultBackground = "{self.focused ? gray : black}",
defaultForeground = "{self.focused ? black : lightGray}",
defaultText = "..."
},
},
}
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,58 +1,87 @@
local images = require("images")
local utils = require("utils")
local XMLParser = require("xmlParser")
local sub = string.sub
return {
VisualObject = function(base)
local textureId, infinitePlay = 1, true
local bimg, texture, textureTimerId
local textureMode = "default"
local images = {}
local object = {
addTexture = function(self, path, animate)
bimg = images.loadImageAsBimg(path)
texture = bimg[1]
if(animate)then
if(bimg.animated)then
self:listenEvent("other_event")
local t = bimg[textureId].duration or bimg.secondsPerFrame or 0.2
textureTimerId = os.startTimer(t)
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
end
end
self:setBackground(false)
self:setForeground(false)
self:setDrawState("texture-base", true)
self:updateDraw()
return self
end,
setTextureMode = function(self, mode)
textureMode = mode or textureMode
removeTexture = function(self, id)
table.remove(images, id)
if(#images==0)then
self:setDrawState("texture-base", false)
end
self:updateDraw()
return self
end,
setInfinitePlay = function(self, state)
infinitePlay = state
clearTextures = function(self)
images = {}
self:setDrawState("texture-base", false)
self:updateDraw()
return self
end,
eventHandler = function(self, event, timerId, ...)
base.eventHandler(self, event, timerId, ...)
if(event=="timer")then
if(timerId == textureTimerId)then
if(bimg[textureId+1]~=nil)then
textureId = textureId + 1
texture = bimg[textureId]
local t = bimg[textureId].duration or bimg.secondsPerFrame or 0.2
textureTimerId = os.startTimer(t)
self:updateDraw()
else
if(infinitePlay)then
textureId = 1
texture = bimg[1]
local t = bimg[textureId].duration or bimg.secondsPerFrame or 0.2
textureTimerId = os.startTimer(t)
self:updateDraw()
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
end
end
end
@@ -62,50 +91,25 @@ return {
draw = function(self)
base.draw(self)
self:addDraw("texture-base", function()
local obj = self:getParent() or self
local x, y = self:getPosition()
local w,h = self:getSize()
local wP,hP = obj:getSize()
local textureWidth = bimg.width or #bimg[textureId][1][1]
local textureHeight = bimg.height or #bimg[textureId]
local startX, startY = 0, 0
if (textureMode == "center") then
startX = x + math.floor((w - textureWidth) / 2 + 0.5) - 1
startY = y + math.floor((h - textureHeight) / 2 + 0.5) - 1
elseif (textureMode == "default") then
startX, startY = x, y
elseif (textureMode == "right") then
startX, startY = x + w - textureWidth, y + h - textureHeight
end
local textureX = x - startX
local textureY = y - startY
if startX < x then
startX = x
textureWidth = textureWidth - textureX
end
if startY < y then
startY = y
textureHeight = textureHeight - textureY
end
if startX + textureWidth > x + w then
textureWidth = (x + w) - startX
end
if startY + textureHeight > y + h then
textureHeight = (y + h) - startY
end
for k = 1, textureHeight do
if(texture[k+textureY]~=nil)then
local t, f, b = table.unpack(texture[k+textureY])
self:addBlit(1, k, t:sub(textureX, textureX + textureWidth), f:sub(textureX, textureX + textureWidth), b:sub(textureX, textureX + textureWidth))
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
end
end
end, 1)
end)
self:setDrawState("texture-base", false)
end
}