Basalt 1.7 Update

- New Objects (Flexbox, Graph, Treeview)
- Pluginsystem to add/remove functionality
- Reworked the entire Object system, instead of one big Object Class we have multiple classes: Object, VisualObject, ChangeableObject
- Instead of one big Frame Class we have multiple Frame Classes: BaseFrame, Frame, MovableFrame, ScrollableFrame, MonitorFrame, Flexbox
- Removed the Animation Object, and added a animation plugin instead
- Removed the Graphic Object and merged it's functionality with the image object
- Updated currently existing objects
This commit is contained in:
Robert Jelic
2023-04-30 17:05:34 +02:00
parent e086c1abb2
commit bb1b1beb79
341 changed files with 15541 additions and 3862 deletions

View File

@@ -1,6 +1,3 @@
local xmlValue = require("utils").getValueFromXML
local basaltEvent = require("basaltEvent")
local floor,sin,cos,pi,sqrt,pow = math.floor,math.sin,math.cos,math.pi,math.sqrt,math.pow
-- You can find the easing curves here https://easings.net
@@ -222,7 +219,8 @@ local lerp = {
local activeAnimations = {}
return function(name)
return function(name, basalt)
local base = basalt.getObject("Object")(name, basalt)
local object = {}
local objectType = "Animation"
@@ -234,8 +232,6 @@ return function(name)
local index = 1
local infinitePlay = false
local eventSystem = basaltEvent()
local nextWaitTimer = 0
local lastFunc
local loop=false
@@ -306,7 +302,7 @@ return function(name)
local obj = _OBJ
local x,y
local name = ""
if(obj.parent~=nil)then name = obj.parent:getName() end
if(obj:getParent()~=nil)then name = obj:getParent():getName() end
name = name..obj:getName()
addAnimationPart(t+0.05, function()
if(typ~=nil)then
@@ -340,14 +336,7 @@ return function(name)
name = name,
getType = function(self)
return objectType
end;
getBaseFrame = function(self)
if(self.parent~=nil)then
return self.parent:getBaseFrame()
end
return self
end;
end,
setMode = function(self, newMode)
mode = newMode
@@ -359,124 +348,6 @@ return function(name)
return self
end,
generateXMLEventFunction = function(self, func, val)
local createF = function(str)
if(str:sub(1,1)=="#")then
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
if(o~=nil)and(o.internalObjetCall~=nil)then
func(self,function()o:internalObjetCall()end)
end
else
func(self,self:getBaseFrame():getVariable(str))
end
end
if(type(val)=="string")then
createF(val)
elseif(type(val)=="table")then
for k,v in pairs(val)do
createF(v)
end
end
return self
end,
setValuesByXMLData = function(self, data)
loop = xmlValue("loop", data)==true and true or false
if(xmlValue("object", data)~=nil)then
local o = self:getBaseFrame():getDeepObject(xmlValue("object", data))
if(o==nil)then
o = self:getBaseFrame():getVariable(xmlValue("object", data))
end
if(o~=nil)then
self:setObject(o)
end
end
if(data["move"]~=nil)then
local x = xmlValue("x", data["move"])
local y = xmlValue("y", data["move"])
local duration = xmlValue("duration", data["move"])
local time = xmlValue("time", data["move"])
self:move(x, y, duration, time)
end
if(data["size"]~=nil)then
local w = xmlValue("width", data["size"])
local h = xmlValue("height", data["size"])
local duration = xmlValue("duration", data["size"])
local time = xmlValue("time", data["size"])
self:size(w, h, duration, time)
end
if(data["offset"]~=nil)then
local x = xmlValue("x", data["offset"])
local y = xmlValue("y", data["offset"])
local duration = xmlValue("duration", data["offset"])
local time = xmlValue("time", data["offset"])
self:offset(x, y, duration, time)
end
if(data["textColor"]~=nil)then
local duration = xmlValue("duration", data["textColor"])
local timer = xmlValue("time", data["textColor"])
local t = {}
local tab = data["textColor"]["color"]
if(tab~=nil)then
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
table.insert(t, colors[v:value()])
end
end
if(duration~=nil)and(#t>0)then
self:changeTextColor(duration, timer or 0, table.unpack(t))
end
end
if(data["background"]~=nil)then
local duration = xmlValue("duration", data["background"])
local timer = xmlValue("time", data["background"])
local t = {}
local tab = data["background"]["color"]
if(tab~=nil)then
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
table.insert(t, colors[v:value()])
end
end
if(duration~=nil)and(#t>0)then
self:changeBackground(duration, timer or 0, table.unpack(t))
end
end
if(data["text"]~=nil)then
local duration = xmlValue("duration", data["text"])
local timer = xmlValue("time", data["text"])
local t = {}
local tab = data["text"]["text"]
if(tab~=nil)then
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
table.insert(t, v:value())
end
end
if(duration~=nil)and(#t>0)then
self:changeText(duration, timer or 0, table.unpack(t))
end
end
if(xmlValue("onDone", data)~=nil)then self:generateXMLEventFunction(self.onDone, xmlValue("onDone", data)) end
if(xmlValue("onStart", data)~=nil)then self:generateXMLEventFunction(self.onDone, xmlValue("onStart", data)) end
if(xmlValue("autoDestroy", data)~=nil)then
if(xmlValue("autoDestroy", data))then
autoDestroy = true
end
end
mode = xmlValue("mode", data) or mode
if(xmlValue("play", data)~=nil)then if(xmlValue("play", data))then self:play(loop) end end
return self
end,
getZIndex = function(self)
return 1
end;
getName = function(self)
return self.name
end;
setObject = function(self, obj)
_OBJ = obj
return self
@@ -557,12 +428,12 @@ return function(name)
end;
onDone = function(self, f)
eventSystem:registerEvent("animation_done", f)
self:registerEvent("animation_done", f)
return self
end,
onStart = function(self, f)
eventSystem:registerEvent("animation_start", f)
self:registerEvent("animation_start", f)
return self
end,
@@ -572,16 +443,16 @@ return function(name)
end,
animationDoneHandler = function(self)
eventSystem:sendEvent("animation_done", self)
self.parent:removeEvent("other_event", self)
self:sendEvent("animation_done", self)
self:listenEvent("other_event", false)
if(autoDestroy)then
self.parent:removeObject(self)
self:getParent():removeObject(self)
self = nil
end
end;
animationStartHandler = function(self)
eventSystem:sendEvent("animation_start", self)
self:sendEvent("animation_start", self)
end;
clear = function(self)
@@ -609,7 +480,7 @@ return function(name)
else
self:animationDoneHandler()
end
self.parent:addEvent("other_event", self)
self:listenEvent("other_event")
return self
end;
@@ -619,7 +490,7 @@ return function(name)
infinitePlay = false
end
animationActive = false
self.parent:removeEvent("other_event", self)
self:listenEvent("other_event", false)
return self
end;
@@ -639,7 +510,7 @@ return function(name)
end
end;
}
object.__index = object
return object
object.__index = object
return setmetatable(object, base)
end

View File

@@ -0,0 +1,213 @@
local drawSystem = require("basaltDraw")
local utils = require("utils")
local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("Container")(name, basalt)
local objectType = "BaseFrame"
local xOffset, yOffset = 0, 0
local colorTheme = {}
local updateRender = true
local termObject = basalt.getTerm()
local basaltDraw = drawSystem(termObject)
local xCursor, yCursor, cursorBlink, cursorColor = 1, 1, false, colors.white
local object = {
getType = function()
return objectType
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
getBase = function(self)
return base
end,
getOffset = function(self)
return xOffset, yOffset
end,
setOffset = function(self, xOff, yOff)
xOffset = xOff or xOffset
yOffset = yOff or yOffset
self:updateDraw()
return self
end,
show = function(self)
base.show(self)
for k,v in pairs(colorTheme)do
if(type(v)=="number")then
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
else
local r,g,b = table.unpack(v)
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
end
end
return self
end,
setPalette = function(self, col, ...)
if(self==basalt.getActiveFrame())then
if(type(col)=="string")then
colorTheme[col] = ...
termObject.setPaletteColor(type(col)=="number" and col or colors[col], ...)
elseif(type(col)=="table")then
for k,v in pairs(col)do
colorTheme[k] = v
if(type(v)=="number")then
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
else
local r,g,b = table.unpack(v)
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
end
end
end
end
return self
end,
setSize = function(self, ...)
base.setSize(self, ...)
basaltDraw = drawSystem(termObject)
return self
end,
getSize = function()
return termObject.getSize()
end,
getWidth = function(self)
return ({termObject.getSize()})[1]
end,
getHeight = function(self)
return ({termObject.getSize()})[2]
end,
show = function(self)
base.show(self)
basalt.setActiveFrame(self)
for k,v in pairs(colors)do
if(type(v)=="number")then
termObject.setPaletteColor(v, colors.packRGB(term.nativePaletteColor((v))))
end
end
for k,v in pairs(colorTheme)do
if(type(v)=="number")then
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
else
local r,g,b = table.unpack(v)
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
end
end
basalt.setMainFrame(self)
return self
end,
render = function(self)
if(base.render~=nil)then
if(self:isVisible())then
if(updateRender)then
base.render(self)
local objects = self:getObjects()
for _, obj in ipairs(objects) do
if (obj.element.render ~= nil) then
obj.element:render()
end
end
updateRender = false
end
end
end
end,
updateDraw = function(self)
updateRender = true
return self
end,
eventHandler = function(self, event, ...)
base.eventHandler(self, event, ...)
if(event=="term_resize")then
self:setSize(termObject.getSize())
end
end,
updateTerm = function(self)
basaltDraw.update()
end,
setTerm = function(self, newTerm)
termObject = newTerm
basaltDraw = drawSystem(termObject)
return self
end,
getTerm = function()
return termObject
end,
blit = function (self, x, y, t, f, b)
local obx, oby = self:getPosition()
local w, h = self:getSize()
if y >= 1 and y <= h then
local t_visible = sub(t, max(1 - x + 1, 1), max(w - x + 1, 1))
local f_visible = sub(f, max(1 - x + 1, 1), max(w - x + 1, 1))
local b_visible = sub(b, max(1 - x + 1, 1), max(w - x + 1, 1))
basaltDraw.blit(max(x + (obx - 1), obx), oby + y - 1, t_visible, f_visible, b_visible)
end
end,
setCursor = function(self, _blink, _xCursor, _yCursor, color)
local obx, oby = self:getAbsolutePosition()
cursorBlink = _blink or false
if (_xCursor ~= nil) then
xCursor = obx + _xCursor - 1
end
if (_yCursor ~= nil) then
yCursor = oby + _yCursor - 1
end
cursorColor = color or cursorColor
if (cursorBlink) then
termObject.setTextColor(cursorColor)
termObject.setCursorPos(xCursor, yCursor)
termObject.setCursorBlink(cursorBlink)
else
termObject.setCursorBlink(false)
end
return self
end,
}
for k,v in pairs({"drawBackgroundBox", "drawForegroundBox", "drawTextBox"})do
object[v] = function(self, x, y, width, height, symbol)
local obx, oby = self:getPosition()
local w, h = self:getSize()
height = (y < 1 and (height + y > self:getHeight() and self:getHeight() or height + y - 1) or (height + y > self:getHeight() and self:getHeight() - y + 1 or height))
width = (x < 1 and (width + x > self:getWidth() and self:getWidth() or width + x - 1) or (width + x > self:getWidth() and self:getWidth() - x + 1 or width))
basaltDraw[v](max(x + (obx - 1), obx), max(y + (oby - 1), oby), width, height, symbol)
end
end
for k,v in pairs({"setBG", "setFG", "setText"}) do
object[v] = function(self, x, y, str)
local obx, oby = self:getPosition()
local w, h = self:getSize()
if (y >= 1) and (y <= h) then
basaltDraw[v](max(x + (obx - 1), obx), oby + y - 1, sub(str, max(1 - x + 1, 1), max(w - x + 1,1)))
end
end
end
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,74 +1,65 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
return function(name, basalt)
-- Button
local base = Object(name)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Button"
local textHorizontalAlign = "center"
local textVerticalAlign = "center"
local text = "Button"
base:setSize(12, 3)
base:setZIndex(5)
base:setValue("Button")
base.width = 12
base.height = 3
local object = {
init = function(self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ButtonBG")
self.fgColor = self.parent:getTheme("ButtonText")
end
end,
getType = function(self)
return objectType
end;
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
getBase = function(self)
return base
end,
setHorizontalAlign = function(self, pos)
textHorizontalAlign = pos
self:updateDraw()
return self
end;
end,
setVerticalAlign = function(self, pos)
textVerticalAlign = pos
self:updateDraw()
return self
end;
end,
setText = function(self, text)
base:setValue(tostring(text))
setText = function(self, newText)
text = newText
self:updateDraw()
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end
if(xmlValue("horizontalAlign", data)~=nil)then textHorizontalAlign = xmlValue("horizontalAlign", data) end
if(xmlValue("verticalAlign", data)~=nil)then textVerticalAlign = xmlValue("verticalAlign", data) end
return self
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
for n = 1, h do
if (n == verticalAlign) then
local val = self:getValue()
self.parent:setText(obx + (w/2-val:len()/2), oby + (n - 1), utils.getTextHorizontalAlign(val, val:len(), textHorizontalAlign))
self.parent:setFG(obx + (w/2-val:len()/2), oby + (n - 1), utils.getTextHorizontalAlign(tHex[self.fgColor]:rep(val:len()), val:len(), textHorizontalAlign))
end
end
base.draw(self)
self:addDraw("button", function()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
local xOffset
if(textHorizontalAlign=="center")then
xOffset = math.floor((w - text:len()) / 2)
elseif(textHorizontalAlign=="right")then
xOffset = w - text:len()
end
end
end,
self:addText(xOffset + 1, verticalAlign, text)
self:addFG(xOffset + 1, verticalAlign, tHex[self:getForeground() or colors.white]:rep(text:len()))
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,31 +1,53 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
return function(name, basalt)
-- Checkbox
local base = Object(name)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Checkbox"
base:setZIndex(5)
base:setValue(false)
base.width = 1
base.height = 1
base:setSize(1, 1)
local symbol = "\42"
local symbol,inactiveSymbol,text,textPos = "\42"," ","","right"
local object = {
load = function(self)
self:listenEvent("mouse_click", self)
self:listenEvent("mouse_up", self)
end,
getType = function(self)
return objectType
end;
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
setSymbol = function(self, sym)
symbol = sym
setSymbol = function(self, sym, inactive)
symbol = sym or symbol
inactiveSymbol = inactive or inactiveSymbol
self:updateDraw()
return self
end,
getSymbol = function(self)
return symbol, inactiveSymbol
end,
setText = function(self, _text)
text = _text
return self
end,
setTextPosition = function(self, pos)
textPos = pos or textPos
return self
end,
setChecked = base.setValue,
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
if(button == 1)then
@@ -41,45 +63,26 @@ return function(name)
return false
end,
touchHandler = function(self, x, y)
return self:mouseHandler(1, x, y)
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("checked", data)~=nil)then if(xmlValue("checked", data))then self:setValue(true) else self:setValue(false) end end
return self
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, "center")
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
for n = 1, h do
if (n == verticalAlign) then
if (self:getValue() == true) then
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(symbol, w, "center"), self.bgColor, self.fgColor)
else
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(" ", w, "center"), self.bgColor, self.fgColor)
end
end
end
base.draw(self)
self:addDraw("checkbox", function()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, "center")
local bg,fg = self:getBackground(), self:getForeground()
if (self:getValue()) then
self:addBlit(1, verticalAlign, utils.getTextHorizontalAlign(symbol, w, "center"), tHex[bg], tHex[fg])
else
self:addBlit(1, verticalAlign, utils.getTextHorizontalAlign(inactiveSymbol, w, "center"), tHex[bg], tHex[fg])
end
end
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("CheckboxBG")
self.fgColor = self.parent:getTheme("CheckboxText")
end
if(text~="")then
local align = textPos=="left" and -text:len() or 3
self:addText(align, verticalAlign, text)
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -0,0 +1,388 @@
local utils = require("utils")
local tableCount = utils.tableCount
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Container"
local elements = {}
local events = {}
local container = {}
local activeEvents = {}
local focusedObject
local sorted = true
local objId, evId = 0, 0
local objSort = function(a, b)
if a.zIndex == b.zIndex then
return a.objId < b.objId
else
return a.zIndex < b.zIndex
end
end
local evSort = function(a, b)
if a.zIndex == b.zIndex then
return a.evId > b.evId
else
return a.zIndex > b.zIndex
end
end
local function getObject(self, name)
if(type(name)=="table")then name = name:getName() end
for i, v in ipairs(elements) do
if v.element:getName() == name then
return v.element
end
end
end
local function getDeepObject(self, name)
local o = getObject(name)
if(o~=nil)then return o end
for _, value in pairs(objects) do
if (b:getType() == "Container") then
local oF = b:getDeepObject(name)
if(oF~=nil)then return oF end
end
end
end
local function addObject(self, element, el2)
if (getObject(element:getName()) ~= nil) then
return
end
objId = objId + 1
local zIndex = element:getZIndex()
table.insert(elements, {element = element, zIndex = zIndex, objId = objId})
sorted = false
element:setParent(self, true)
if(element.init~=nil)then element:init() end
if(element.load~=nil)then element:load() end
if(element.draw~=nil)then element:draw() end
return element
end
local function updateZIndex(self, element, newZ)
objId = objId + 1
evId = evId + 1
for k,v in pairs(elements)do
if(v.element==element)then
v.zIndex = newZ
v.objId = objId
break
end
end
for k,v in pairs(events)do
for a,b in pairs(v)do
if(b.element==element)then
b.zIndex = newZ
b.evId = evId
end
end
end
sorted = false
self:updateDraw()
end
local function removeObject(self, element)
if(type(element)=="string")then element = getObject(element:getName()) end
if(element==nil)then return end
for i, v in ipairs(elements) do
if v.element == element then
table.remove(elements, i)
return true
end
end
sorted = false
end
local function removeEvents(self, element)
local parent = self:getParent()
for a, b in pairs(events) do
for c, d in pairs(b) do
if(d.element == element)then
table.remove(events[a], c)
end
end
if(tableCount(events[a])<=0)then
activeEvents[a] = false
if(parent~=nil)then
parent:removeEvent(a, self)
end
end
end
sorted = false
end
local function getEvent(self, event, name)
if(type(name)=="table")then name = name:getName() end
if(events[event]~=nil)then
for _, obj in pairs(events[event]) do
if (obj.element:getName() == name) then
return obj
end
end
end
end
local function addEvent(self, event, element)
if (getEvent(self, event, element:getName()) ~= nil) then
return
end
local zIndex = element:getZIndex()
evId = evId + 1
if(events[event]==nil)then events[event] = {} end
table.insert(events[event], {element = element, zIndex = zIndex, evId = evId})
sorted = false
self:listenEvent(event)
return element
end
local function removeEvent(self, event, element)
local parent = self:getParent()
if(events[event]~=nil)then
for a, b in pairs(events[event]) do
if(b.element == element)then
table.remove(events[event], a)
end
end
if(tableCount(events[event])<=0)then
self:listenEvent(event, false)
end
end
sorted = false
end
local function getObjects(self)
self:sortElementOrder()
return elements
end
container = {
getType = function()
return objectType
end,
getBase = function(self)
return base
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
setSize = function(self, ...)
base.setSize(self, ...)
self:customEventHandler("basalt_FrameResize")
return self
end,
setPosition = function(self, ...)
base.setPosition(self, ...)
self:customEventHandler("basalt_FrameReposition")
return self
end,
searchObjects = function(self, name)
local t = {}
for k,v in pairs(elements)do
if(string.find(k:getName(), name))then
table.insert(t, v)
end
end
return t
end,
getObjectsByType = function(self, t)
local t = {}
for k,v in pairs(elements)do
if(v:isType(t))then
table.insert(t, v)
end
end
return t
end,
setImportant = function(self, element)
objId = objId + 1
evId = evId + 1
for a, b in pairs(events) do
for c, d in pairs(b) do
if(d.element == element)then
d.evId = evId
table.remove(events[a], c)
table.insert(events[a], d)
break
end
end
end
for i, v in ipairs(elements) do
if v.element == element then
v.objId = objId
table.remove(elements, i)
table.insert(elements, v)
break
end
end
if(self.updateDraw~=nil)then
self:updateDraw()
end
sorted = false
end,
sortElementOrder = function(self)
if(sorted)then return end
table.sort(elements, objSort)
for a, b in pairs(events) do
table.sort(events[a], evSort)
end
sorted = true
end,
removeFocusedObject = function(self)
if(focusedObject~=nil)then
if(getObject(self, focusedObject)~=nil)then
focusedObject:loseFocusHandler()
end
end
focusedObject = nil
return self
end,
setFocusedObject = function(self, obj)
if(focusedObject~=obj)then
if(focusedObject~=nil)then
if(getObject(self, focusedObject)~=nil)then
focusedObject:loseFocusHandler()
end
end
if(obj~=nil)then
if(getObject(self, obj)~=nil)then
obj:getFocusHandler()
end
end
focusedObject = obj
return true
end
return false
end,
getFocusedObject = function(self)
return focusedObject
end,
getObject = getObject,
getObjects = getObjects,
getDeepObject = getDeepObject,
addObject = addObject,
removeObject = removeObject,
getEvent = getEvent,
addEvent = addEvent,
removeEvent = removeEvent,
updateZIndex = updateZIndex,
listenEvent = function(self, event, active)
base.listenEvent(self, event, active)
activeEvents[event] = active~=nil and active or true
if(events[event]==nil)then events[event] = {} end
return self
end,
customEventHandler = function(self, ...)
base.customEventHandler(self, ...)
for _, o in pairs(elements) do
if (o.element.customEventHandler ~= nil) then
o.element:customEventHandler(...)
end
end
end,
loseFocusHandler = function(self)
base.loseFocusHandler(self)
if(focusedObject~=nil)then focusedObject:loseFocusHandler() focusedObject = nil end
end,
getBasalt = function(self)
return basalt
end,
setPalette = function(self, col, ...)
local parent = self:getParent()
parent:setPalette(col, ...)
return self
end,
eventHandler = function(self, ...)
if(base.eventHandler~=nil)then
base.eventHandler(self, ...)
if(events["other_event"]~=nil)then
self:sortElementOrder()
for _, obj in ipairs(events["other_event"]) do
if (obj.element.eventHandler ~= nil) then
obj.element.eventHandler(obj.element, ...)
end
end
end
end
end,
}
for k,v in pairs({mouse_click={"mouseHandler", true},mouse_up={"mouseUpHandler", false},mouse_drag={"dragHandler", false},mouse_scroll={"scrollHandler", true},mouse_hover={"hoverHandler", false}})do
container[v[1]] = function(self, btn, x, y, ...)
if(base[v[1]]~=nil)then
if(base[v[1]](self, btn, x, y, ...))then
if(events[k]~=nil)then
self:sortElementOrder()
for _, obj in ipairs(events[k]) do
if (obj.element[v[1]] ~= nil) then
local xO, yO = 0, 0
if(self.getOffset~=nil)then
xO, yO = self:getOffset()
end
if (obj.element[v[1]](obj.element, btn, x+xO, y+yO, ...)) then
return true
end
end
end
if(v[2])then
self:removeFocusedObject()
end
return true
end
end
end
end
end
for k,v in pairs({key="keyHandler",key_up="keyUpHandler",char="charHandler"})do
container[v] = function(self, ...)
if(base[v]~=nil)then
if(base[v](self, ...))then
if(events[k]~=nil)then
self:sortElementOrder()
for _, obj in ipairs(events[k]) do
if (obj.element[v] ~= nil) then
if (obj.element[v](obj.element, ...)) then
return true
end
end
end
end
end
end
end
end
for k,v in pairs(basalt.getObjects())do
container["add"..k] = function(self, name)
return addObject(self, v(name, basalt))
end
end
container.__index = container
return setmetatable(container, base)
end

View File

@@ -1,17 +1,15 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = require("utils").getValueFromXML
local tHex = require("tHex")
return function(name)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("List")(name, basalt)
local objectType = "Dropdown"
base.width = 12
base.height = 1
base:setSize(12, 1)
base:setZIndex(6)
local list = {}
local itemSelectedBG
local itemSelectedFG
local itemSelectedBG = colors.black
local itemSelectedFG = colors.lightGray
local selectionColorActive = true
local align = "left"
local yOffset = 0
@@ -25,94 +23,28 @@ return function(name)
local object = {
getType = function(self)
return objectType
end;
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
if(xmlValue("dropdownWidth", data)~=nil)then dropdownW = xmlValue("dropdownWidth", data) end
if(xmlValue("dropdownHeight", data)~=nil)then dropdownH = xmlValue("dropdownHeight", data) end
if(xmlValue("offset", data)~=nil)then yOffset = xmlValue("offset", data) end
if(data["item"]~=nil)then
local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
end
end
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
load = function(self)
self:listenEvent("mouse_click", self)
self:listenEvent("mouse_up", self)
self:listenEvent("mouse_scroll", self)
self:listenEvent("mouse_drag", self)
end,
setOffset = function(self, yOff)
yOffset = yOff
self:updateDraw()
return self
end;
end,
getOffset = function(self)
return yOffset
end;
addItem = function(self, text, bgCol, fgCol, ...)
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
getAll = function(self)
return list
end;
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
getItem = function(self, index)
return list[index]
end;
getItemIndex = function(self)
local selected = self:getValue()
for key, value in pairs(list) do
if (value == selected) then
return key
end
end
end;
clear = function(self)
list = {}
self:setValue({}, false)
self:updateDraw()
return self
end;
getItemCount = function(self)
return #list
end;
editItem = function(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {}, false)
self:updateDraw()
return self
end;
setSelectedItem = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self.bgColor
itemSelectedFG = fgCol or self.fgColor
selectionColorActive = active~=nil and active
self:updateDraw()
return self
end;
end,
setDropdownSize = function(self, width, height)
dropdownW, dropdownH = width, height
@@ -124,20 +56,18 @@ return function(name)
return dropdownW, dropdownH
end,
mouseHandler = function(self, button, x, y, touch)
mouseHandler = function(self, button, x, y)
if (isOpened) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local obx, oby = self:getAbsolutePosition()
if(button==1)then
local list = self:getAll()
if (#list > 0) then
for n = 1, dropdownH do
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
self:setValue(list[n + yOffset])
self:updateDraw()
local val = self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", dir, x, y)
if(touch)then
self:mouseUpHandler(button, x, y)
end
local val = self:sendEvent("mouse_click", self, "mouse_click", dir, x, y)
if(val==false)then return val end
return true
end
@@ -146,8 +76,9 @@ return function(name)
end
end
end
local base = base:getBase()
if (base.mouseHandler(self, button, x, y)) then
isOpened = (not isOpened)
isOpened = true
self:updateDraw()
return true
else
@@ -161,15 +92,16 @@ return function(name)
mouseUpHandler = function(self, button, x, y)
if (isOpened) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local obx, oby = self:getAbsolutePosition()
if(button==1)then
local list = self:getAll()
if (#list > 0) then
for n = 1, dropdownH do
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
isOpened = false
self:updateDraw()
local val = self:getEventSystem():sendEvent("mouse_up", self, "mouse_up", dir, x, y)
local val = self:sendEvent("mouse_up", self, "mouse_up", dir, x, y)
if(val==false)then return val end
return true
end
@@ -182,6 +114,7 @@ return function(name)
scrollHandler = function(self, dir, x, y)
if (isOpened)and(self:isFocused()) then
local list = self:getAll()
yOffset = yOffset + dir
if (yOffset < 0) then
yOffset = 0
@@ -195,7 +128,7 @@ return function(name)
yOffset = math.min(#list - 1, 0)
end
end
local val = self:getEventSystem():sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y)
local val = self:sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y)
if(val==false)then return val end
self:updateDraw()
return true
@@ -203,46 +136,40 @@ return function(name)
end,
draw = function(self)
if (base.draw(self)) then
local obx, oby = self:getAnchorPosition()
base.draw(self)
self:setDrawState("list", false)
self:addDraw("dropdown", function()
local obx, oby = self:getPosition()
local w,h = self:getSize()
if (self.parent ~= nil) then
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
local val = self:getValue()
local text = utils.getTextHorizontalAlign((val~=nil and val.text or ""), w, align):sub(1, w - 1) .. (isOpened and openedSymbol or closedSymbol)
self.parent:writeText(obx, oby, text, self.bgColor, self.fgColor)
local val = self:getValue()
local list = self:getAll()
local bgCol, fgCol = self:getBackground(), self:getForeground()
local text = utils.getTextHorizontalAlign((val~=nil and val.text or ""), w, align):sub(1, w - 1) .. (isOpened and openedSymbol or closedSymbol)
self:addBlit(1, 1, text, tHex[fgCol]:rep(#text), tHex[bgCol]:rep(#text))
if (isOpened) then
for n = 1, dropdownH do
if (list[n + yOffset] ~= nil) then
if (list[n + yOffset] == val) then
if (selectionColorActive) then
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), itemSelectedBG, itemSelectedFG)
else
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
end
if (isOpened) then
self:addTextBox(1, 2, dropdownW, dropdownH, " ")
self:addBackgroundBox(1, 2, dropdownW, dropdownH, bgCol)
self:addForegroundBox(1, 2, dropdownW, dropdownH, fgCol)
for n = 1, dropdownH do
if (list[n + yOffset] ~= nil) then
local t =utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align)
if (list[n + yOffset] == val) then
if (selectionColorActive) then
self:addBlit(1, n+1, t, tHex[itemSelectedFG]:rep(#t), tHex[itemSelectedBG]:rep(#t))
else
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
self:addBlit(1, n+1, t, tHex[list[n + yOffset].fgCol]:rep(#t), tHex[list[n + yOffset].bgCol]:rep(#t))
end
else
self:addBlit(1, n+1, t, tHex[list[n + yOffset].fgCol]:rep(#t), tHex[list[n + yOffset].bgCol]:rep(#t))
end
end
end
end
end
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("DropdownBG")
self.fgColor = self.parent:getTheme("DropdownText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -0,0 +1,95 @@
return function(name, basalt)
local base = basalt.getObject("Frame")(name, basalt)
local objectType = "Flexbox"
local flexDirection = "row" -- "row" oder "column"
local justifyContent = "flex-start" -- "flex-start", "flex-end", "center", "space-between", "space-around"
local spacing = 1
local function applyLayout(self)
local objects = self:getObjects()
local totalElements = #objects
local _, _ = self:getPosition()
local width, height = self:getSize()
local totalChildSize = 0
for _, obj in ipairs(objects) do
if flexDirection == "row" then
local objWidth, _ = obj.element:getSize()
totalChildSize = totalChildSize + objWidth
else
local _, objHeight = obj.element:getSize()
totalChildSize = totalChildSize + objHeight
end
end
local availableSpace = (flexDirection == "row" and width or height) - totalChildSize - (spacing * (totalElements - 1))
local currentOffset = 0
if justifyContent == "center" then
currentOffset = availableSpace / 2
elseif justifyContent == "flex-end" then
currentOffset = availableSpace
end
for _, obj in ipairs(objects) do
if flexDirection == "row" then
obj.element:setPosition(currentOffset, 1) -- Ändere den y-Wert auf 1
local objWidth, _ = obj.element:getSize()
currentOffset = currentOffset + objWidth + spacing
else
obj.element:setPosition(1, math.floor(currentOffset+0.5)) -- Ändere den x-Wert auf 1
local _, objHeight = obj.element:getSize()
currentOffset = currentOffset + objHeight + spacing
end
end
end
local object = {
getType = function()
return objectType
end,
isType = function(self, t)
return objectType == t or base.getBase(self).isType(t) or false
end,
setSpacing = function(self, newSpacing)
spacing = newSpacing
applyLayout(self)
return self
end,
getSpacing = function(self)
return spacing
end,
setFlexDirection = function(self, direction)
if direction == "row" or direction == "column" then
flexDirection = direction
applyLayout(self)
end
return self
end,
setJustifyContent = function(self, alignment)
if alignment == "flex-start" or alignment == "flex-end" or alignment == "center" or alignment == "space-between" or alignment == "space-around" then
justifyContent = alignment
applyLayout(self)
end
return self
end,
}
for k,v in pairs(basalt.getObjects())do
object["add"..k] = function(self, name)
local obj = base["add"..k](self, name)
applyLayout(base)
return obj
end
end
object.__index = object
return setmetatable(object, base)
end

116
Basalt/objects/Frame.lua Normal file
View File

@@ -0,0 +1,116 @@
local utils = require("utils")
local max,min,sub,rep,len = math.max,math.min,string.sub,string.rep,string.len
return function(name, basalt)
local base = basalt.getObject("Container")(name, basalt)
local objectType = "Frame"
local parent
local updateRender = true
local xOffset, yOffset = 0, 0
base:setSize(30, 10)
base:setZIndex(10)
local object = {
getType = function()
return objectType
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
getBase = function(self)
return base
end,
getOffset = function(self)
return xOffset, yOffset
end,
setOffset = function(self, xOff, yOff)
xOffset = xOff or xOffset
yOffset = yOff or yOffset
self:updateDraw()
return self
end,
setParent = function(self, p, ...)
base.setParent(self, p, ...)
parent = p
return self
end,
render = function(self)
if(base.render~=nil)then
if(self:isVisible())then
base.render(self)
local objects = self:getObjects()
for _, obj in ipairs(objects) do
if (obj.element.render ~= nil) then
obj.element:render()
end
end
end
end
end,
updateDraw = function(self)
if(parent~=nil)then
parent:updateDraw()
end
return self
end,
blit = function (self, x, y, t, f, b)
local obx, oby = self:getPosition()
local xO, yO = parent:getOffset()
obx = obx - xO
oby = oby - yO
local w, h = self:getSize()
if y >= 1 and y <= h then
local t_visible = sub(t, max(1 - x + 1, 1), max(w - x + 1, 1))
local f_visible = sub(f, max(1 - x + 1, 1), max(w - x + 1, 1))
local b_visible = sub(b, max(1 - x + 1, 1), max(w - x + 1, 1))
parent:blit(max(x + (obx - 1), obx), oby + y - 1, t_visible, f_visible, b_visible)
end
end,
setCursor = function(self, blink, x, y, color)
local obx, oby = self:getPosition()
parent:setCursor(blink or false, (x or 0)+obx-1, (y or 0)+oby-1, color or colors.white)
return self
end,
}
for k,v in pairs({"drawBackgroundBox", "drawForegroundBox", "drawTextBox"})do
object[v] = function(self, x, y, width, height, symbol)
local obx, oby = self:getPosition()
local xO, yO = parent:getOffset()
obx = obx - xO
oby = oby - yO
height = (y < 1 and (height + y > self:getHeight() and self:getHeight() or height + y - 1) or (height + y > self:getHeight() and self:getHeight() - y + 1 or height))
width = (x < 1 and (width + x > self:getWidth() and self:getWidth() or width + x - 1) or (width + x > self:getWidth() and self:getWidth() - x + 1 or width))
parent[v](parent, max(x + (obx - 1), obx), max(y + (oby - 1), oby), width, height, symbol)
end
end
for k,v in pairs({"setBG", "setFG", "setText"})do
object[v] = function(self, x, y, str)
local obx, oby = self:getPosition()
local xO, yO = parent:getOffset()
obx = obx - xO
oby = oby - yO
local w, h = self:getSize()
if (y >= 1) and (y <= h) then
parent[v](parent, max(x + (obx - 1), obx), oby + y - 1, sub(str, max(1 - x + 1, 1), max(w - x + 1,1)))
end
end
end
object.__index = object
return setmetatable(object, base)
end

159
Basalt/objects/Graph.lua Normal file
View File

@@ -0,0 +1,159 @@
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Graph"
base:setZIndex(5)
base:setSize(30, 10)
local graphData = {}
local graphColor = colors.gray
local graphSymbol = "\7"
local graphSymbolCol = colors.black
local maxValue = 100
local minValue = 0
local graphType = "line"
local maxEntries = 10
local object = {
getType = function(self)
return objectType
end,
setGraphColor = function(self, color)
graphColor = color or graphColor
self:updateDraw()
return self
end,
setGraphSymbol = function(self, symbol, symbolcolor)
graphSymbol = symbol or graphSymbol
graphSymbolCol = symbolcolor or graphSymbolCol
self:updateDraw()
return self
end,
getGraphSymbol = function(self)
return graphSymbol, graphSymbolCol
end,
addDataPoint = function(self, value)
if value >= minValue and value <= maxValue then
table.insert(graphData, value)
self:updateDraw()
end
if(#graphData>100)then -- 100 is hard capped to prevent memory leaks
table.remove(graphData,1)
end
return self
end,
setMaxValue = function(self, value)
maxValue = value
self:updateDraw()
return self
end,
getMaxValue = function(self)
return maxValue
end,
setMinValue = function(self, value)
minValue = value
self:updateDraw()
return self
end,
getMinValue = function(self)
return minValue
end,
setGraphType = function(self, graph_type)
if graph_type == "scatter" or graph_type == "line" or graph_type == "bar" then
graphType = graph_type
self:updateDraw()
end
return self
end,
setMaxEntries = function(self, value)
maxEntries = value
self:updateDraw()
return self
end,
getMaxEntries = function(self)
return maxEntries
end,
clear = function(self)
graphData = {}
self:updateDraw()
return self
end,
draw = function(self)
base.draw(self)
self:addDraw("graph", function()
local obx, oby = self:getPosition()
local w, h = self:getSize()
local bgCol, fgCol = self:getBackground(), self:getForeground()
local range = maxValue - minValue
local prev_x, prev_y
local startIndex = #graphData - maxEntries + 1
if startIndex < 1 then startIndex = 1 end
for i = startIndex, #graphData do
local data = graphData[i]
local x = math.floor(((w - 1) / (maxEntries - 1)) * (i - startIndex) + 1.5)
local y = math.floor((h - 1) - ((h - 1) / range) * (data - minValue) + 1.5)
if graphType == "scatter" then
self:addBackgroundBox(x, y, 1, 1, graphColor)
self:addForegroundBox(x, y, 1, 1, graphSymbolCol)
self:addTextBox(x, y, 1, 1, graphSymbol)
elseif graphType == "line" then
if prev_x and prev_y then
local dx = math.abs(x - prev_x)
local dy = math.abs(y - prev_y)
local sx = prev_x < x and 1 or -1
local sy = prev_y < y and 1 or -1
local err = dx - dy
while true do
self:addBackgroundBox(prev_x, prev_y, 1, 1, graphColor)
self:addForegroundBox(prev_x, prev_y, 1, 1, graphSymbolCol)
self:addTextBox(prev_x, prev_y, 1, 1, graphSymbol)
if prev_x == x and prev_y == y then
break
end
local e2 = 2 * err
if e2 > -dy then
err = err - dy
prev_x = prev_x + sx
end
if e2 < dx then
err = err + dx
prev_y = prev_y + sy
end
end
end
prev_x, prev_y = x, y
elseif graphType == "bar" then
self:addBackgroundBox(x - 1, y, 1, h - y, graphColor)
end
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,115 +1,195 @@
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
local images = require("images")
local unpack,sub = table.unpack,string.sub
return function(name)
local bimg = require("bimg")
local unpack,sub,max,min = table.unpack,string.sub,math.max,math.min
return function(name, basalt)
-- Image
local base = Object(name)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Image"
base:setZIndex(2)
local bimgLibrary = bimg()
local bimgFrame = bimgLibrary.getFrameObject(1)
local originalImage
local image
local curFrame = 1
local activeFrame = 1
local infinitePlay = false
local animTimer
local usePalette = false
base.width = 24
base.height = 8
local xOffset, yOffset = 0, 0
base:setSize(24, 8)
base:setZIndex(2)
local function getPalette(id)
if(originalImage~=nil)then
local p = {}
for k,v in pairs(colors)do
if(type(v)=="number")then
p[v] = {term.nativePaletteColor(v)}
end
local p = {}
for k,v in pairs(colors)do
if(type(v)=="number")then
p[k] = {term.nativePaletteColor(v)}
end
if(originalImage.palette~=nil)then
for k,v in pairs(originalImage.palette)do
p[2^k] = v
end
end
if(originalImage[id]~=nil)and(originalImage[id].palette~=nil)then
for k,v in pairs(originalImage[id].palette)do
p[2^k] = v
end
end
return p
end
local globalPalette = bimgLibrary.getMetadata("palette")
if(globalPalette~=nil)then
for k,v in pairs(globalPalette)do
p[k] = tonumber(v)
end
end
local localPalette = bimgLibrary.getFrameData("palette")
basalt.log(localPalette)
if(localPalette~=nil)then
for k,v in pairs(localPalette)do
p[k] = tonumber(v)
end
end
return p
end
local object = {
init = function(self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ImageBG")
end
end,
getType = function(self)
return objectType
end;
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
loadImage = function(self, path, f)
if not(fs.exists(path))then error("No valid path: "..path) end
originalImage = images.loadImageAsBimg(path, f)
curFrame = 1
image = originalImage
if(animTimer~=nil)then
os.cancelTimer(animTimer)
setOffset = function(self, _x, _y, rel)
if(rel)then
xOffset = xOffset + _x or 0
yOffset = yOffset + _y or 0
else
xOffset = _x or xOffset
yOffset = _y or yOffset
end
self:updateDraw()
return self
end;
end,
setImage = function(self, data)
originalImage = data
image = originalImage
curFrame = 1
if(animTimer~=nil)then
os.cancelTimer(animTimer)
getOffset = function(self)
return xOffset, yOffset
end,
selectFrame = function(self, id)
if(bimgLibrary.getFrameObject(id)==nil)then
bimgLibrary.addFrame(id)
end
bimgFrame = bimgLibrary.getFrameObject(id)
image = bimgFrame.getImage(id)
selectedFrame = id
self:updateDraw()
end,
addFrame = function(self, id)
bimgLibrary.addFrame(id)
return self
end,
getFrame = function(self, id)
return bimgLibrary.getFrame(id)
end,
getFrameObject = function(self, id)
return bimgLibrary.getFrameObject(id)
end,
removeFrame = function(self, id)
bimgLibrary.removeFrame(id)
return self
end,
moveFrame = function(self, id, dir)
bimgLibrary.moveFrame(id, dir)
return self
end,
getFrames = function(self)
return bimgLibrary.getFrames()
end,
getFrameCount = function(self)
return #bimgLibrary.getFrames()
end,
getActiveFrame = function(self)
return activeFrame
end,
loadImage = function(self, path)
if(fs.exists(path))then
local newBimg = images.loadBIMG(path)
bimgLibrary = bimg(newBimg)
selectedFrame = 1
bimgFrame = bimgLibrary.getFrameObject(1)
originalImage = bimgLibrary.createBimg()
image = bimgFrame.getImage()
self:updateDraw()
end
return self
end,
setImage = function(self, t)
if(type(t)=="table")then
bimgLibrary = bimg(t)
selectedFrame = 1
bimgFrame = bimgLibrary.getFrameObject(1)
originalImage = bimgLibrary.createBimg()
image = bimgFrame.getImage()
self:updateDraw()
end
return self
end,
clear = function(self)
bimgLibrary = bimg()
bimgFrame = bimgLibrary.getFrameObject(1)
image = nil
self:updateDraw()
return self
end,
getImage = function(self)
return bimgLibrary.createBimg()
end,
getImageFrame = function(self, id)
return bimgFrame.getImage(id)
end,
usePalette = function(self, use)
usePalette = use~=nil and use or true
return self
end,
play = function(self, inf)
if(originalImage.animated)then
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
self.parent:addEvent("other_event", self)
if(bimgLibrary.getMetadata("animated"))then
local t = bimgLibrary.getMetadata("duration") or bimgLibrary.getMetadata("secondsPerFrame") or 0.2
self:listenEvent("other_event")
animTimer = os.startTimer(t)
infinitePlay = inf or false
end
return self
end,
selectFrame = function(self, fr)
if(originalImage[fr]~=nil)then
curFrame = fr
if(animTimer~=nil)then
os.cancelTimer(animTimer)
end
self:updateDraw()
end
stop = function(self)
os.cancelTimer(animTimer)
animTimer = nil
infinitePlay = false
return self
end,
eventHandler = function(self, event, timerId, ...)
base.eventHandler(self, event, timerId, ...)
if(event=="timer")then
if(timerId==animTimer)then
if(originalImage[curFrame+1]~=nil)then
curFrame = curFrame + 1
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
if(bimgLibrary.getFrame(activeFrame+1)~=nil)then
activeFrame = activeFrame + 1
self:selectFrame(activeFrame)
local t = bimgLibrary.getFrameData(activeFrame, "duration") or bimgLibrary.getMetadata("secondsPerFrame") or 0.2
animTimer = os.startTimer(t)
else
if(infinitePlay)then
curFrame = 1
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
activeFrame = 1
self:selectFrame(activeFrame)
local t = bimgLibrary.getFrameData(activeFrame, "duration") or bimgLibrary.getMetadata("secondsPerFrame") or 0.2
animTimer = os.startTimer(t)
end
end
@@ -118,46 +198,117 @@ return function(name)
end
end,
setMetadata = function(self, key, value)
bimgLibrary.setMetadata(key, value)
return self
end,
getMetadata = function(self, key)
return originalImage[key]
return bimgLibrary.getMetadata(key)
end,
getImageSize = function(self)
return originalImage.width, originalImage.height
getFrameMetadata = function(self, id, key)
return bimgLibrary.getFrameData(id, key)
end,
resizeImage = function(self, w, h)
image = images.resizeBIMG(originalImage, w, h)
setFrameMetadata = function(self, id, key, value)
bimgLibrary.setFrameData(id, key, value)
return self
end,
blit = function(self, text, fg, bg, _x, _y)
x = _x or x
y = _y or y
bimgFrame.blit(text, fg, bg, x, y)
image = bimgFrame.getImage()
self:updateDraw()
return self
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("path", data)~=nil)then self:loadImage(xmlValue("path", data)) end
setText = function(self, text, _x, _y)
x = _x or x
y = _y or y
bimgFrame.text(text, x, y)
image = bimgFrame.getImage()
self:updateDraw()
return self
end,
setBg = function(self, bg, _x, _y)
x = _x or x
y = _y or y
bimgFrame.bg(bg, x, y)
image = bimgFrame.getImage()
self:updateDraw()
return self
end,
setFg = function(self, fg, _x, _y)
x = _x or x
y = _y or y
bimgFrame.fg(fg, x, y)
image = bimgFrame.getImage()
self:updateDraw()
return self
end,
getImageSize = function(self)
return bimgLibrary.getSize()
end,
setImageSize = function(self, w, h)
bimgLibrary.setSize(w, h)
image = bimgFrame.getImage()
self:updateDraw()
return self
end,
resizeImage = function(self, w, h)
local newBimg = images.resizeBIMG(originalImage, w, h)
bimgLibrary = bimg(newBimg)
selectedFrame = 1
bimgFrame = bimgLibrary.getFrameObject(1)
image = bimgFrame.getImage()
self:updateDraw()
return self
end,
draw = function(self)
if (base.draw(self)) then
if (image ~= nil) then
if(usePalette)then
self:getBaseFrame():setThemeColor(getPalette(curFrame))
end
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
for y,v in ipairs(image[curFrame])do
local t, f, b = unpack(v)
t = sub(t, 1,w)
f = sub(f, 1,w)
b = sub(b, 1,w)
self.parent:blit(obx, oby+y-1, t, f, b)
if(y==h)then break end
base.draw(self)
self:addDraw("image", function()
local w,h = self:getSize()
local x, y = self:getPosition()
local wParent, hParent = self:getParent():getSize()
local parentXOffset, parentYOffset = self:getParent():getOffset()
if(x - parentXOffset > wParent)or(y - parentYOffset > hParent)or(x - parentXOffset + w < 1)or(y - parentYOffset + h < 1)then
return
end
if(usePalette)then
self:getParent():setPalette(getPalette(activeFrame))
end
if(image~=nil)then
for k,v in pairs(image)do
if(k+yOffset<=h)and(k+yOffset>=1)then
local t,f,b = v[1],v[2],v[3]
local startIdx = max(1 - xOffset, 1)
local endIdx = min(w - xOffset, #t)
t = sub(t, startIdx, endIdx)
f = sub(f, startIdx, endIdx)
b = sub(b, startIdx, endIdx)
self:addBlit(max(1 + xOffset, 1), k + yOffset, t, f, b)
end
end
end
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,46 +1,46 @@
local Object = require("Object")
local utils = require("utils")
local log = require("basaltLogs")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
return function(name, basalt)
-- Input
local base = Object(name)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Input"
local inputType = "text"
local inputLimit = 0
base:setZIndex(5)
base:setValue("")
base.width = 10
base.height = 1
base:setSize(12, 1)
local textX = 1
local wIndex = 1
local defaultText = ""
local defaultBGCol
local defaultFGCol
local defaultBGCol = colors.black
local defaultFGCol = colors.white
local showingText = defaultText
local internalValueChange = false
local object = {
load = function(self)
self:listenEvent("mouse_click")
self:listenEvent("key")
self:listenEvent("char")
self:listenEvent("other_event")
self:listenEvent("mouse_drag")
end,
getType = function(self)
return objectType
end;
setInputType = function(self, iType)
if (iType == "password") or (iType == "number") or (iType == "text") then
inputType = iType
end
self:updateDraw()
return self
end;
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
setDefaultText = function(self, text, fCol, bCol)
defaultText = text
defaultBGCol = bCol or defaultBGCol
defaultFGCol = fCol or defaultFGCol
defaultBGCol = bCol or defaultBGCol
if (self:isFocused()) then
showingText = ""
else
@@ -48,11 +48,41 @@ return function(name)
end
self:updateDraw()
return self
end;
end,
getDefaultText = function(self)
return defaultText, defaultFGCol, defaultBGCol
end,
setOffset = function(self, x)
wIndex = x
self:updateDraw()
return self
end,
getOffset = function(self)
return wIndex
end,
setTextOffset = function(self, x)
textX = x
self:updateDraw()
return self
end,
getTextOffset = function(self)
return textX
end,
setInputType = function(self, t)
inputType = t
self:updateDraw()
return self
end,
getInputType = function(self)
return inputType
end;
end,
setValue = function(self, val)
base.setValue(self, tostring(val))
@@ -60,105 +90,84 @@ return function(name)
textX = tostring(val):len() + 1
wIndex = math.max(1, textX-self:getWidth()+1)
if(self:isFocused())then
local obx, oby = self:getAnchorPosition()
self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor)
local parent = self:getParent()
local obx, oby = self:getPosition()
parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self:getForeground())
end
end
self:updateDraw()
return self
end;
end,
getValue = function(self)
local val = base.getValue(self)
return inputType == "number" and tonumber(val) or val
end;
end,
setInputLimit = function(self, limit)
inputLimit = tonumber(limit) or inputLimit
self:updateDraw()
return self
end;
end,
getInputLimit = function(self)
return inputLimit
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
local dBG,dFG
if(xmlValue("defaultBG", data)~=nil)then dBG = xmlValue("defaultBG", data) end
if(xmlValue("defaultFG", data)~=nil)then dFG = xmlValue("defaultFG", data) end
if(xmlValue("default", data)~=nil)then self:setDefaultText(xmlValue("default", data), dFG~=nil and colors[dFG], dBG~=nil and colors[dBG]) end
if(xmlValue("limit", data)~=nil)then self:setInputLimit(xmlValue("limit", data)) end
if(xmlValue("type", data)~=nil)then self:setInputType(xmlValue("type", data)) end
return self
end,
getFocusHandler = function(self)
base.getFocusHandler(self)
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local parent = self:getParent()
if (parent ~= nil) then
local obx, oby = self:getPosition()
showingText = ""
if(defaultText~="")then
self:updateDraw()
end
self.parent:setCursor(true, obx + textX - wIndex, oby+math.max(math.ceil(self:getHeight()/2-1, 1)), self.fgColor)
parent:setCursor(true, obx + textX - wIndex, oby+math.max(math.ceil(self:getHeight()/2-1, 1)), self:getForeground())
end
end;
end,
loseFocusHandler = function(self)
base.loseFocusHandler(self)
if (self.parent ~= nil) then
showingText = defaultText
if(defaultText~="")then
self:updateDraw()
end
self.parent:setCursor(false)
local parent = self:getParent()
showingText = defaultText
if(defaultText~="")then
self:updateDraw()
end
end;
parent:setCursor(false)
end,
keyHandler = function(self, key)
if (base.keyHandler(self, key)) then
local w,h = self:getSize()
local parent = self:getParent()
internalValueChange = true
if (key == keys.backspace) then
-- on backspace
local text = tostring(base.getValue())
if (textX > 1) then
self:setValue(text:sub(1, textX - 2) .. text:sub(textX, text:len()))
if (textX > 1) then
textX = textX - 1
end
if (wIndex > 1) then
if (textX < wIndex) then
wIndex = wIndex - 1
end
textX = math.max(textX - 1, 1)
if (textX < wIndex) then
wIndex = math.max(wIndex - 1, 1)
end
end
end
if (key == keys.enter) then
-- on enter
if (self.parent ~= nil) then
--self.parent:removeFocusedObject(self)
end
parent:removeFocusedObject(self)
end
if (key == keys.right) then
-- right arrow
local tLength = tostring(base.getValue()):len()
textX = textX + 1
if (textX > tLength) then
textX = tLength + 1
end
if (textX < 1) then
textX = 1
end
textX = math.max(textX, 1)
if (textX < wIndex) or (textX >= w + wIndex) then
wIndex = textX - w + 1
end
if (wIndex < 1) then
wIndex = 1
end
wIndex = math.max(wIndex, 1)
end
if (key == keys.left) then
@@ -169,29 +178,16 @@ return function(name)
wIndex = textX
end
end
if (textX < 1) then
textX = 1
end
if (wIndex < 1) then
wIndex = 1
end
textX = math.max(textX, 1)
wIndex = math.max(wIndex, 1)
end
local obx, oby = self:getAnchorPosition()
local obx, oby = self:getPosition()
local val = tostring(base.getValue())
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
local inpX = self:getX()
if (cursorX > inpX + w - 1) then
cursorX = inpX + w - 1
end
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
end
self:updateDraw()
internalValueChange = false
return true
end
return false
end,
charHandler = function(self, char)
@@ -220,27 +216,19 @@ return function(name)
wIndex = wIndex + 1
end
end
local obx, oby = self:getAnchorPosition()
local obx, oby = self:getPosition()
local val = tostring(base.getValue())
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
local x = self:getX()
if (cursorX > x + w - 1) then
cursorX = x + w - 1
end
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
end
internalValueChange = false
self:updateDraw()
return true
end
return false
end,
mouseHandler = function(self, button, x, y)
if(base.mouseHandler(self, button, x, y))then
local ax, ay = self:getAnchorPosition()
local parent = self:getParent()
local ax, ay = self:getPosition()
local obx, oby = self:getAbsolutePosition(ax, ay)
local w, h = self:getSize()
textX = x - obx + wIndex
@@ -254,7 +242,7 @@ return function(name)
wIndex = 1
end
end
self.parent:setCursor(true, ax + textX - wIndex, ay+math.max(math.ceil(h/2-1, 1)), self.fgColor)
parent:setCursor(true, ax + textX - wIndex, ay+math.max(math.ceil(h/2-1, 1)), self:getForeground())
return true
end
end,
@@ -266,108 +254,51 @@ return function(name)
return true
end
end
self.parent:removeFocusedObject()
end
end,
eventHandler = function(self, event, paste, ...)
base.eventHandler(self, event, paste, ...)
if(event=="paste")then
if(self:isFocused())then
local text = base.getValue()
local w, h = self:getSize()
internalValueChange = true
if (inputType == "number") then
local cache = text
if (paste == ".") or (tonumber(paste) ~= nil) then
self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len()))
textX = textX + paste:len()
end
if (tonumber(base.getValue()) == nil) then
self:setValue(cache)
end
else
self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len()))
textX = textX + paste:len()
end
if (textX >= w + wIndex) then
wIndex = (textX+1)-w
end
local obx, oby = self:getAnchorPosition()
local val = tostring(base.getValue())
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
local x = self:getX()
if (cursorX > x + w - 1) then
cursorX = x + w - 1
end
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
end
self:updateDraw()
internalValueChange = false
end
local parent = self:getParent()
parent:removeFocusedObject()
end
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, "center")
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
for n = 1, h do
if (n == verticalAlign) then
local val = tostring(base.getValue())
local bCol = self.bgColor
local fCol = self.fgColor
local text
if (val:len() <= 0) then
text = showingText
bCol = defaultBGCol or bCol
fCol = defaultFGCol or fCol
end
text = showingText
if (val ~= "") then
text = val
end
text = text:sub(wIndex, w + wIndex - 1)
local space = w - text:len()
if (space < 0) then
space = 0
end
if (inputType == "password") and (val ~= "") then
text = string.rep("*", text:len())
end
text = text .. string.rep(self.bgSymbol, space)
self.parent:writeText(obx, oby + (n - 1), text, bCol, fCol)
end
end
if(self:isFocused())then
self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor)
end
base.draw(self)
self:addDraw("input", function()
local parent = self:getParent()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
local val = tostring(base.getValue())
local bCol = self:getBackground()
local fCol = self:getForeground()
local text
if (val:len() <= 0) then
text = showingText
bCol = defaultBGCol or bCol
fCol = defaultFGCol or fCol
end
end
end,
init = function(self)
if(self.parent~=nil)then
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("key", self)
self.parent:addEvent("char", self)
self.parent:addEvent("other_event", self)
self.parent:addEvent("mouse_drag", self)
end
if(base.init(self))then
self.bgColor = self.parent:getTheme("InputBG")
self.fgColor = self.parent:getTheme("InputText")
end
text = showingText
if (val ~= "") then
text = val
end
text = text:sub(wIndex, w + wIndex - 1)
local space = w - text:len()
if (space < 0) then
space = 0
end
if (inputType == "password") and (val ~= "") then
text = string.rep("*", text:len())
end
text = text .. string.rep(" ", space)
self:addBlit(1, verticalAlign, text, tHex[fCol]:rep(text:len()), tHex[bCol]:rep(text:len()))
if(self:isFocused())then
parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self:getForeground())
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,170 +1,94 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local createText = utils.createText
local wrapText = utils.wrapText
local tHex = require("tHex")
local bigFont = require("bigfont")
return function(name)
return function(name, basalt)
-- Label
local base = Object(name)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Label"
base:setZIndex(3)
local autoSize = true
base:setValue("Label")
base.width = 5
local textHorizontalAlign = "left"
local textVerticalAlign = "top"
local fontsize = 0
local fgColChanged,bgColChanged = false,false
local text, textAlign = "Label", "left"
local object = {
getType = function(self)
return objectType
end;
end,
getBase = function(self)
return base
end,
setText = function(self, text)
text = tostring(text)
base:setValue(text)
if (autoSize) then
local xOffset = self.parent:getOffset()
if(text:len()+self:getX()>self.parent:getWidth()+xOffset)then
local newW = self.parent:getWidth()+xOffset - self:getX()
base.setSize(self, newW, #createText(text, newW))
else
base.setSize(self, text:len(), 1)
end
setText = function(self, newText)
text = tostring(newText)
if(autoSize)then
self:setSize(#text, 1)
autoSize = true
end
self:updateDraw()
return self
end;
end,
getText = function(self)
return text
end,
setBackground = function(self, col)
base.setBackground(self, col)
bgColChanged = true
self:updateDraw()
return self
end,
setForeground = function(self, col)
base.setForeground(self, col)
fgColChanged = true
self:updateDraw()
return self
end,
setTextAlign = function(self, hor, vert)
textHorizontalAlign = hor or textHorizontalAlign
textVerticalAlign = vert or textVerticalAlign
self:updateDraw()
return self
end;
setFontSize = function(self, size)
if(size>0)and(size<=4)then
fontsize = size-1 or 0
end
self:updateDraw()
return self
end;
getFontSize = function(self)
return fontsize+1
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end
if(xmlValue("verticalAlign", data)~=nil)then textVerticalAlign = xmlValue("verticalAlign", data) end
if(xmlValue("horizontalAlign", data)~=nil)then textHorizontalAlign = xmlValue("horizontalAlign", data) end
if(xmlValue("font", data)~=nil)then self:setFontSize(xmlValue("font", data)) end
return self
end,
setSize = function(self, width, height, rel)
base.setSize(self, width, height, rel)
setSize = function(self, ...)
base.setSize(self, ...)
autoSize = false
self:updateDraw()
return self
end;
end,
eventHandler = function(self, event)
if(event=="basalt_resize")then
if (autoSize) then
local text = self:getValue()
if(text:len()+self:getX()>self.parent:getWidth())then
local newW = self.parent:getWidth() - self:getX()
base.setSize(self, newW, #createText(text, newW))
else
base.setSize(self, text:len(), 1)
end
else
--self.parent:removeEvent("other_event", self)
end
end
setTextAlign = function(self, align)
textAlign = align or textAlign
return self;
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
if(fontsize==0)then
if not(autoSize)then
local text = createText(self:getValue(), self:getWidth())
for k,v in pairs(text)do
if(k<=h)then
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
end
end
else
if(#self:getValue()+obx>self.parent:getWidth())then
local text = createText(self:getValue(), self:getWidth())
for k,v in pairs(text)do
if(k<=h)then
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
end
end
else
self.parent:writeText(obx, oby, self:getValue(), self.bgColor, self.fgColor)
end
base.draw(self)
self:addDraw("label", function()
local parent = self:getParent()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local bgCol,fgCol = self:getBackground(), self:getForeground()
if not(autoSize)then
local text = wrapText(text, w)
for k,v in pairs(text)do
if(k<=h)then
local align = textAlign=="center" and math.floor(w/2-v:len()/2+0.5) or textAlign=="right" and w-(v:len()-1) or 1
self:addText(align, k, v)
end
else
local tData = bigFont(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.lightGray)
if(autoSize)then
self:setSize(#tData[1][1], #tData[1]-1)
end
local oX, oY = self.parent:getSize()
local cX, cY = #tData[1][1], #tData[1]
obx = obx or math.floor((oX - cX) / 2) + 1
oby = oby or math.floor((oY - cY) / 2) + 1
for i = 1, cY do
self.parent:setFG(obx, oby + i - 1, tData[2][i])
self.parent:setBG(obx, oby + i - 1, tData[3][i])
self.parent:setText(obx, oby + i - 1, tData[1][i])
end
end
else
self:addText(1, 1, text:sub(1,w))
end
end
end)
end,
init = function(self)
self.parent:addEvent("other_event", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("LabelBG")
self.fgColor = self.parent:getTheme("LabelText")
if(self.parent.bgColor==colors.black)and(self.fgColor==colors.black)then
self.fgColor = colors.lightGray
end
end
base.init(self)
local parent = self:getParent()
self:setForeground(parent:getForeground())
self:setBackground(parent:getBackground())
end
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,59 +1,87 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "List"
base.width = 16
base.height = 6
base:setZIndex(5)
local list = {}
local itemSelectedBG
local itemSelectedFG
local itemSelectedBG = colors.black
local itemSelectedFG = colors.lightGray
local selectionColorActive = true
local align = "left"
local textAlign = "left"
local yOffset = 0
local scrollable = true
base:setSize(16, 8)
base:setZIndex(5)
local object = {
init = function(self)
local parent = self:getParent()
self:listenEvent("mouse_click")
self:listenEvent("mouse_drag")
self:listenEvent("mouse_scroll")
return base.init(self)
end,
getBase = function(self)
return base
end,
setTextAlign = function(self, align)
textAlign = align
return self
end,
getTextAlign = function(self)
return textAlign
end,
getBase = function(self)
return base
end,
getType = function(self)
return objectType
end;
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
addItem = function(self, text, bgCol, fgCol, ...)
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
table.insert(list, { text = text, bgCol = bgCol or self:getBackground(), fgCol = fgCol or self:getForeground(), args = { ... } })
if (#list <= 1) then
self:setValue(list[1], false)
end
self:updateDraw()
return self
end;
end,
setOffset = function(self, yOff)
yOffset = yOff
self:updateDraw()
return self
end;
end,
getOffset = function(self)
return yOffset
end;
end,
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
end,
getItem = function(self, index)
return list[index]
end;
end,
getAll = function(self)
return list
end;
end,
getItemIndex = function(self)
local selected = self:getValue()
@@ -62,61 +90,53 @@ return function(name)
return key
end
end
end;
end,
clear = function(self)
list = {}
self:setValue({}, false)
self:updateDraw()
return self
end;
end,
getItemCount = function(self)
return #list
end;
end,
editItem = function(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
table.insert(list, index, { text = text, bgCol = bgCol or self:getBackground(), fgCol = fgCol or self:getForeground(), args = { ... } })
self:updateDraw()
return self
end;
end,
selectItem = function(self, index)
self:setValue(list[index] or {}, false)
self:updateDraw()
return self
end;
end,
setSelectedItem = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self.bgColor
itemSelectedFG = fgCol or self.fgColor
setSelectionColor = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self:getBackground()
itemSelectedFG = fgCol or self:getForeground()
selectionColorActive = active~=nil and active or true
self:updateDraw()
return self
end;
end,
getSelectionColor = function(self)
return itemSelectedBG, itemSelectedFG
end,
isSelectionColorActive = function(self)
return selectionColorActive
end,
setScrollable = function(self, scroll)
scrollable = scroll
if(scroll==nil)then scrollable = true end
self:updateDraw()
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
if(xmlValue("scrollable", data)~=nil)then if(xmlValue("scrollable", data))then self:setScrollable(true) else self:setScrollable(false) end end
if(xmlValue("offset", data)~=nil)then yOffset = xmlValue("offset", data) end
if(data["item"]~=nil)then
local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
end
end
return self
end,
scrollHandler = function(self, dir, x, y)
@@ -148,7 +168,7 @@ return function(name)
mouseHandler = function(self, button, x, y)
if(base.mouseHandler(self, button, x, y))then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local obx, oby = self:getAbsolutePosition()
local w,h = self:getSize()
if (#list > 0) then
for n = 1, h do
@@ -174,42 +194,25 @@ return function(name)
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
end
for n = 1, h do
if (list[n + yOffset] ~= nil) then
if (list[n + yOffset] == self:getValue()) then
if (selectionColorActive) then
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), itemSelectedBG, itemSelectedFG)
else
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
end
else
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
end
base.draw(self)
self:addDraw("list", function()
local parent = self:getParent()
local obx, oby = self:getPosition()
local w, h = self:getSize()
for n = 1, h do
if list[n + yOffset] then
local t = list[n + yOffset].text
local fg, bg = list[n + yOffset].fgCol, list[n + yOffset].bgCol
if list[n + yOffset] == self:getValue() and selectionColorActive then
fg, bg = itemSelectedFG, itemSelectedBG
end
self:addBlit(1, n, t, tHex[fg]:rep(#t), tHex[bg]:rep(#t))
end
end
end
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ListBG")
self.fgColor = self.parent:getTheme("ListText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,170 +1,69 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("List")(name, basalt)
local objectType = "Menubar"
local object = {}
base.width = 30
base.height = 1
base:setSize(30, 1)
base:setZIndex(5)
local list = {}
local itemSelectedBG
local itemSelectedFG
local selectionColorActive = true
local align = "left"
local itemOffset = 0
local space = 1
local scrollable = false
local space, outerSpace = 1, 1
local scrollable = true
local function maxScroll()
local mScroll = 0
local xPos = 0
local w = object:getWidth()
local w = base:getWidth()
local list = base:getAll()
for n = 1, #list do
if (xPos + list[n].text:len() + space * 2 > w) then
if(xPos < w)then
mScroll = mScroll + (list[n].text:len() + space * 2-(w - xPos))
else
mScroll = mScroll + list[n].text:len() + space * 2
end
end
xPos = xPos + list[n].text:len() + space * 2
mScroll = mScroll + list[n].text:len() + space * 2
end
return mScroll
return math.max(mScroll - w, 0)
end
object = {
init = function(self)
local parent = self:getParent()
self:listenEvent("mouse_click")
self:listenEvent("mouse_drag")
self:listenEvent("mouse_scroll")
return base.init(self)
end,
getType = function(self)
return objectType
end;
end,
addItem = function(self, text, bgCol, fgCol, ...)
table.insert(list, { text = tostring(text), bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
if (#list == 1) then
self:setValue(list[1])
end
self:updateDraw()
return self
end;
getAll = function(self)
return list
end;
getItemIndex = function(self)
local selected = self:getValue()
for key, value in pairs(list) do
if (value == selected) then
return key
end
end
end;
clear = function(self)
list = {}
self:setValue({}, false)
self:updateDraw()
return self
end;
getBase = function(self)
return base
end,
setSpace = function(self, _space)
space = _space or space
self:updateDraw()
return self
end;
setOffset = function(self, offset)
itemOffset = offset or 0
if (itemOffset < 0) then
itemOffset = 0
end
local mScroll = maxScroll()
if (itemOffset > mScroll) then
itemOffset = mScroll
end
self:updateDraw()
return self
end;
getOffset = function(self)
return itemOffset
end;
end,
setScrollable = function(self, scroll)
scrollable = scroll
if(scroll==nil)then scrollable = true end
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
if(xmlValue("scrollable", data)~=nil)then if(xmlValue("scrollable", data))then self:setScrollable(true) else self:setScrollable(false) end end
if(xmlValue("offset", data)~=nil)then self:setOffset(xmlValue("offset", data)) end
if(xmlValue("space", data)~=nil)then space = xmlValue("space", data) end
if(data["item"]~=nil)then
local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
end
end
return self
end,
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
getItem = function(self, index)
return list[index]
end;
getItemCount = function(self)
return #list
end;
editItem = function(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {}, false)
self:updateDraw()
return self
end;
setSelectedItem = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self.bgColor
itemSelectedFG = fgCol or self.fgColor
selectionColorActive = active
self:updateDraw()
return self
end;
mouseHandler = function(self, button, x, y)
if(base.mouseHandler(self, button, x, y))then
local objX, objY = self:getAbsolutePosition(self:getAnchorPosition())
if(base:getBase().mouseHandler(self, button, x, y))then
local objX, objY = self:getAbsolutePosition()
local w,h = self:getSize()
local xPos = 0
local list = self:getAll()
for n = 1, #list do
if (list[n] ~= nil) then
if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then
self:setValue(list[n])
self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n])
self:sendEvent(event, self, event, 0, x, y, list[n])
end
xPos = xPos + list[n].text:len() + space * 2
end
@@ -172,11 +71,10 @@ return function(name)
self:updateDraw()
return true
end
return false
end,
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
if(base:getBase().scrollHandler(self, dir, x, y))then
if(scrollable)then
itemOffset = itemOffset + dir
if (itemOffset < 0) then
@@ -196,46 +94,32 @@ return function(name)
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
base.draw(self)
self:addDraw("list", function()
local parent = self:getParent()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local text = ""
local textBGCol = ""
local textFGCol = ""
local itemSelectedBG, itemSelectedFG = self:getSelectionColor()
for _, v in pairs(self:getAll()) do
local newItem = (" "):rep(space) .. v.text .. (" "):rep(space)
text = text .. newItem
if(v == self:getValue())then
textBGCol = textBGCol .. tHex[itemSelectedBG or v.bgCol or self:getBackground()]:rep(newItem:len())
textFGCol = textFGCol .. tHex[itemSelectedFG or v.FgCol or self:getForeground()]:rep(newItem:len())
else
textBGCol = textBGCol .. tHex[v.bgCol or self:getBackground()]:rep(newItem:len())
textFGCol = textFGCol .. tHex[v.FgCol or self:getForeground()]:rep(newItem:len())
end
local text = ""
local textBGCol = ""
local textFGCol = ""
for _, v in pairs(list) do
local newItem = (" "):rep(space) .. v.text .. (" "):rep(space)
text = text .. newItem
if(v == self:getValue())then
textBGCol = textBGCol .. tHex[itemSelectedBG or v.bgCol or self.bgColor]:rep(newItem:len())
textFGCol = textFGCol .. tHex[itemSelectedFG or v.FgCol or self.fgColor]:rep(newItem:len())
else
textBGCol = textBGCol .. tHex[v.bgCol or self.bgColor]:rep(newItem:len())
textFGCol = textFGCol .. tHex[v.FgCol or self.fgColor]:rep(newItem:len())
end
end
self.parent:setText(obx, oby, text:sub(itemOffset+1, w+itemOffset))
self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, w+itemOffset))
self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, w+itemOffset))
end
end
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("MenubarBG")
self.fgColor = self.parent:getTheme("MenubarText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end
self:addBlit(1, 1, text:sub(itemOffset+1, w+itemOffset), textFGCol:sub(itemOffset+1, w+itemOffset), textBGCol:sub(itemOffset+1, w+itemOffset))
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -0,0 +1,40 @@
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:hide()
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, name)
local mon = peripheral.wrap(name)
if(mon~=nil)then
self:setTerm(mon)
end
return self
end,
show = function(self)
if(basalt.getTerm()~=self:getTerm())then
base.show()
end
return self
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -0,0 +1,92 @@
local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("Frame")(name, basalt)
local objectType = "MovableFrame"
local parent
local dragXOffset, dragYOffset = 0, 0
local dragMap = {
{x1 = 1, x2 = "width", y1 = 1, y2 = 1}
}
local object = {
getType = function()
return objectType
end,
setDraggingMap = function(self, t)
dragMap = t
return self
end,
getDraggingMap = function(self)
return dragMap
end,
isType = function(self, t)
return objectType==t or (base.isType~=nil and base.isType(t)) or false
end,
getBase = function(self)
return base
end,
load = function(self)
base.load(self)
self:listenEvent("mouse_click")
self:listenEvent("mouse_up")
self:listenEvent("mouse_drag")
end,
dragHandler = function(self, btn, x, y)
if(base.dragHandler(self, btn, x, y))then
if (isDragging) then
local xO, yO = parent:getOffset()
xO = xO < 0 and math.abs(xO) or -xO
yO = yO < 0 and math.abs(yO) or -yO
local parentX = 1
local parentY = 1
parentX, parentY = parent:getAbsolutePosition()
self:setPosition(x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO)
self:updateDraw()
end
return true
end
end,
mouseHandler = function(self, btn, x, y, ...)
if(base.mouseHandler(self, btn, x, y, ...))then
parent:setImportant(self)
local fx, fy = self:getAbsolutePosition()
local w, h = self:getSize()
for k,v in pairs(dragMap)do
local x1, x2 = v.x1=="width" and w or v.x1, v.x2=="width" and w or v.x2
local y1, y2= v.y1=="height" and h or v.y1, v.y2=="height" and h or v.y2
if(x>=fx+x1-1)and(x<=fx+x2-1)and(y>=fy+y1-1)and(y<=fy+y2-1)then
isDragging = true
dragXOffset = fx - x
dragYOffset = fy - y
return true
end
end
return true
end
end,
mouseUpHandler = function(self, ...)
isDragging = false
return base.mouseUpHandler(self, ...)
end,
setParent = function(self, p, ...)
base.setParent(self, p, ...)
parent = p
return self
end,
}
object.__index = object
return setmetatable(object, base)
end

240
Basalt/objects/Object.lua Normal file
View File

@@ -0,0 +1,240 @@
local basaltEvent = require("basaltEvent")
local utils = require("utils")
local uuid = utils.uuid
local unpack,sub = table.unpack,string.sub
return function(name, basalt)
name = name or uuid()
assert(basalt~=nil, "Unable to find basalt instance! ID: "..name)
-- Base object
local objectType = "Object" -- not changeable
local isEnabled,initialized = true,false
local eventSystem = basaltEvent()
local activeEvents = {}
local parent
local object = {
init = function(self)
if(initialized)then return false end
initialized = true
return true
end,
load = function(self)
end,
getType = function(self)
return objectType
end,
isType = function(self, t)
return objectType==t
end,
getName = function(self)
return name
end,
getParent = function(self)
return parent
end,
setParent = function(self, newParent, noRemove)
if(noRemove)then parent = newParent return self end
if (newParent.getType ~= nil and newParent:isType("Container")) then
self:remove()
newParent:addObject(self)
if (self.show) then
self:show()
end
parent = newParent
end
return self
end,
updateEvents = function(self)
for k,v in pairs(activeEvents)do
parent:removeEvent(k, self)
if(v)then
parent:addEvent(k, self)
end
end
return self
end,
listenEvent = function(self, event, active)
if(parent~=nil)then
if(active)or(active==nil)then
activeEvents[event] = true
parent:addEvent(event, self)
elseif(active==false)then
activeEvents[event] = false
parent:removeEvent(event, self)
end
end
return self
end,
getZIndex = function(self)
return 1
end,
enable = function(self)
isEnabled = true
return self
end,
disable = function(self)
isEnabled = false
return self
end,
isEnabled = function(self)
return isEnabled
end,
remove = function(self)
if (parent ~= nil) then
parent:removeObject(self)
end
self:updateDraw()
return self
end,
getBaseFrame = function(self)
if(parent~=nil)then
return parent:getBaseFrame()
end
return self
end,
onEvent = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("other_event", v)
end
end
return self
end,
getEventSystem = function(self)
return eventSystem
end,
registerEvent = function(self, event, func)
if(parent~=nil)then
parent:addEvent(event, self)
end
return eventSystem:registerEvent(event, func)
end,
removeEvent = function(self, event, index)
if(eventSystem:getEventCount(event)<1)then
if(parent~=nil)then
parent:removeEvent(event, self)
end
end
return eventSystem:removeEvent(event, index)
end,
sendEvent = function(self, event, ...)
return eventSystem:sendEvent(event, self, ...)
end,
onClick = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_click", v)
end
end
return self
end,
onClickUp = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_up", v)
end
end
return self
end,
onRelease = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_release", v)
end
end
return self
end,
onScroll = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_scroll", v)
end
end
return self
end,
onHover = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_hover", v)
end
end
return self
end,
onLeave = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_leave", v)
end
end
return self
end,
onDrag = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_drag", v)
end
end
return self
end,
onKey = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("key", v)
end
end
return self
end,
onChar = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("char", v)
end
end
return self
end,
onKeyUp = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("key_up", v)
end
end
return self
end,
}
object.__index = object
return object
end

View File

@@ -1,28 +1,16 @@
local Object = require("Object")
local log = require("basaltLogs")
return function(name)
return function(name, basalt)
-- Pane
local base = Object(name)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Pane"
base:setSize(25, 10)
local object = {
getType = function(self)
return objectType
end;
setBackground = function(self, col, sym, symC)
base.setBackground(self, col, sym, symC)
return self
end,
init = function(self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("PaneBG")
self.fgColor = self.parent:getTheme("PaneBG")
end
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,19 +1,16 @@
local Object = require("Object")
local tHex = require("tHex")
local process = require("process")
local xmlValue = require("utils").getValueFromXML
local sub = string.sub
return function(name, parent)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Program"
base:setZIndex(5)
local object
local cachedPath
local enviroment = {}
local function createBasaltWindow(x, y, width, height, self)
local function createBasaltWindow(x, y, width, height)
local xCursor, yCursor = 1, 1
local bgColor, fgColor = colors.black, colors.white
local cursorBlink = false
@@ -30,7 +27,7 @@ return function(name, parent)
for i = 0, 15 do
local c = 2 ^ i
tPalette[c] = { parent:getBasaltInstance().getBaseTerm().getPaletteColour(c) }
tPalette[c] = { basalt.getTerm().getPaletteColour(c) }
end
local function createEmptyLines()
@@ -66,67 +63,17 @@ return function(name, parent)
end
local function internalBlit(sText, sTextColor, sBackgroundColor)
-- copy pasti strikes again (cc: window.lua)
local nStart = xCursor
local nEnd = nStart + #sText - 1
if yCursor >= 1 and yCursor <= height then
if nStart <= width and nEnd >= 1 then
-- Modify line
if nStart == 1 and nEnd == width then
cacheT[yCursor] = sText
cacheFG[yCursor] = sTextColor
cacheBG[yCursor] = sBackgroundColor
else
local sClippedText, sClippedTextColor, sClippedBackgroundColor
if nStart < 1 then
local nClipStart = 1 - nStart + 1
local nClipEnd = width - nStart + 1
sClippedText = sub(sText, nClipStart, nClipEnd)
sClippedTextColor = sub(sTextColor, nClipStart, nClipEnd)
sClippedBackgroundColor = sub(sBackgroundColor, nClipStart, nClipEnd)
elseif nEnd > width then
local nClipEnd = width - nStart + 1
sClippedText = sub(sText, 1, nClipEnd)
sClippedTextColor = sub(sTextColor, 1, nClipEnd)
sClippedBackgroundColor = sub(sBackgroundColor, 1, nClipEnd)
else
sClippedText = sText
sClippedTextColor = sTextColor
sClippedBackgroundColor = sBackgroundColor
end
local sOldText = cacheT[yCursor]
local sOldTextColor = cacheFG[yCursor]
local sOldBackgroundColor = cacheBG[yCursor]
local sNewText, sNewTextColor, sNewBackgroundColor
if nStart > 1 then
local nOldEnd = nStart - 1
sNewText = sub(sOldText, 1, nOldEnd) .. sClippedText
sNewTextColor = sub(sOldTextColor, 1, nOldEnd) .. sClippedTextColor
sNewBackgroundColor = sub(sOldBackgroundColor, 1, nOldEnd) .. sClippedBackgroundColor
else
sNewText = sClippedText
sNewTextColor = sClippedTextColor
sNewBackgroundColor = sClippedBackgroundColor
end
if nEnd < width then
local nOldStart = nEnd + 1
sNewText = sNewText .. sub(sOldText, nOldStart, width)
sNewTextColor = sNewTextColor .. sub(sOldTextColor, nOldStart, width)
sNewBackgroundColor = sNewBackgroundColor .. sub(sOldBackgroundColor, nOldStart, width)
end
cacheT[yCursor] = sNewText
cacheFG[yCursor] = sNewTextColor
cacheBG[yCursor] = sNewBackgroundColor
end
object:updateDraw()
end
xCursor = nEnd + 1
if (visible) then
updateCursor()
end
if yCursor < 1 or yCursor > height or xCursor < 1 or xCursor + #sText - 1 > width then
return
end
cacheT[yCursor] = sub(cacheT[yCursor], 1, xCursor - 1) .. sText .. sub(cacheT[yCursor], xCursor + #sText, width)
cacheFG[yCursor] = sub(cacheFG[yCursor], 1, xCursor - 1) .. sTextColor .. sub(cacheFG[yCursor], xCursor + #sText, width)
cacheBG[yCursor] = sub(cacheBG[yCursor], 1, xCursor - 1) .. sBackgroundColor .. sub(cacheBG[yCursor], xCursor + #sText, width)
xCursor = xCursor + #sText
if visible then
updateCursor()
end
object:updateDraw()
end
local function setText(_x, _y, text)
@@ -233,7 +180,7 @@ return function(name, parent)
if (visible) then
updateCursor()
end
end;
end,
getCursorPos = function()
return xCursor, yCursor
@@ -310,57 +257,40 @@ return function(name, parent)
end
end;
writeText = function(_x, _y, text, bgCol, fgCol)
bgCol = bgCol or bgColor
fgCol = fgCol or fgColor
setText(x, _y, text)
setBG(_x, _y, tHex[bgCol]:rep(text:len()))
setFG(_x, _y, tHex[fgCol]:rep(text:len()))
end;
basalt_update = function()
if (parent ~= nil) then
for n = 1, height do
parent:setText(x, y + (n - 1), cacheT[n])
parent:setBG(x, y + (n - 1), cacheBG[n])
parent:setFG(x, y + (n - 1), cacheFG[n])
end
for n = 1, height do
object:addBlit(1, n, cacheT[n], cacheFG[n], cacheBG[n])
end
end;
end,
scroll = function(offset)
if type(offset) ~= "number" then
error("bad argument #1 (expected number, got " .. type(offset) .. ")", 2)
end
assert(type(offset) == "number", "bad argument #1 (expected number, got " .. type(offset) .. ")")
if offset ~= 0 then
local sEmptyText = emptySpaceLine
local sEmptyTextColor = emptyColorLines[fgColor]
local sEmptyBackgroundColor = emptyColorLines[bgColor]
for newY = 1, height do
local y = newY + offset
if y >= 1 and y <= height then
cacheT[newY] = cacheT[y]
cacheBG[newY] = cacheBG[y]
cacheFG[newY] = cacheFG[y]
else
cacheT[newY] = sEmptyText
cacheFG[newY] = sEmptyTextColor
cacheBG[newY] = sEmptyBackgroundColor
end
for newY = 1, height do
local y = newY + offset
if y < 1 or y > height then
cacheT[newY] = emptySpaceLine
cacheFG[newY] = emptyColorLines[fgColor]
cacheBG[newY] = emptyColorLines[bgColor]
else
cacheT[newY] = cacheT[y]
cacheBG[newY] = cacheBG[y]
cacheFG[newY] = cacheFG[y]
end
end
end
if (visible) then
updateCursor()
end
end;
end,
isColor = function()
return parent:getBasaltInstance().getBaseTerm().isColor()
return basalt.getTerm().isColor()
end;
isColour = function()
return parent:getBasaltInstance().getBaseTerm().isColor()
return basalt.getTerm().isColor()
end;
write = function(text)
@@ -416,19 +346,20 @@ return function(name, parent)
return basaltwindow
end
base.width = 30
base.height = 12
local pWindow = createBasaltWindow(1, 1, base.width, base.height)
base:setZIndex(5)
base:setSize(30, 12)
local pWindow = createBasaltWindow(1, 1, 30, 12)
local curProcess
local paused = false
local queuedEvent = {}
local function updateCursor(self)
local parent = self:getParent()
local xCur, yCur = pWindow.getCursorPos()
local obx, oby = self:getAnchorPosition()
local obx, oby = self:getPosition()
local w,h = self:getSize()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
@@ -452,7 +383,7 @@ return function(name, parent)
end
if not (curProcess:isDead()) then
if not (paused) then
local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true))
local absX, absY = self:getAbsolutePosition()
resumeProcess(self, event, p1, x-absX+1, y-absY+1)
updateCursor(self)
end
@@ -480,8 +411,8 @@ return function(name, parent)
show = function(self)
base.show(self)
pWindow.setBackgroundColor(self.bgColor)
pWindow.setTextColor(self.fgColor)
pWindow.setBackgroundColor(self:getBackground())
pWindow.setTextColor(self:getForeground())
pWindow.basalt_setVisible(true)
return self
end;
@@ -494,14 +425,8 @@ return function(name, parent)
setPosition = function(self, x, y, rel)
base.setPosition(self, x, y, rel)
pWindow.basalt_reposition(self:getAnchorPosition())
pWindow.basalt_reposition(self:getPosition())
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("path", data)~=nil)then cachedPath = xmlValue("path", data) end
if(xmlValue("execute", data)~=nil)then if(xmlValue("execute", data))then if(cachedPath~=nil)then self:execute(cachedPath) end end end
end,
getBasaltWindow = function()
@@ -537,37 +462,34 @@ return function(name, parent)
pWindow.setTextColor(colors.white)
pWindow.clear()
pWindow.setCursorPos(1, 1)
pWindow.setBackgroundColor(self.bgColor)
pWindow.setTextColor(self.fgColor)
pWindow.setBackgroundColor(self:getBackground())
pWindow.setTextColor(self:getForeground() or colors.white)
pWindow.basalt_setVisible(true)
resumeProcess(self)
paused = false
if(self.parent~=nil)then
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
self.parent:addEvent("key", self)
self.parent:addEvent("key_up", self)
self.parent:addEvent("char", self)
self.parent:addEvent("other_event", self)
end
self:listenEvent("mouse_click", self)
self:listenEvent("mouse_up", self)
self:listenEvent("mouse_drag", self)
self:listenEvent("mouse_scroll", self)
self:listenEvent("key", self)
self:listenEvent("key_up", self)
self:listenEvent("char", self)
self:listenEvent("other_event", self)
return self
end;
stop = function(self)
stop = function(self)
local parent = self:getParent()
if (curProcess ~= nil) then
if not (curProcess:isDead()) then
resumeProcess(self, "terminate")
if (curProcess:isDead()) then
if (self.parent ~= nil) then
self.parent:setCursor(false)
end
parent:setCursor(false)
end
end
end
self.parent:removeEvents(self)
parent:removeEvents(self)
return self
end;
@@ -588,13 +510,13 @@ return function(name, parent)
return paused
end;
injectEvent = function(self, event, p1, p2, p3, p4, ign)
injectEvent = function(self, event, ign, ...)
if (curProcess ~= nil) then
if not (curProcess:isDead()) then
if (paused == false) or (ign) then
resumeProcess(self, event, p1, p2, p3, p4)
resumeProcess(self, event, ...)
else
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
table.insert(queuedEvent, { event = event, args = {...} })
end
end
end
@@ -610,10 +532,10 @@ return function(name, parent)
return self
end;
injectEvents = function(self, events)
injectEvents = function(self, ...)
if (curProcess ~= nil) then
if not (curProcess:isDead()) then
for _, value in pairs(events) do
for _, value in pairs({...}) do
resumeProcess(self, value.event, table.unpack(value.args))
end
end
@@ -682,12 +604,13 @@ return function(name, parent)
if (curProcess ~= nil) then
if not (curProcess:isDead()) then
if not (paused) then
if (self.parent ~= nil) then
local parent = self:getParent()
if (parent ~= nil) then
local xCur, yCur = pWindow.getCursorPos()
local obx, oby = self:getAnchorPosition()
local obx, oby = self:getPosition()
local w,h = self:getSize()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
end
@@ -699,77 +622,47 @@ return function(name, parent)
base.loseFocusHandler(self)
if (curProcess ~= nil) then
if not (curProcess:isDead()) then
if (self.parent ~= nil) then
self.parent:setCursor(false)
local parent = self:getParent()
if (parent ~= nil) then
parent:setCursor(false)
end
end
end
end,
customEventHandler = function(self, event, ...)
base.customEventHandler(self, event, ...)
if (curProcess == nil) then
return
end
if(event=="basalt_resize")then
local w, h = pWindow.getSize()
local pW, pH = self:getSize()
if(w~=pW)or(h~=pH)then
pWindow.basalt_resize(pW, pH)
if not (curProcess:isDead()) then
resumeProcess(self, "term_resize")
end
end
pWindow.basalt_reposition(self:getAnchorPosition())
end
end,
eventHandler = function(self, event, p1, p2, p3, p4)
base.eventHandler(self, event, p1, p2, p3, p4)
if (curProcess == nil) then
eventHandler = function(self, event, ...)
base.eventHandler(self, event, ...)
if curProcess == nil then
return
end
if not (curProcess:isDead()) then
if not (paused) then
if(event ~= "terminate") then
resumeProcess(self, event, p1, p2, p3, p4)
end
if (self:isFocused()) then
local obx, oby = self:getAnchorPosition()
if not curProcess:isDead() then
if not paused then
resumeProcess(self, event, ...)
if self:isFocused() then
local parent = self:getParent()
local obx, oby = self:getPosition()
local xCur, yCur = pWindow.getCursorPos()
if (self.parent ~= nil) then
local w,h = self:getSize()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
if (event == "terminate") then
resumeProcess(self, event)
self.parent:setCursor(false)
return true
local w,h = self:getSize()
if obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1 then
parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
else
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
table.insert(queuedEvent, { event = event, args = { ... } })
end
end
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local xCur, yCur = pWindow.getCursorPos()
local w,h = self:getSize()
pWindow.basalt_reposition(obx, oby)
pWindow.basalt_update()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
end
base.draw(self)
self:addDraw("program", function()
local parent = self:getParent()
local obx, oby = self:getPosition()
local xCur, yCur = pWindow.getCursorPos()
local w,h = self:getSize()
pWindow.basalt_reposition(obx, oby)
pWindow.basalt_update()
end)
end,
onError = function(self, ...)
@@ -778,9 +671,8 @@ return function(name, parent)
self:registerEvent("program_error", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("other_event", self)
end
local parent = self:getParent()
self:listenEvent("other_event")
return self
end,
@@ -790,19 +682,13 @@ return function(name, parent)
self:registerEvent("program_done", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("other_event", self)
end
local parent = self:getParent()
self:listenEvent("other_event")
return self
end,
init = function(self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ProgramBG")
end
end,
}
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -1,52 +1,29 @@
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
return function(name)
-- Checkbox
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Progressbar"
local progress = 0
base:setZIndex(5)
base:setValue(false)
base.width = 25
base.height = 1
base:setSize(25, 3)
local activeBarColor
local activeBarColor = colors.black
local activeBarSymbol = ""
local activeBarSymbolCol = colors.white
local bgBarSymbol = ""
local direction = 0
local object = {
init = function(self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ProgressbarBG")
self.fgColor = self.parent:getTheme("ProgressbarText")
activeBarColor = self.parent:getTheme("ProgressbarActiveBG")
end
end,
getType = function(self)
return objectType
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("direction", data)~=nil)then direction = xmlValue("direction", data) end
if(xmlValue("progressColor", data)~=nil)then activeBarColor = colors[xmlValue("progressColor", data)] end
if(xmlValue("progressSymbol", data)~=nil)then activeBarSymbol = xmlValue("progressSymbol", data) end
if(xmlValue("backgroundSymbol", data)~=nil)then bgBarSymbol = xmlValue("backgroundSymbol", data) end
if(xmlValue("progressSymbolColor", data)~=nil)then activeBarSymbolCol = colors[xmlValue("progressSymbolColor", data)] end
if(xmlValue("onDone", data)~=nil)then self:generateXMLEventFunction(self.onProgressDone, xmlValue("onDone", data)) end
return self
end,
setDirection = function(self, dir)
direction = dir
self:updateDraw()
return self
end;
end,
setProgressBar = function(self, color, symbol, symbolcolor)
activeBarColor = color or activeBarColor
@@ -54,13 +31,17 @@ return function(name)
activeBarSymbolCol = symbolcolor or activeBarSymbolCol
self:updateDraw()
return self
end;
end,
getProgressBar = function(self)
return activeBarColor, activeBarSymbol, activeBarSymbolCol
end,
setBackgroundSymbol = function(self, symbol)
bgBarSymbol = symbol:sub(1, 1)
self:updateDraw()
return self
end;
end,
setProgress = function(self, value)
if (value >= 0) and (value <= 100) and (progress ~= value) then
@@ -72,51 +53,52 @@ return function(name)
end
self:updateDraw()
return self
end;
end,
getProgress = function(self)
return progress
end;
end,
onProgressDone = function(self, f)
self:registerEvent("progress_done", f)
return self
end;
end,
progressDoneHandler = function(self)
self:sendEvent("progress_done", self)
end;
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
if(bgBarSymbol~="")then self.parent:drawTextBox(obx, oby, w, h, bgBarSymbol) end
if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) end
if (direction == 1) then
self.parent:drawBackgroundBox(obx, oby, w, h / 100 * progress, activeBarColor)
self.parent:drawForegroundBox(obx, oby, w, h / 100 * progress, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby, w, h / 100 * progress, activeBarSymbol)
elseif (direction == 2) then
self.parent:drawBackgroundBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarColor)
self.parent:drawForegroundBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbol)
elseif (direction == 3) then
self.parent:drawBackgroundBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarColor)
self.parent:drawForegroundBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarSymbolCol)
self.parent:drawTextBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarSymbol)
else
self.parent:drawBackgroundBox(obx, oby, w / 100 * progress, h, activeBarColor)
self.parent:drawForegroundBox(obx, oby, w / 100 * progress, h, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby, w / 100 * progress, h, activeBarSymbol)
end
base.draw(self)
self:addDraw("progressbar", function()
local obx, oby = self:getPosition()
local w,h = self:getSize()
local bgCol,fgCol = self:getBackground(), self:getForeground()
if(bgCol~=false)then self:addBackgroundBox(obx, oby, w, h, bgCol) end
if(bgBarSymbol~="")then self:addTextBox(obx, oby, w, h, bgBarSymbol) end
if(fgCol~=false)then self:addForegroundBox(obx, oby, w, h, fgCol) end
if (direction == 1) then
self:addBackgroundBox(obx, oby, w, h / 100 * progress, activeBarColor)
self:addForegroundBox(obx, oby, w, h / 100 * progress, activeBarSymbolCol)
self:addTextBox(obx, oby, w, h / 100 * progress, activeBarSymbol)
elseif (direction == 2) then
self:addBackgroundBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarColor)
self:addForegroundBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbolCol)
self:addTextBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbol)
elseif (direction == 3) then
self:addBackgroundBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarColor)
self:addForegroundBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarSymbolCol)
self:addTextBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarSymbol)
else
self:addBackgroundBox(obx, oby, w / 100 * progress, h, activeBarColor)
self:addForegroundBox(obx, oby, w / 100 * progress, h, activeBarSymbolCol)
self:addTextBox(obx, oby, w / 100 * progress, h, activeBarSymbol)
end
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,20 +1,18 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("List")(name, basalt)
local objectType = "Radio"
base.width = 8
base:setSize(1, 1)
base:setZIndex(5)
local list = {}
local itemSelectedBG
local itemSelectedFG
local boxSelectedBG
local boxSelectedFG
local boxNotSelectedBG
local boxNotSelectedFG
local boxSelectedBG = colors.black
local boxSelectedFG = colors.green
local boxNotSelectedBG = colors.black
local boxNotSelectedFG = colors.red
local selectionColorActive = true
local symbol = "\7"
local align = "left"
@@ -22,148 +20,87 @@ return function(name)
local object = {
getType = function(self)
return objectType
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
if(xmlValue("boxBG", data)~=nil)then boxSelectedBG = colors[xmlValue("boxBG", data)] end
if(xmlValue("inactiveBoxBG", data)~=nil)then boxNotSelectedBG = colors[xmlValue("inactiveBoxBG", data)] end
if(xmlValue("inactiveBoxFG", data)~=nil)then boxNotSelectedFG = colors[xmlValue("inactiveBoxFG", data)] end
if(xmlValue("boxFG", data)~=nil)then boxSelectedFG = colors[xmlValue("boxFG", data)] end
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data) end
if(data["item"]~=nil)then
local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
self:addItem(xmlValue("text", v), xmlValue("x", v), xmlValue("y", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
end
end
return self
end,
addItem = function(self, text, x, y, bgCol, fgCol, ...)
table.insert(list, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
if (#list == 1) then
self:setValue(list[1])
end
self:updateDraw()
return self
end;
getAll = function(self)
return list
end;
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
getItem = function(self, index)
return list[index]
end;
getItemIndex = function(self)
local selected = self:getValue()
for key, value in pairs(list) do
if (value == selected) then
return key
end
end
end;
clear = function(self)
list = {}
self:setValue({}, false)
self:updateDraw()
return self
end;
getItemCount = function(self)
return #list
end;
editItem = function(self, index, text, x, y, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {}, false)
self:updateDraw()
return self
end;
setActiveSymbol = function(self, sym)
symbol = sym:sub(1,1)
self:updateDraw()
base.addItem(self, text, bgCol, fgCol, ...)
table.insert(list, { x = x or 1, y = y or #list * 2 })
return self
end,
setSelectedItem = function(self, bgCol, fgCol, boxBG, boxFG, active)
itemSelectedBG = bgCol or itemSelectedBG
itemSelectedFG = fgCol or itemSelectedFG
boxSelectedBG = boxBG or boxSelectedBG
boxSelectedFG = boxFG or boxSelectedFG
selectionColorActive = active~=nil and active or true
self:updateDraw()
removeItem = function(self, index)
base.removeItem(self, index)
table.remove(list, index)
return self
end;
end,
mouseHandler = function(self, button, x, y)
clear = function(self)
base.clear(self)
list = {}
return self
end,
editItem = function(self, index, text, x, y, bgCol, fgCol, ...)
base.editItem(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { x = x or 1, y = y or 1 })
return self
end,
setBoxSelectionColor = function(self, bg, fg)
boxSelectedBG = bg
boxSelectedFG = fg
return self
end,
getBoxSelectionColor = function(self)
return boxSelectedBG, boxSelectedFG
end,
setBoxDefaultColor = function(self, bg, fg)
boxNotSelectedBG = bg
boxNotSelectedFG = fg
return self
end,
getBoxDefaultColor = function(self)
return boxNotSelectedBG, boxNotSelectedFG
end,
mouseHandler = function(self, button, x, y, ...)
if (#list > 0) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
for _, value in pairs(list) do
if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 1 >= x) and (oby + value.y - 1 == y) then
local obx, oby = self:getAbsolutePosition()
local baseList = self:getAll()
for k, value in pairs(baseList) do
if (obx + list[k].x - 1 <= x) and (obx + list[k].x - 1 + value.text:len() + 1 >= x) and (oby + list[k].y - 1 == y) then
self:setValue(value)
local val = self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", button, x, y)
if(val==false)then return val end
if(self.parent~=nil)then
self.parent:setFocusedObject(self)
end
local val = self:sendEvent("mouse_click", self, "mouse_click", button, x, y, ...)
self:updateDraw()
if(val==false)then return val end
return true
end
end
end
return false
end;
end,
draw = function(self)
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
for _, value in pairs(list) do
self:addDraw("radio", function()
local itemSelectedBG, itemSelectedFG = self:getSelectionColor()
local baseList = self:getAll()
for k, value in pairs(baseList) do
if (value == self:getValue()) then
if (align == "left") then
self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG)
self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG)
end
self:addBlit(list[k].x, list[k].y, symbol, tHex[boxSelectedFG], tHex[boxSelectedBG])
self:addBlit(list[k].x + 2, list[k].y, value.text, tHex[itemSelectedFG]:rep(#value.text), tHex[itemSelectedBG]:rep(#value.text))
else
self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, boxNotSelectedBG or self.bgColor)
self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol)
self:addBackgroundBox(list[k].x, list[k].y, 1, 1, boxNotSelectedBG or colors.black)
self:addBlit(list[k].x + 2, list[k].y, value.text, tHex[value.fgCol]:rep(#value.text), tHex[value.bgCol]:rep(#value.text))
end
end
return true
end
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("MenubarBG")
self.fgColor = self.parent:getTheme("MenubarFG")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
boxSelectedBG = self.parent:getTheme("MenubarBG")
boxSelectedFG = self.parent:getTheme("MenubarText")
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -0,0 +1,85 @@
local max,min,sub,rep = math.max,math.min,string.sub,string.rep
return function(name, basalt)
local base = basalt.getObject("Frame")(name, basalt)
local objectType = "ScrollableFrame"
local parent
local direction = 0
local function getHorizontalScrollAmount(self)
local amount = 0
local objects = self:getObjects()
for _, b in pairs(objects) do
if(b.element.getWidth~=nil)and(b.element.getX~=nil)then
local h, y = b.element:getWidth(), b.element:getX()
local width = self:getWidth()
if (h + y - width >= amount) then
amount = max(h + y - width, 0)
end
end
end
return amount
end
local function getVerticalScrollAmount(self)
local amount = 0
local objects = self:getObjects()
for _, b in pairs(objects) do
if(b.element.getHeight~=nil)and(b.element.getY~=nil)then
local h, y = b.element:getHeight(), b.element:getY()
local height = self:getHeight()
if (h + y - height >= amount) then
amount = max(h + y - height, 0)
end
end
end
return amount
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,
getBase = function(self)
return base
end,
load = function(self)
base.load(self)
self:listenEvent("mouse_scroll")
end,
setParent = function(self, p, ...)
base.setParent(self, p, ...)
parent = p
return self
end,
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
local xO, yO = self:getOffset()
if(direction==1)then
self:setOffset(min(getHorizontalScrollAmount(self), max(0, xO + dir)), yO)
elseif(direction==0)then
self:setOffset(xO, min(getVerticalScrollAmount(self), max(0, yO + dir)))
end
self:updateDraw()
return true
end
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,42 +1,39 @@
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
local tHex = require("tHex")
return function(name)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
local objectType = "Scrollbar"
base.width = 1
base.height = 8
base:setValue(1)
base:setZIndex(2)
base:setSize(1, 8)
base:setBackground(colors.lightGray, "\127", colors.gray)
local barType = "vertical"
local symbol = " "
local symbolColor
local bgSymbol = "\127"
local maxValue = base.height
local symbolBG = colors.yellow
local symbolFG = colors.black
local scrollAmount = 3
local index = 1
local symbolSize = 1
local symbolAutoSize = true
local function updateSymbolSize()
local w,h = base:getSize()
if(symbolAutoSize)then
symbolSize = math.max((barType == "vertical" and h or w-(#symbol)) - (scrollAmount-1), 1)
end
end
local function mouseEvent(self, button, x, y)
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local obx, oby = self:getPosition()
local w,h = self:getSize()
if (barType == "horizontal") then
for _index = 0, w do
if (obx + _index == x) and (oby <= y) and (oby + h > y) then
index = math.min(_index + 1, w - (symbolSize - 1))
self:setValue(maxValue / w * (index))
self:updateDraw()
end
end
end
if (barType == "vertical") then
for _index = 0, h do
if (oby + _index == y) and (obx <= x) and (obx + w > x) then
index = math.min(_index + 1, h - (symbolSize - 1))
self:setValue(maxValue / h * (index))
self:updateDraw()
end
updateSymbolSize()
local size = barType == "vertical" and h or w
for i = 0, size do
if ((barType == "vertical" and oby + i == y) or (barType == "horizontal" and obx + i == x)) and (obx <= x) and (obx + w > x) and (oby <= y) and (oby + h > y) then
index = math.min(i + 1, size - (#symbol + symbolSize - 2))
self:scrollbarMoveHandler()
self:updateDraw()
end
end
end
@@ -44,23 +41,24 @@ return function(name)
local object = {
getType = function(self)
return objectType
end;
end,
setSymbol = function(self, _symbol)
symbol = _symbol:sub(1, 1)
load = function(self)
base.load(self)
local parent = self:getParent()
self:listenEvent("mouse_click")
self:listenEvent("mouse_up")
self:listenEvent("mouse_scroll")
self:listenEvent("mouse_drag")
end,
setSymbol = function(self, _symbol, bg, fg)
symbol = _symbol:sub(1,1)
symbolBG = bg or symbolBG
symbolFG = fg or symbolFG
updateSymbolSize()
self:updateDraw()
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("maxValue", data)~=nil)then maxValue = xmlValue("maxValue", data) end
if(xmlValue("backgroundSymbol", data)~=nil)then bgSymbol = xmlValue("backgroundSymbol", data):sub(1,1) end
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data):sub(1,1) end
if(xmlValue("barType", data)~=nil)then barType = xmlValue("barType", data):lower() end
if(xmlValue("symbolSize", data)~=nil)then self:setSymbolSize(xmlValue("symbolSize", data)) end
if(xmlValue("symbolColor", data)~=nil)then symbolColor = colors[xmlValue("symbolColor", data)] end
if(xmlValue("index", data)~=nil)then self:setIndex(xmlValue("index", data)) end
end,
setIndex = function(self, _index)
@@ -70,50 +68,37 @@ return function(name)
end
local w,h = self:getSize()
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
updateSymbolSize()
self:updateDraw()
return self
end,
setScrollAmount = function(self, amount)
scrollAmount = amount
updateSymbolSize()
self:updateDraw()
return self
end,
getIndex = function(self)
return index
local w,h = self:getSize()
return scrollAmount > (barType=="vertical" and h or w) and math.floor(scrollAmount/(barType=="vertical" and h or w) * index) or index
end,
setSymbolSize = function(self, size)
symbolSize = tonumber(size) or 1
local w,h = self:getSize()
if (barType == "vertical") then
self:setValue(index - 1 * (maxValue / (h - (symbolSize - 1))) - (maxValue / (h - (symbolSize - 1))))
elseif (barType == "horizontal") then
self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1))))
end
symbolAutoSize = size~=false and false or true
updateSymbolSize()
self:updateDraw()
return self
end;
setMaxValue = function(self, val)
maxValue = val
self:updateDraw()
return self
end;
setBackgroundSymbol = function(self, _bgSymbol)
bgSymbol = string.sub(_bgSymbol, 1, 1)
self:updateDraw()
return self
end;
setSymbolColor = function(self, col)
symbolColor = col
self:updateDraw()
return self
end;
end,
setBarType = function(self, _typ)
barType = _typ:lower()
updateSymbolSize()
self:updateDraw()
return self
end;
end,
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
@@ -131,58 +116,69 @@ return function(name)
return false
end,
setSize = function(self, ...)
base.setSize(self, ...)
updateSymbolSize()
return self
end,
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
local w,h = self:getSize()
updateSymbolSize()
index = index + dir
if (index < 1) then
index = 1
end
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
index = math.min(index, (barType == "vertical" and h or w) - (barType == "vertical" and symbolSize - 1 or #symbol+symbolSize-2))
self:scrollbarMoveHandler()
self:updateDraw()
end
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (barType == "horizontal") then
self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor)
self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor)
self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(w - (index + symbolSize - 1)), self.bgColor, self.fgColor)
end
onChange = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("scrollbar_moved", v)
end
end
return self
end,
if (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor)
end
else
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor)
end
scrollbarMoveHandler = function(self)
self:sendEvent("scrollbar_moved", self, self:getIndex())
end,
customEventHandler = function(self, event, ...)
base.customEventHandler(self, event, ...)
if(event=="basalt_FrameResize")then
updateSymbolSize()
end
end,
draw = function(self)
base.draw(self)
self:addDraw("scrollbar", function()
local parent = self:getParent()
local w,h = self:getSize()
local bgCol,fgCol = self:getBackground(), self:getForeground()
if (barType == "horizontal") then
for n = 0, h - 1 do
self:addBlit(index, 1 + n, symbol:rep(symbolSize), tHex[symbolFG]:rep(#symbol*symbolSize), tHex[symbolBG]:rep(#symbol*symbolSize))
end
elseif (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self:blit(1, index + curIndexOffset, symbol:rep(math.max(#symbol, w)), tHex[symbolFG]:rep(math.max(#symbol, w)), tHex[symbolBG]:rep(math.max(#symbol, w)))
end
end
end
end
end
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ScrollbarBG")
self.fgColor = self.parent:getTheme("ScrollbarText")
symbolColor = self.parent:getTheme("ScrollbarSymbolColor")
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,66 +1,49 @@
local Object = require("Object")
local log = require("basaltLogs")
local xmlValue = require("utils").getValueFromXML
local tHex = require("tHex")
return function(name)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Slider"
base.width = 8
base.height = 1
base:setSize(12, 1)
base:setValue(1)
base:setBackground(false, "\140", colors.black)
local barType = "horizontal"
local symbol = " "
local symbolColor
local bgSymbol = "\140"
local maxValue = base.width
local symbolFG = colors.black
local symbolBG = colors.gray
local maxValue = 12
local index = 1
local symbolSize = 1
local function mouseEvent(self, button, x, y)
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local w,h = self:getSize()
if (barType == "horizontal") then
for _index = 0, w do
if (obx + _index == x) and (oby <= y) and (oby + h > y) then
index = math.min(_index + 1, w - (symbolSize - 1))
self:setValue(maxValue / w * (index))
self:updateDraw()
end
end
end
if (barType == "vertical") then
for _index = 0, h do
if (oby + _index == y) and (obx <= x) and (obx + w > x) then
index = math.min(_index + 1, h - (symbolSize - 1))
self:setValue(maxValue / h * (index))
self:updateDraw()
end
end
local obx, oby = self:getPosition()
local w,h = self:getSize()
local size = barType == "vertical" and h or w
for i = 0, size do
if ((barType == "vertical" and oby + i == y) or (barType == "horizontal" and obx + i == x)) and (obx <= x) and (obx + w > x) and (oby <= y) and (oby + h > y) then
index = math.min(i + 1, size - (#symbol + symbolSize - 2))
self:setValue(maxValue / size * index)
self:updateDraw()
end
end
end
local object = {
getType = function(self)
return objectType
end;
end,
load = function(self)
self:listenEvent("mouse_click")
self:listenEvent("mouse_drag")
self:listenEvent("mouse_scroll")
end,
setSymbol = function(self, _symbol)
symbol = _symbol:sub(1, 1)
self:updateDraw()
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("maxValue", data)~=nil)then maxValue = xmlValue("maxValue", data) end
if(xmlValue("backgroundSymbol", data)~=nil)then bgSymbol = xmlValue("backgroundSymbol", data):sub(1,1) end
if(xmlValue("barType", data)~=nil)then barType = xmlValue("barType", data):lower() end
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data):sub(1,1) end
if(xmlValue("symbolSize", data)~=nil)then self:setSymbolSize(xmlValue("symbolSize", data)) end
if(xmlValue("symbolColor", data)~=nil)then symbolColor = colors[xmlValue("symbolColor", data)] end
if(xmlValue("index", data)~=nil)then self:setIndex(xmlValue("index", data)) end
end,
setIndex = function(self, _index)
@@ -79,39 +62,22 @@ return function(name)
return index
end,
setSymbolSize = function(self, size)
symbolSize = tonumber(size) or 1
if (barType == "vertical") then
self:setValue(index - 1 * (maxValue / (h - (symbolSize - 1))) - (maxValue / (h - (symbolSize - 1))))
elseif (barType == "horizontal") then
self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1))))
end
self:updateDraw()
return self
end;
setMaxValue = function(self, val)
maxValue = val
return self
end;
setBackgroundSymbol = function(self, _bgSymbol)
bgSymbol = string.sub(_bgSymbol, 1, 1)
self:updateDraw()
return self
end;
end,
setSymbolColor = function(self, col)
symbolColor = col
self:updateDraw()
return self
end;
end,
setBarType = function(self, _typ)
barType = _typ:lower()
self:updateDraw()
return self
end;
end,
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
@@ -145,44 +111,33 @@ return function(name)
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (barType == "horizontal") then
self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor)
self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor)
self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(w - (index + symbolSize - 1)), self.bgColor, self.fgColor)
end
base.draw(self)
self:addDraw("slider", function()
local w,h = self:getSize()
local bgCol,fgCol = self:getBackground(), self:getForeground()
if (barType == "horizontal") then
self:addText(index, oby, symbol:rep(symbolSize))
if(symbolBG~=false)then self:addBG(index, 1, tHex[symbolBG]:rep(#symbol*symbolSize)) end
if(symbolFG~=false)then self:addFG(index, 1, tHex[symbolFG]:rep(#symbol*symbolSize)) end
end
if (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor)
end
else
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor)
end
if (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self:addBlit(1, 1+n+curIndexOffset, symbol, tHex[symbolColor], tHex[symbolColor])
end
else
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
self:addBlit(1, 1+n, bgSymbol, tHex[fgCol], tHex[bgCol])
end
end
end
end
end
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("SliderBG")
self.fgColor = self.parent:getTheme("SliderText")
symbolColor = self.parent:getTheme("SliderSymbolColor")
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,14 +1,8 @@
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
return function(name)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Switch"
base.width = 2
base.height = 1
base.bgColor = colors.lightGray
base.fgColor = colors.gray
base:setSize(4, 1)
base:setValue(false)
base:setZIndex(5)
@@ -19,71 +13,53 @@ return function(name)
local object = {
getType = function(self)
return objectType
end;
setSymbolColor = function(self, symbolColor)
bgSymbol = symbolColor
self:updateDraw()
return self
end;
setActiveBackground = function(self, bgcol)
activeBG = bgcol
self:updateDraw()
return self
end;
setInactiveBackground = function(self, bgcol)
inactiveBG = bgcol
self:updateDraw()
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("inactiveBG", data)~=nil)then inactiveBG = colors[xmlValue("inactiveBG", data)] end
if(xmlValue("activeBG", data)~=nil)then activeBG = colors[xmlValue("activeBG", data)] end
if(xmlValue("symbolColor", data)~=nil)then bgSymbol = colors[xmlValue("symbolColor", data)] end
end,
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
setSymbol = function(self, col)
bgSymbol = col
return self
end,
setActiveBackground = function(self, col)
activeBG = col
return self
end,
setInactiveBackground = function(self, col)
inactiveBG = col
return self
end,
load = function(self)
self:listenEvent("mouse_click")
end,
mouseHandler = function(self, ...)
if (base.mouseHandler(self, ...)) then
self:setValue(not self:getValue())
self:updateDraw()
return true
end
end;
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
if(self:getValue())then
self.parent:drawBackgroundBox(obx, oby, 1, h, activeBG)
self.parent:drawBackgroundBox(obx+1, oby, 1, h, bgSymbol)
else
self.parent:drawBackgroundBox(obx, oby, 1, h, bgSymbol)
self.parent:drawBackgroundBox(obx+1, oby, 1, h, inactiveBG)
end
end
end
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("SwitchBG")
self.fgColor = self.parent:getTheme("SwitchText")
bgSymbol = self.parent:getTheme("SwitchBGSymbol")
inactiveBG = self.parent:getTheme("SwitchInactive")
activeBG = self.parent:getTheme("SwitchActive")
end
draw = function(self)
base.draw(self)
self:addDraw("switch", function()
local parent = self:getParent()
local bgCol,fgCol = self:getBackground(), self:getForeground()
local w,h = self:getSize()
if(self:getValue())then
self:addBackgroundBox(1, 1, w, h, activeBG)
self:addBackgroundBox(w, 1, 1, h, bgSymbol)
else
self:addBackgroundBox(1, 1, w, h, inactiveBG)
self:addBackgroundBox(1, 1, 1, h, bgSymbol)
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -1,12 +1,9 @@
local Object = require("Object")
local tHex = require("tHex")
local xmlValue = require("utils").getValueFromXML
local log = require("basaltLogs")
local rep,find,gmatch,sub,len = string.rep,string.find,string.gmatch,string.sub,string.len
return function(name)
local base = Object(name)
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Textfield"
local hIndex, wIndex, textX, textY = 1, 1, 1, 1
@@ -20,8 +17,7 @@ return function(name)
local selectionBG,selectionFG = colors.lightBlue,colors.black
base.width = 30
base.height = 12
base:setSize(30, 12)
base:setZIndex(5)
local function isSelected()
@@ -32,57 +28,56 @@ return function(name)
end
local function getSelectionCoordinates()
local sx,ex,sy,ey
if(isSelected())then
if(startSelX>endSelX)then
sx,ex = endSelX,startSelX
else
sx,ex = startSelX,endSelX
end
if(startSelY>endSelY)then
sy,ey = endSelY,startSelY
else
sy,ey = startSelY,endSelY
local sx, ex, sy, ey = startSelX, endSelX, startSelY, endSelY
if isSelected() then
if startSelX < endSelX and startSelY <= endSelY then
sx = startSelX
ex = endSelX
if startSelY < endSelY then
sy = startSelY
ey = endSelY
else
sy = endSelY
ey = startSelY
end
elseif startSelX > endSelX and startSelY >= endSelY then
sx = endSelX
ex = startSelX
if startSelY > endSelY then
sy = endSelY
ey = startSelY
else
sy = startSelY
ey = endSelY
end
elseif startSelY > endSelY then
sx = endSelX
ex = startSelX
sy = endSelY
ey = startSelY
end
return sx, ex, sy, ey
end
return sx,ex,sy,ey
end
local function getSelection()
end
local function removeSelection(self)
local sx,ex,sy,ey = getSelectionCoordinates(self)
for n=ey,sy,-1 do
if(n==sy)or(n==ey)then
local l = lines[n]
local b = bgLines[n]
local f = fgLines[n]
if(n==sy)and(n==ey)then
l = l:sub(1,sx-1)..l:sub(ex+1,l:len())
b = b:sub(1,sx-1)..b:sub(ex+1,b:len())
f = f:sub(1,sx-1)..f:sub(ex+1,f:len())
elseif(n==sx)then
l = l:sub(1, sx)
b = b:sub(1, sx)
f = f:sub(1, sx)
elseif(n==sy)then
l = l:sub(ex, l:len())
b = b:sub(ex, b:len())
f = f:sub(ex, f:len())
end
lines[n] = l
bgLines[n] = b
fgLines[n] = f
else
table.remove(lines, n)
table.remove(bgLines, n)
table.remove(fgLines, n)
local sx, ex, sy, ey = getSelectionCoordinates(self)
local startLine = lines[sy]
local endLine = lines[ey]
lines[sy] = startLine:sub(1, sx - 1) .. endLine:sub(ex + 1, endLine:len())
bgLines[sy] = bgLines[sy]:sub(1, sx - 1) .. bgLines[ey]:sub(ex + 1, bgLines[ey]:len())
fgLines[sy] = fgLines[sy]:sub(1, sx - 1) .. fgLines[ey]:sub(ex + 1, fgLines[ey]:len())
for i = ey, sy + 1, -1 do
if i ~= sy then
table.remove(lines, i)
table.remove(bgLines, i)
table.remove(fgLines, i)
end
end
textX,textY = startSelX,startSelY
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
textX, textY = sx, sy
startSelX, endSelX, startSelY, endSelY = nil, nil, nil, nil
return self
end
@@ -105,8 +100,8 @@ return function(name)
local function updateColors(self, l)
l = l or textY
local fgLine = tHex[self.fgColor]:rep(fgLines[l]:len())
local bgLine = tHex[self.bgColor]:rep(bgLines[l]:len())
local fgLine = tHex[self:getForeground()]:rep(fgLines[l]:len())
local bgLine = tHex[self:getBackground()]:rep(bgLines[l]:len())
for k,v in pairs(rules)do
local pos = stringGetPositions(lines[l], v[1])
if(#pos>0)then
@@ -160,60 +155,30 @@ return function(name)
return self
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(data["lines"]~=nil)then
local l = data["lines"]["line"]
if(l.properties~=nil)then l = {l} end
for k,v in pairs(l)do
self:addLine(v:value())
end
end
if(data["keywords"]~=nil)then
for k,v in pairs(data["keywords"])do
if(colors[k]~=nil)then
local entry = v
if(entry.properties~=nil)then entry = {entry} end
local tab = {}
for a,b in pairs(entry)do
local keywordList = b["keyword"]
if(b["keyword"].properties~=nil)then keywordList = {b["keyword"]} end
for c,d in pairs(keywordList)do
table.insert(tab, d:value())
end
end
self:addKeywords(colors[k], tab)
end
end
end
if(data["rules"]~=nil)then
if(data["rules"]["rule"]~=nil)then
local tab = data["rules"]["rule"]
if(data["rules"]["rule"].properties~=nil)then tab = {data["rules"]["rule"]} end
for k,v in pairs(tab)do
setSelection = function(self, fg, bg)
selectionFG = fg or selectionFG
selectionBG = bg or selectionBG
return self
end,
if(xmlValue("pattern", v)~=nil)then
self:addRule(xmlValue("pattern", v), colors[xmlValue("fg", v)], colors[xmlValue("bg", v)])
end
end
end
end
getSelection = function(self)
return selectionFG, selectionBG
end,
getLines = function(self)
return lines
end;
end,
getLine = function(self, index)
return lines[index]
end;
end,
editLine = function(self, index, text)
lines[index] = text or lines[index]
updateColors(self, index)
self:updateDraw()
return self
end;
end,
clear = function(self)
lines = {""}
@@ -227,21 +192,23 @@ return function(name)
addLine = function(self, text, index)
if(text~=nil)then
local bgColor = self:getBackground()
local fgColor = self:getForeground()
if(#lines==1)and(lines[1]=="")then
lines[1] = text
bgLines[1] = tHex[self.bgColor]:rep(text:len())
fgLines[1] = tHex[self.fgColor]:rep(text:len())
bgLines[1] = tHex[bgColor]:rep(text:len())
fgLines[1] = tHex[fgColor]:rep(text:len())
updateColors(self, 1)
return self
end
if (index ~= nil) then
table.insert(lines, index, text)
table.insert(bgLines, index, tHex[self.bgColor]:rep(text:len()))
table.insert(fgLines, index, tHex[self.fgColor]:rep(text:len()))
table.insert(bgLines, index, tHex[bgColor]:rep(text:len()))
table.insert(fgLines, index, tHex[fgColor]:rep(text:len()))
else
table.insert(lines, text)
table.insert(bgLines, tHex[self.bgColor]:rep(text:len()))
table.insert(fgLines, tHex[self.fgColor]:rep(text:len()))
table.insert(bgLines, tHex[bgColor]:rep(text:len()))
table.insert(fgLines, tHex[fgColor]:rep(text:len()))
end
end
updateColors(self, index or #lines)
@@ -285,13 +252,13 @@ return function(name)
end
self:updateDraw()
return self
end;
end,
setKeywords = function(self, color, tab)
keyWords[color] = tab
self:updateDraw()
return self
end;
end,
removeLine = function(self, index)
if(#lines>1)then
@@ -305,83 +272,91 @@ return function(name)
end
self:updateDraw()
return self
end;
end,
getTextCursor = function(self)
return textX, textY
end;
end,
getOffset = function(self)
return wIndex, hIndex
end,
setOffset = function(self, xOff, yOff)
wIndex = xOff or wIndex
hIndex = yOff or hIndex
self:updateDraw()
return self
end,
getFocusHandler = function(self)
base.getFocusHandler(self)
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self.fgColor)
end
end
end;
local obx, oby = self:getPosition()
self:getParent():setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self:getForeground())
end,
loseFocusHandler = function(self)
base.loseFocusHandler(self)
if (self.parent ~= nil) then
self.parent:setCursor(false)
end
end;
self:getParent():setCursor(false)
end,
keyHandler = function(self, key)
if (base.keyHandler(self, event, key)) then
local obx, oby = self:getAnchorPosition()
local parent = self:getParent()
local obx, oby = self:getPosition()
local w,h = self:getSize()
if (key == keys.backspace) then
-- on backspace
if (lines[textY] == "") then
if (textY > 1) then
table.remove(lines, textY)
table.remove(fgLines, textY)
table.remove(bgLines, textY)
textX = lines[textY - 1]:len() + 1
wIndex = textX - w + 1
if (wIndex < 1) then
wIndex = 1
end
textY = textY - 1
end
elseif (textX <= 1) then
if (textY > 1) then
textX = lines[textY - 1]:len() + 1
wIndex = textX - w + 1
if (wIndex < 1) then
wIndex = 1
end
lines[textY - 1] = lines[textY - 1] .. lines[textY]
fgLines[textY - 1] = fgLines[textY - 1] .. fgLines[textY]
bgLines[textY - 1] = bgLines[textY - 1] .. bgLines[textY]
table.remove(lines, textY)
table.remove(fgLines, textY)
table.remove(bgLines, textY)
textY = textY - 1
end
if(isSelected())then
removeSelection(self)
else
lines[textY] = lines[textY]:sub(1, textX - 2) .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 2) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 2) .. bgLines[textY]:sub(textX, bgLines[textY]:len())
if (textX > 1) then
textX = textX - 1
end
if (wIndex > 1) then
if (textX < wIndex) then
wIndex = wIndex - 1
if (lines[textY] == "") then
if (textY > 1) then
table.remove(lines, textY)
table.remove(fgLines, textY)
table.remove(bgLines, textY)
textX = lines[textY - 1]:len() + 1
wIndex = textX - w + 1
if (wIndex < 1) then
wIndex = 1
end
textY = textY - 1
end
elseif (textX <= 1) then
if (textY > 1) then
textX = lines[textY - 1]:len() + 1
wIndex = textX - w + 1
if (wIndex < 1) then
wIndex = 1
end
lines[textY - 1] = lines[textY - 1] .. lines[textY]
fgLines[textY - 1] = fgLines[textY - 1] .. fgLines[textY]
bgLines[textY - 1] = bgLines[textY - 1] .. bgLines[textY]
table.remove(lines, textY)
table.remove(fgLines, textY)
table.remove(bgLines, textY)
textY = textY - 1
end
else
lines[textY] = lines[textY]:sub(1, textX - 2) .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 2) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 2) .. bgLines[textY]:sub(textX, bgLines[textY]:len())
if (textX > 1) then
textX = textX - 1
end
if (wIndex > 1) then
if (textX < wIndex) then
wIndex = wIndex - 1
end
end
end
end
if (textY < hIndex) then
hIndex = hIndex - 1
if (textY < hIndex) then
hIndex = hIndex - 1
end
end
updateColors(self)
self:setValue("")
end
if (key == keys.delete) then
elseif (key == keys.delete) then
-- on delete
if(isSelected())then
removeSelection(self)
@@ -400,9 +375,10 @@ return function(name)
end
end
updateColors(self)
end
if (key == keys.enter) then
elseif (key == keys.enter) then
if(isSelected())then
removeSelection(self)
end
-- on enter
table.insert(lines, textY + 1, lines[textY]:sub(textX, lines[textY]:len()))
table.insert(fgLines, textY + 1, fgLines[textY]:sub(textX, fgLines[textY]:len()))
@@ -417,9 +393,8 @@ return function(name)
hIndex = hIndex + 1
end
self:setValue("")
end
if (key == keys.up) then
elseif (key == keys.up) then
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
-- arrow up
if (textY > 1) then
textY = textY - 1
@@ -440,8 +415,8 @@ return function(name)
end
end
end
end
if (key == keys.down) then
elseif (key == keys.down) then
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
-- arrow down
if (textY < #lines) then
textY = textY + 1
@@ -460,8 +435,8 @@ return function(name)
hIndex = hIndex + 1
end
end
end
if (key == keys.right) then
elseif (key == keys.right) then
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
-- arrow right
textX = textX + 1
if (textY < #lines) then
@@ -482,8 +457,8 @@ return function(name)
wIndex = 1
end
end
if (key == keys.left) then
elseif (key == keys.left) then
startSelX, startSelY, endSelX, endSelY = nil, nil, nil, nil
-- arrow left
textX = textX - 1
if (textX >= 1) then
@@ -504,6 +479,19 @@ return function(name)
if (wIndex < 1) then
wIndex = 1
end
elseif(key == keys.tab)then
if(textX % 3 == 0 )then
lines[textY] = lines[textY]:sub(1, textX - 1) .. " " .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self:getForeground()] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self:getBackground()] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
textX = textX + 1
end
while textX % 3 ~= 0 do
lines[textY] = lines[textY]:sub(1, textX - 1) .. " " .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self:getForeground()] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self:getBackground()] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
textX = textX + 1
end
end
if not((obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h)) then
@@ -519,7 +507,7 @@ return function(name)
if (cursorX < 1) then
cursorX = 0
end
self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor)
parent:setCursor(true, obx + cursorX, oby + cursorY, self:getForeground())
self:updateDraw()
return true
end
@@ -527,11 +515,15 @@ return function(name)
charHandler = function(self, char)
if(base.charHandler(self, char))then
local obx, oby = self:getAnchorPosition()
local parent = self:getParent()
local obx, oby = self:getPosition()
local w,h = self:getSize()
if(isSelected())then
removeSelection(self)
end
lines[textY] = lines[textY]:sub(1, textX - 1) .. char .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self.fgColor] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self:getForeground()] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self:getBackground()] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
textX = textX + 1
if (textX >= w + wIndex) then
wIndex = wIndex + 1
@@ -552,10 +544,7 @@ return function(name)
if (cursorX < 1) then
cursorX = 0
end
if(isSelected())then
removeSelection(self)
end
self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor)
parent:setCursor(true, obx + cursorX, oby + cursorY, self:getForeground())
self:updateDraw()
return true
end
@@ -563,30 +552,31 @@ return function(name)
dragHandler = function(self, button, x, y)
if (base.dragHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local anchx, anchy = self:getAnchorPosition()
local parent = self:getParent()
local obx, oby = self:getAbsolutePosition()
local anchx, anchy = self:getPosition()
local w,h = self:getSize()
if (lines[y - oby + hIndex] ~= nil) then
if(anchx+w > anchx + x - (obx+1)+ wIndex)and(anchx < anchx + x - obx+ wIndex)then
if anchx <= x - obx + wIndex and anchx + w > x - obx + wIndex then
textX = x - obx + wIndex
textY = y - oby + hIndex
endSelX = textX
endSelY = textY
if (textX > lines[textY]:len()) then
if textX > lines[textY]:len() then
textX = lines[textY]:len() + 1
endSelX = textX
end
if (textX < wIndex) then
endSelX = textX
endSelY = textY
if textX < wIndex then
wIndex = textX - 1
if (wIndex < 1) then
if wIndex < 1 then
wIndex = 1
end
end
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
parent:setCursor(not isSelected(), anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
self:updateDraw()
end
end
end
return true
end
@@ -594,8 +584,9 @@ return function(name)
scrollHandler = function(self, dir, x, y)
if (base.scrollHandler(self, dir, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local anchx, anchy = self:getAnchorPosition()
local parent = self:getParent()
local obx, oby = self:getAbsolutePosition()
local anchx, anchy = self:getPosition()
local w,h = self:getSize()
hIndex = hIndex + dir
if (hIndex > #lines - (h - 1)) then
@@ -607,9 +598,9 @@ return function(name)
end
if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (anchy + textY - hIndex >= anchy and anchy + textY - hIndex < anchy + h) then
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
parent:setCursor(not isSelected(), anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
else
self.parent:setCursor(false)
parent:setCursor(false)
end
self:updateDraw()
return true
@@ -618,8 +609,9 @@ return function(name)
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local anchx, anchy = self:getAnchorPosition()
local parent = self:getParent()
local obx, oby = self:getAbsolutePosition()
local anchx, anchy = self:getPosition()
if (lines[y - oby + hIndex] ~= nil) then
textX = x - obx + wIndex
textY = y - oby + hIndex
@@ -639,17 +631,15 @@ return function(name)
end
self:updateDraw()
end
if (self.parent ~= nil) then
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
end
parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
return true
end
end,
mouseUpHandler = function(self, button, x, y)
if (base.mouseUpHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local anchx, anchy = self:getAnchorPosition()
local obx, oby = self:getAbsolutePosition()
local anchx, anchy = self:getPosition()
if (lines[y - oby + hIndex] ~= nil) then
endSelX = x - obx + wIndex
endSelY = y - oby + hIndex
@@ -666,100 +656,89 @@ return function(name)
end,
eventHandler = function(self, event, paste, p2, p3, p4)
base.eventHandler(self, event, paste, p2, p3, p4)
if(event=="paste")then
if(self:isFocused())then
local w, h = self:getSize()
lines[textY] = lines[textY]:sub(1, textX - 1) .. paste .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self.fgColor]:rep(paste:len()) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor]:rep(paste:len()) .. bgLines[textY]:sub(textX, bgLines[textY]:len())
textX = textX + paste:len()
if (textX >= w + wIndex) then
wIndex = (textX+1)-w
if(base.eventHandler(self, event, paste, p2, p3, p4))then
if(event=="paste")then
if(self:isFocused())then
local parent = self:getParent()
local fgColor, bgColor = self:getForeground(), self:getBackground()
local w, h = self:getSize()
lines[textY] = lines[textY]:sub(1, textX - 1) .. paste .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[fgColor]:rep(paste:len()) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[bgColor]:rep(paste:len()) .. bgLines[textY]:sub(textX, bgLines[textY]:len())
textX = textX + paste:len()
if (textX >= w + wIndex) then
wIndex = (textX+1)-w
end
local anchx, anchy = self:getPosition()
parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, fgColor)
updateColors(self)
self:updateDraw()
end
local anchx, anchy = self:getAnchorPosition()
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
updateColors(self)
self:updateDraw()
end
end
end,
setSelectionColor = function(self, bg, fg)
selectionBG = bg or selectionBG
selectionFG = fg or selectionFG
return self
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
for n = 1, h do
local text = ""
local bg = ""
local fg = ""
if (lines[n + hIndex - 1] ~= nil) then
text = lines[n + hIndex - 1]
fg = fgLines[n + hIndex - 1]
bg = bgLines[n + hIndex - 1]
end
text = text:sub(wIndex, w + wIndex - 1)
bg = bg:sub(wIndex, w + wIndex - 1)
fg = fg:sub(wIndex, w + wIndex - 1)
local space = w - text:len()
if (space < 0) then
space = 0
end
text = text .. rep(self.bgSymbol, space)
bg = bg .. rep(tHex[self.bgColor], space)
fg = fg .. rep(tHex[self.fgColor], space)
self.parent:setText(obx, oby + n - 1, text)
self.parent:setBG(obx, oby + n - 1, bg)
self.parent:setFG(obx, oby + n - 1, fg)
base.draw(self)
self:addDraw("textfield", function()
local parent = self:getParent()
local obx, oby = self:getPosition()
local w, h = self:getSize()
local bgColor = tHex[self:getBackground()]
local fgColor = tHex[self:getForeground()]
for n = 1, h do
local text = ""
local bg = ""
local fg = ""
if lines[n + hIndex - 1] then
text = lines[n + hIndex - 1]
fg = fgLines[n + hIndex - 1]
bg = bgLines[n + hIndex - 1]
end
--[[
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
local sx,ex,sy,ey = getSelectionCoordinates(self)
for n=sy,ey do
local line = lines[n]:len()
local xOffset = 0
if(n==sy)and(n==ey)then
xOffset = sx-1
line = line - (sx-1) - (line - ex)
elseif(n==ey)then
line = line - (line - ex)
elseif(n==sy)then
line = line-(sx-1)
xOffset = sx-1
end
self.parent:setBG(obx + xOffset, oby + n - 1, rep(tHex[selectionBG], line))
self.parent:setFG(obx + xOffset, oby + n - 1, rep(tHex[selectionFG], line))
text = sub(text, wIndex, w + wIndex - 1)
bg = rep(bgColor, w)
fg = rep(fgColor, w)
self:addText(1, n, text)
self:addBG(1, n, bg)
self:addFG(1, n, fg)
self:addBlit(1, n, text, fg, bg)
end
if startSelX and endSelX and startSelY and endSelY then
local sx, ex, sy, ey = getSelectionCoordinates(self)
for n = sy, ey do
local line = #lines[n]
local xOffset = 0
if n == sy and n == ey then
xOffset = sx - 1
line = line - (sx - 1) - (line - ex)
elseif n == ey then
line = line - (line - ex)
elseif n == sy then
line = line - (sx - 1)
xOffset = sx - 1
end
end]]
if(self:isFocused())then
local anchx, anchy = self:getAnchorPosition()
--self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
self:addBG(1 + xOffset, n, rep(tHex[selectionBG], line))
self:addFG(1 + xOffset, n, rep(tHex[selectionFG], line))
end
end
end
end)
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_scroll", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("key", self)
self.parent:addEvent("char", self)
self.parent:addEvent("other_event", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("TextfieldBG")
self.fgColor = self.parent:getTheme("TextfieldText")
end
load = function(self)
self:listenEvent("mouse_click")
self:listenEvent("mouse_up")
self:listenEvent("mouse_scroll")
self:listenEvent("mouse_drag")
self:listenEvent("key")
self:listenEvent("char")
self:listenEvent("other_event")
end,
}
object.__index = object
return setmetatable(object, base)
end
end

View File

@@ -1,7 +1,6 @@
local xmlValue = require("utils").getValueFromXML
return function(name, basalt)
local base = basalt.getObject("Object")(name, basalt)
return function(name)
local object
local objectType = "Thread"
local func
@@ -9,42 +8,9 @@ return function(name)
local isActive = false
local filter
local generateXMLEventFunction = function(self, str)
if(str:sub(1,1)=="#")then
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
if(o~=nil)and(o.internalObjetCall~=nil)then
return (function()o:internalObjetCall()end)
end
else
return self:getBaseFrame():getVariable(str)
end
return self
end
object = {
name = name,
local object = {
getType = function(self)
return objectType
end;
getZIndex = function(self)
return 1
end;
getName = function(self)
return self.name
end;
getBaseFrame = function(self)
if(self.parent~=nil)then
return self.parent:getBaseFrame()
end
return self
end;
setValuesByXMLData = function(self, data)
local f
if(xmlValue("thread", data)~=nil)then f = generateXMLEventFunction(self, xmlValue("thread", data)) end
if(xmlValue("start", data)~=nil)then if(xmlValue("start", data))and(f~=nil)then self:start(f) end end
return self
end,
start = function(self, f)
@@ -62,36 +28,36 @@ return function(name)
error("Thread Error Occurred - " .. result)
end
end
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_scroll", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("key", self)
self.parent:addEvent("key_up", self)
self.parent:addEvent("char", self)
self.parent:addEvent("other_event", self)
self:listenEvent("mouse_click")
self:listenEvent("mouse_up")
self:listenEvent("mouse_scroll")
self:listenEvent("mouse_drag")
self:listenEvent("key")
self:listenEvent("key_up")
self:listenEvent("char")
self:listenEvent("other_event")
return self
end;
end,
getStatus = function(self, f)
if (cRoutine ~= nil) then
return coroutine.status(cRoutine)
end
return nil
end;
end,
stop = function(self, f)
isActive = false
self.parent:removeEvent("mouse_click", self)
self.parent:removeEvent("mouse_up", self)
self.parent:removeEvent("mouse_scroll", self)
self.parent:removeEvent("mouse_drag", self)
self.parent:removeEvent("key", self)
self.parent:removeEvent("key_up", self)
self.parent:removeEvent("char", self)
self.parent:removeEvent("other_event", self)
self:listenEvent("mouse_click", false)
self:listenEvent("mouse_up", false)
self:listenEvent("mouse_scroll", false)
self:listenEvent("mouse_drag", false)
self:listenEvent("key", false)
self:listenEvent("key_up", false)
self:listenEvent("char", false)
self:listenEvent("other_event", false)
return self
end;
end,
mouseHandler = function(self, ...)
self:eventHandler("mouse_click", ...)
@@ -136,11 +102,10 @@ return function(name)
self:stop()
end
end
end;
end,
}
object.__index = object
return object
return setmetatable(object, base)
end

View File

@@ -1,6 +1,3 @@
local basaltEvent = require("basaltEvent")
local xmlValue = require("utils").getValueFromXML
return function(name)
local objectType = "Timer"
@@ -8,64 +5,18 @@ return function(name)
local savedRepeats = 0
local repeats = 0
local timerObj
local eventSystem = basaltEvent()
local timerIsActive = false
local generateXMLEventFunction = function(self, func, val)
local createF = function(str)
if(str:sub(1,1)=="#")then
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
if(o~=nil)and(o.internalObjetCall~=nil)then
func(self,function()o:internalObjetCall()end)
end
else
func(self,self:getBaseFrame():getVariable(str))
end
end
if(type(val)=="string")then
createF(val)
elseif(type(val)=="table")then
for k,v in pairs(val)do
createF(v)
end
end
return self
end
local object = {
name = name,
getType = function(self)
return objectType
end;
setValuesByXMLData = function(self, data)
if(xmlValue("time", data)~=nil)then timer = xmlValue("time", data) end
if(xmlValue("repeat", data)~=nil)then savedRepeats = xmlValue("repeat", data) end
if(xmlValue("start", data)~=nil)then if(xmlValue("start", data))then self:start() end end
if(xmlValue("onCall", data)~=nil)then generateXMLEventFunction(self, self.onCall, xmlValue("onCall", data)) end
return self
end,
getBaseFrame = function(self)
if(self.parent~=nil)then
return self.parent:getBaseFrame()
end
return self
end;
getZIndex = function(self)
return 1
end;
getName = function(self)
return self.name
end;
setTime = function(self, _timer, _repeats)
timer = _timer or 0
savedRepeats = _repeats or 1
return self
end;
end,
start = function(self)
if(timerIsActive)then
@@ -74,31 +25,31 @@ return function(name)
repeats = savedRepeats
timerObj = os.startTimer(timer)
timerIsActive = true
self.parent:addEvent("other_event", self)
self:listenEvent("other_event")
return self
end;
end,
isActive = function(self)
return timerIsActive
end;
end,
cancel = function(self)
if (timerObj ~= nil) then
os.cancelTimer(timerObj)
end
timerIsActive = false
self.parent:removeEvent("other_event", self)
self:removeEvent("other_event")
return self
end;
end,
onCall = function(self, func)
eventSystem:registerEvent("timed_event", func)
self:registerEvent("timed_event", func)
return self
end;
end,
eventHandler = function(self, event, tObj)
if event == "timer" and tObj == timerObj and timerIsActive then
eventSystem:sendEvent("timed_event", self)
self:sendEvent("timed_event")
if (repeats >= 1) then
repeats = repeats - 1
if (repeats >= 1) then
@@ -108,7 +59,7 @@ return function(name)
timerObj = os.startTimer(timer)
end
end
end;
end,
}
object.__index = object

262
Basalt/objects/Treeview.lua Normal file
View File

@@ -0,0 +1,262 @@
local utils = require("utils")
local tHex = require("tHex")
return function(name, basalt)
local base = basalt.getObject("ChangeableObject")(name, basalt)
local objectType = "Treeview"
local nodes = {}
local itemSelectedBG = colors.black
local itemSelectedFG = colors.lightGray
local selectionColorActive = true
local textAlign = "left"
local xOffset, yOffset = 0, 0
local scrollable = true
base:setSize(16, 8)
base:setZIndex(5)
local function newNode(text, expandable)
text = text or ""
expandable = expandable or false
local expanded = false
local parent = nil
local children = {}
local node = {}
node = {
getChildren = function()
return children
end,
setParent = function(p)
parent = p
end,
getParent = function()
return parent
end,
addChild = function(text, expandable)
local childNode = newNode(text, expandable)
childNode.setParent(node)
table.insert(children, childNode)
base:updateDraw()
return childNode
end,
setExpanded = function(exp)
if(expandable)then
expanded = exp
end
base:updateDraw()
end,
isExpanded = function()
return expanded
end,
setExpandable = function(expandable)
expandable = expandable
base:updateDraw()
end,
isExpandable = function()
return expandable
end,
removeChild = function(index)
table.remove(children, index)
end,
findChildrenByText = function(searchText)
local foundNodes = {}
for _, child in ipairs(children) do
if child.getText() == searchText then
table.insert(foundNodes, child)
end
end
return foundNodes
end,
getText = function()
return text
end,
setText = function(t)
text = t
end
}
return node
end
local root = newNode("Root", true)
root.setExpanded(true)
local object = {
init = function(self)
local parent = self:getParent()
self:listenEvent("mouse_click")
self:listenEvent("mouse_scroll")
return base.init(self)
end,
getBase = function(self)
return base
end,
getType = function(self)
return objectType
end,
isType = function(self, t)
return objectType == t or base.isType ~= nil and base.isType(t) or false
end,
setOffset = function(self, x, y)
xOffset = x
yOffset = y
return self
end,
getOffset = function(self)
return xOffset, yOffset
end,
setScrollable = function(self, scroll)
scrollable = scroll
return self
end,
setSelectionColor = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self:getBackground()
itemSelectedFG = fgCol or self:getForeground()
selectionColorActive = active~=nil and active or true
self:updateDraw()
return self
end,
getSelectionColor = function(self)
return itemSelectedBG, itemSelectedFG
end,
isSelectionColorActive = function(self)
return selectionColorActive
end,
getRoot = function(self)
return root
end,
mouseHandler = function(self, button, x, y)
if base.mouseHandler(self, button, x, y) then
local currentLine = 1 - yOffset
local obx, oby = self:getAbsolutePosition()
local w, h = self:getSize()
local function checkNodeClick(node, level)
if y == oby+currentLine-1 then
if x >= obx and x < obx + w then
node.setExpanded(not node.isExpanded())
self:setValue(node)
self:updateDraw()
return true
end
end
currentLine = currentLine + 1
if node.isExpanded() then
for _, child in ipairs(node.getChildren()) do
if checkNodeClick(child, level + 1) then
return true
end
end
end
return false
end
for _, item in ipairs(root.getChildren()) do
if checkNodeClick(item, 1) then
return true
end
end
end
end,
scrollHandler = function(self, dir, x, y)
if base.scrollHandler(self, dir, x, y) then
if scrollable then
local _, h = self:getSize()
yOffset = yOffset + dir
if yOffset < 0 then
yOffset = 0
end
if dir >= 1 then
local visibleLines = 0
local function countVisibleLines(node, level)
visibleLines = visibleLines + 1
if node.isExpanded() then
for _, child in ipairs(node.getChildren()) do
countVisibleLines(child, level + 1)
end
end
end
for _, item in ipairs(root.getChildren()) do
countVisibleLines(item, 1)
end
if visibleLines > h then
if yOffset > visibleLines - h then
yOffset = visibleLines - h
end
else
yOffset = yOffset - 1
end
end
self:updateDraw()
end
return true
end
return false
end,
draw = function(self)
base.draw(self)
self:addDraw("treeview", function()
local currentLine = 1 - yOffset
local lastClickedNode = self:getValue()
local function drawNode(node, level)
local w, h = self:getSize()
if currentLine >= 1 and currentLine <= h then
local bg = (node == lastClickedNode) and itemSelectedBG or self:getBackground()
local fg = (node == lastClickedNode) and itemSelectedFG or self:getForeground()
local text = node.getText()
self:addBlit(1 + level + xOffset, currentLine, text, tHex[fg]:rep(#text), tHex[bg]:rep(#text))
end
currentLine = currentLine + 1
if node.isExpanded() then
for _, child in ipairs(node.getChildren()) do
drawNode(child, level + 1)
end
end
end
for _, item in ipairs(root.getChildren()) do
drawNode(item, 1)
end
end)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -0,0 +1,618 @@
local utils = require("utils")
local tHex = require("tHex")
local sub, find, insert = string.sub, string.find, table.insert
return function(name, basalt)
local base = basalt.getObject("Object")(name, basalt)
-- Base object
local objectType = "VisualObject" -- not changeable
local isVisible,ignOffset,isHovered,isClicked,isDragging = true,false,false,false,false
local zIndex = 1
local x, y, width, height = 1,1,1,1
local dragStartX, dragStartY, dragXOffset, dragYOffset = 0, 0, 0, 0
local bgColor,fgColor, transparency = colors.black, colors.white, false
local parent
local preDrawQueue = {}
local drawQueue = {}
local postDrawQueue = {}
local renderObject = {}
local function split(str, d)
local result = {}
if str == "" then
return result
end
d = d or " "
local start = 1
local delim_start, delim_end = find(str, d, start)
while delim_start do
insert(result, {x=start, value=sub(str, start, delim_start - 1)})
start = delim_end + 1
delim_start, delim_end = find(str, d, start)
end
insert(result, {x=start, value=sub(str, start)})
return result
end
local object = {
getType = function(self)
return objectType
end,
getBase = function(self)
return base
end,
isType = function(self, t)
return objectType==t or base.isType~=nil and base.isType(t) or false
end,
getBasalt = function(self)
return basalt
end,
show = function(self)
isVisible = true
self:updateDraw()
return self
end,
hide = function(self)
isVisible = false
self:updateDraw()
return self
end,
isVisible = function(self)
return isVisible
end,
setVisible = function(self, _isVisible)
isVisible = _isVisible or not isVisible
self:updateDraw()
return self
end,
setTransparency = function(self, _transparency)
transparency = _transparency~= nil and _transparency or true
self:updateDraw()
return self
end,
setParent = function(self, newParent, noRemove)
base.setParent(self, newParent, noRemove)
parent = newParent
return self
end,
setFocus = function(self)
if (parent ~= nil) then
parent:setFocusedObject(self)
end
return self
end,
setZIndex = function(self, index)
zIndex = index
if (parent ~= nil) then
parent:updateZIndex(self, zIndex)
self:updateDraw()
end
return self
end,
getZIndex = function(self)
return zIndex
end,
updateDraw = function(self)
if (parent ~= nil) then
parent:updateDraw()
end
return self
end,
setPosition = function(self, xPos, yPos, rel)
local curX, curY
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()
return self
end,
getX = function(self)
return x
end,
getY = function(self)
return y
end,
getPosition = function(self)
return x, y
end,
setSize = function(self, newWidth, newHeight, rel)
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:updateDraw()
return self
end,
getHeight = function(self)
return height
end,
getWidth = function(self)
return width
end,
getSize = function(self)
return width, height
end,
setBackground = function(self, color)
bgColor = color
self:updateDraw()
return self
end,
getBackground = function(self)
return bgColor
end,
setForeground = function(self, color)
fgColor = color or false
self:updateDraw()
return self
end,
getForeground = function(self)
return fgColor
end,
getAbsolutePosition = function(self, x, y)
-- relative position to absolute position
if (x == nil) or (y == nil) then
x, y = self:getPosition()
end
if (parent ~= nil) then
local fx, fy = parent:getAbsolutePosition()
x = fx + x - 1
y = fy + y - 1
end
return x, y
end,
ignoreOffset = function(self, ignore)
ignOffset = ignore
if(ignore==nil)then ignOffset = true end
return self
end,
isCoordsInObject = function(self, x, y)
if(isVisible)and(self:isEnabled())then
if(x==nil)or(y==nil)then return false end
local objX, objY = self:getAbsolutePosition()
local w, h = self:getSize()
if (objX <= x) and (objX + w > x) and (objY <= y) and (objY + h > y) then
return true
end
end
return false
end,
onGetFocus = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("get_focus", v)
end
end
return self
end,
onLoseFocus = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("lose_focus", v)
end
end
return self
end,
isFocused = function(self)
if (parent ~= nil) then
return parent:getFocusedObject() == self
end
return true
end,
onResize = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("basalt_resize", v)
end
end
return self
end,
onReposition = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("basalt_reposition", v)
end
end
return self
end,
mouseHandler = function(self, button, x, y, isMon)
if(self:isCoordsInObject(x, y))then
local objX, objY = self:getAbsolutePosition()
local val = self:sendEvent("mouse_click", self, button, x - (objX-1), y - (objY-1), x, y, isMon)
if(val==false)then return false end
if(parent~=nil)then
parent:setFocusedObject(self)
end
isClicked = true
isDragging = true
dragStartX, dragStartY = x, y
return true
end
end,
mouseUpHandler = function(self, button, x, y)
isDragging = false
if(isClicked)then
local objX, objY = self:getAbsolutePosition()
local val = self:sendEvent("mouse_release", self, "mouse_release", button, x - (objX-1), y - (objY-1), x, y)
isClicked = false
end
if(self:isCoordsInObject(x, y))then
local objX, objY = self:getAbsolutePosition()
local val = self:sendEvent("mouse_up", self, button, x - (objX-1), y - (objY-1), x, y)
if(val==false)then return false end
return true
end
end,
dragHandler = function(self, button, x, y)
if(isDragging)then
local objX, objY = self:getAbsolutePosition()
local val = self:sendEvent("mouse_drag", self, button, x - (objX-1), y - (objY-1), dragStartX-x, dragStartY-y, x, y)
dragStartX, dragStartY = x, y
if(val~=nil)then return val end
if(parent~=nil)then
parent:setFocusedObject(self)
end
return true
end
if(self:isCoordsInObject(x, y))then
local objX, objY = self:getAbsolutePosition()
dragStartX, dragStartY = x, y
dragXOffset, dragYOffset = objX - x, objY - y
end
end,
scrollHandler = function(self, dir, x, y)
if(self:isCoordsInObject(x, y))then
local objX, objY = self:getAbsolutePosition()
local val = self:sendEvent("mouse_scroll", self, "mouse_scroll", dir, x - (objX-1), y - (objY-1))
if(val==false)then return false end
if(parent~=nil)then
parent:setFocusedObject(self)
end
return true
end
end,
hoverHandler = function(self, x, y, stopped)
if(self:isCoordsInObject(x, y))then
local val = self:sendEvent("mouse_hover", self, "mouse_hover", x, y, stopped)
if(val==false)then return false end
isHovered = true
return true
end
if(isHovered)then
local val = self:sendEvent("mouse_leave", self, "mouse_leave", x, y, stopped)
if(val==false)then return false end
isHovered = false
end
end,
keyHandler = function(self, key, isHolding)
if(self:isEnabled())and(isVisible)then
if (self:isFocused()) then
local val = self:sendEvent("key", self, "key", key, isHolding)
if(val==false)then return false end
return true
end
end
end,
keyUpHandler = function(self, key)
if(self:isEnabled())and(isVisible)then
if (self:isFocused()) then
local val = self:sendEvent("key_up", self, "key_up", key)
if(val==false)then return false end
return true
end
end
end,
charHandler = function(self, char)
if(self:isEnabled())and(isVisible)then
if(self:isFocused())then
local val = self:sendEvent("char", self, "char", char)
if(val==false)then return false end
return true
end
end
end,
eventHandler = function(self, event, ...)
local val = self:sendEvent("other_event", self, event, ...)
if(val~=nil)then return val end
end,
customEventHandler = function(self, event, ...)
local val = self:sendEvent("custom_event", self, event, ...)
if(val~=nil)then return val end
return true
end,
getFocusHandler = function(self)
local val = self:sendEvent("get_focus", self)
if(val~=nil)then return val end
return true
end,
loseFocusHandler = function(self)
isDragging = false
local val = self:sendEvent("lose_focus", self)
if(val~=nil)then return val end
return true
end,
addDraw = function(self, name, f, pos, typ, active)
local queue = (typ==nil or typ==1) and drawQueue or typ==2 and preDrawQueue or typ==3 and postDrawQueue
pos = pos or #queue+1
if(name~=nil)then
for k,v in pairs(queue)do
if(v.name==name)then
table.remove(queue, k)
break
end
end
local t = {name=name, f=f, pos=pos, active=active~=nil and active or true}
table.insert(queue, pos, t)
end
self:updateDraw()
return self
end,
addPreDraw = function(self, name, f, pos, typ)
self:addDraw(name, f, pos, 2)
return self
end,
addPostDraw = function(self, name, f, pos, typ)
self:addDraw(name, f, pos, 3)
return self
end,
setDrawState = function(self, name, state, typ)
local queue = (typ==nil or typ==1) and drawQueue or typ==2 and preDrawQueue or typ==3 and postDrawQueue
for k,v in pairs(queue)do
if(v.name==name)then
v.active = state
break
end
end
self:updateDraw()
return self
end,
getDrawId = function(self, name, typ)
local queue = typ==1 and drawQueue or typ==2 and preDrawQueue or typ==3 and postDrawQueue or drawQueue
for k,v in pairs(queue)do
if(v.name==name)then
return k
end
end
end,
addText = function(self, x, y, text)
local obj = self:getParent() or self
local xPos,yPos = self:getPosition()
if(parent~=nil)then
local xO, yO = parent:getOffset()
xPos = ignOffset and xPos or xPos - xO
yPos = ignOffset and yPos or yPos - yO
end
if not(transparency)then
obj:setText(x+xPos-1, y+yPos-1, text)
return
end
local t = split(text, "\0")
for k,v in pairs(t)do
if(v.value~="")and(v.value~="\0")then
obj:setText(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
end,
addBG = function(self, x, y, bg, noText)
local obj = parent or self
local xPos,yPos = self:getPosition()
if(parent~=nil)then
local xO, yO = parent:getOffset()
xPos = ignOffset and xPos or xPos - xO
yPos = ignOffset and yPos or yPos - yO
end
if not(transparency)then
obj:setBG(x+xPos-1, y+yPos-1, bg)
return
end
local t = split(bg)
for k,v in pairs(t)do
if(v.value~="")and(v.value~=" ")then
if(noText~=true)then
obj:setText(x+v.x+xPos-2, y+yPos-1, (" "):rep(#v.value))
obj:setBG(x+v.x+xPos-2, y+yPos-1, v.value)
else
table.insert(renderObject, {x=x+v.x-1,y=y,bg=v.value})
obj:setBG(x+xPos-1, y+yPos-1, fg)
end
end
end
end,
addFG = function(self, x, y, fg)
local obj = parent or self
local xPos,yPos = self:getPosition()
if(parent~=nil)then
local xO, yO = parent:getOffset()
xPos = ignOffset and xPos or xPos - xO
yPos = ignOffset and yPos or yPos - yO
end
if not(transparency)then
obj:setFG(x+xPos-1, y+yPos-1, fg)
return
end
local t = split(fg)
for k,v in pairs(t)do
if(v.value~="")and(v.value~=" ")then
obj:setFG(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
end,
addBlit = function(self, x, y, t, fg, bg)
local obj = parent or self
local xPos,yPos = self:getPosition()
if(parent~=nil)then
local xO, yO = parent:getOffset()
xPos = ignOffset and xPos or xPos - xO
yPos = ignOffset and yPos or yPos - yO
end
if not(transparency)then
obj:blit(x+xPos-1, y+yPos-1, t, fg, bg)
return
end
local _text = split(t, "\0")
local _fg = split(fg)
local _bg = split(bg)
for k,v in pairs(_text)do
if(v.value~="")or(v.value~="\0")then
obj:setText(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
for k,v in pairs(_bg)do
if(v.value~="")or(v.value~=" ")then
obj:setBG(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
for k,v in pairs(_fg)do
if(v.value~="")or(v.value~=" ")then
obj:setFG(x+v.x+xPos-2, y+yPos-1, v.value)
end
end
end,
addTextBox = function(self, x, y, w, h, text)
local obj = parent or self
local xPos,yPos = self:getPosition()
if(parent~=nil)then
local xO, yO = parent:getOffset()
xPos = ignOffset and xPos or xPos - xO
yPos = ignOffset and yPos or yPos - yO
end
obj:drawTextBox(x+xPos-1, y+yPos-1, w, h, text)
end,
addForegroundBox = function(self, x, y, w, h, col)
local obj = parent or self
local xPos,yPos = self:getPosition()
if(parent~=nil)then
local xO, yO = parent:getOffset()
xPos = ignOffset and xPos or xPos - xO
yPos = ignOffset and yPos or yPos - yO
end
obj:drawForegroundBox(x+xPos-1, y+yPos-1, w, h, col)
end,
addBackgroundBox = function(self, x, y, w, h, col)
local obj = parent or self
local xPos,yPos = self:getPosition()
if(parent~=nil)then
local xO, yO = parent:getOffset()
xPos = ignOffset and xPos or xPos - xO
yPos = ignOffset and yPos or yPos - yO
end
obj:drawBackgroundBox(x+xPos-1, y+yPos-1, w, h, col)
end,
render = function(self)
if (isVisible)then
self:redraw()
end
end,
redraw = function(self)
for k,v in pairs(preDrawQueue)do
if (v.active)then
v.f(self)
end
end
for k,v in pairs(drawQueue)do
if (v.active)then
v.f(self)
end
end
for k,v in pairs(postDrawQueue)do
if (v.active)then
v.f(self)
end
end
return true
end,
draw = function(self)
self:addDraw("base", function()
local w,h = self:getSize()
if(bgColor~=false)then
self:addTextBox(1, 1, w, h, " ")
self:addBackgroundBox(1, 1, w, h, bgColor)
end
if(fgColor~=false)then
self:addForegroundBox(1, 1, w, h, fgColor)
end
end, 1)
end,
}
object.__index = object
return setmetatable(object, base)
end

View File

@@ -0,0 +1,40 @@
return function(name, basalt)
local base = basalt.getObject("VisualObject")(name, basalt)
-- Base object
local objectType = "ChangeableObject"
local value
local object = {
setValue = function(self, _value, valueChangedHandler)
if (value ~= _value) then
value = _value
self:updateDraw()
if(valueChangedHandler~=false)then
self:valueChangedHandler()
end
end
return self
end,
getValue = function(self)
return value
end,
onChange = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("value_changed", v)
end
end
return self
end,
valueChangedHandler = function(self)
self:sendEvent("value_changed", value)
end,
}
object.__index = object
return setmetatable(object, base)
end