Compare commits
77 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14c0630c1e | ||
|
|
64cb0d15e8 | ||
|
|
322ddb6158 | ||
|
|
c71557feb7 | ||
|
|
98b4191504 | ||
|
|
8dd8e63d21 | ||
|
|
28d35559c8 | ||
|
|
f3eb0accf8 | ||
|
|
599edf55dd | ||
|
|
303d0e65ff | ||
|
|
12e981a0e2 | ||
|
|
ca2fd64302 | ||
|
|
4fefe5734c | ||
|
|
8168fa4465 | ||
|
|
33753f6d8f | ||
|
|
1c7558d133 | ||
|
|
8d4e96a128 | ||
|
|
42aa1059cf | ||
|
|
a3886d34b0 | ||
|
|
5f8cbc90f3 | ||
|
|
82dcceda05 | ||
|
|
8ebede1430 | ||
|
|
31cda3d672 | ||
|
|
b794612017 | ||
|
|
9aa3663f90 | ||
|
|
71b4d6e01a | ||
|
|
2970451fc6 | ||
|
|
193616c20d | ||
|
|
df40fb496c | ||
|
|
9dc7449ace | ||
|
|
24b31a091a | ||
|
|
45f4d99db1 | ||
|
|
fe9d1f44a1 | ||
|
|
958b962ada | ||
|
|
cbe67c3919 | ||
|
|
63f88f8184 | ||
|
|
cc43817f34 | ||
|
|
c583eb666d | ||
|
|
f16e172fb1 | ||
|
|
4d2aad4155 | ||
|
|
dd7c26d4c3 | ||
|
|
8f370a0106 | ||
|
|
26567debd6 | ||
|
|
af14c7b867 | ||
|
|
1339337e6e | ||
|
|
84096eeca5 | ||
|
|
5bbed5be5c | ||
|
|
c945931c3c | ||
|
|
716debd419 | ||
|
|
f7e55c9f52 | ||
|
|
555ab6217c | ||
|
|
5373dab682 | ||
|
|
de94f8266f | ||
|
|
d3db685573 | ||
|
|
cfb4a197cd | ||
|
|
4feeaa7942 | ||
|
|
42972f3c2c | ||
|
|
e67945fccf | ||
|
|
1b7f61323b | ||
|
|
2293aacdec | ||
|
|
2d9efbbb5a | ||
|
|
9b0af8fcb3 | ||
|
|
87105c4856 | ||
|
|
a5e3191fde | ||
|
|
afe6639200 | ||
|
|
01a8226721 | ||
|
|
86972e21ab | ||
|
|
ad7a15af7c | ||
|
|
e22c2dfcd5 | ||
|
|
1f9734ef5f | ||
|
|
f4c469d64e | ||
|
|
cfec78f6f7 | ||
|
|
67a408a4c8 | ||
|
|
cbc8ca5c5b | ||
|
|
631eef525c | ||
|
|
930d2ad0c8 | ||
|
|
df1569af39 |
165
Basalt/libraries/reactivePrimitives.lua
Normal file
165
Basalt/libraries/reactivePrimitives.lua
Normal file
@@ -0,0 +1,165 @@
|
||||
local NodeStatus = {
|
||||
CURRENT = 0,
|
||||
STALE = 1,
|
||||
MAYBE_STALE = 2
|
||||
}
|
||||
|
||||
local Node = {}
|
||||
|
||||
Node.new = function()
|
||||
return {
|
||||
fn = nil,
|
||||
value = nil,
|
||||
status = NodeStatus.STALE,
|
||||
parents = {},
|
||||
children = {},
|
||||
|
||||
cleanup = function(self)
|
||||
for _, parentNode in ipairs(self.parents) do
|
||||
for index, childNode in ipairs(parentNode.children) do
|
||||
if (childNode == self) then
|
||||
table.remove(parentNode.children, index)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
self.parents = {}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
local ReactiveState = {
|
||||
listeningNode = nil,
|
||||
sourceNodes = {},
|
||||
effectNodes = {},
|
||||
transaction = false
|
||||
}
|
||||
|
||||
local Reactive = {}
|
||||
|
||||
Reactive.pushUpdates = function()
|
||||
for _, sourceNode in ipairs(ReactiveState.sourceNodes) do
|
||||
Reactive.pushSourceNodeUpdate(sourceNode)
|
||||
end
|
||||
Reactive.pullUpdates()
|
||||
end
|
||||
|
||||
Reactive.pushSourceNodeUpdate = function(sourceNode)
|
||||
if (sourceNode.status == NodeStatus.CURRENT) then
|
||||
return
|
||||
end
|
||||
Reactive.pushNodeUpdate(sourceNode)
|
||||
for _, childNode in ipairs(sourceNode.children) do
|
||||
childNode.status = NodeStatus.STALE
|
||||
end
|
||||
sourceNode.status = NodeStatus.CURRENT
|
||||
end
|
||||
|
||||
Reactive.pushNodeUpdate = function(node)
|
||||
if (node == nil) then
|
||||
return
|
||||
end
|
||||
node.status = NodeStatus.MAYBE_STALE
|
||||
for _, childNode in ipairs(node.children) do
|
||||
Reactive.pushNodeUpdate(childNode)
|
||||
end
|
||||
end
|
||||
|
||||
Reactive.pullUpdates = function()
|
||||
for _, effectNode in ipairs(ReactiveState.effectNodes) do
|
||||
Reactive.pullNodeUpdates(effectNode)
|
||||
end
|
||||
end
|
||||
|
||||
Reactive.pullNodeUpdates = function(node)
|
||||
if (node.status == NodeStatus.CURRENT) then
|
||||
return
|
||||
end
|
||||
if (node.status == NodeStatus.MAYBE_STALE) then
|
||||
for _, parentNode in ipairs(node.parents) do
|
||||
Reactive.pullNodeUpdates(parentNode)
|
||||
end
|
||||
end
|
||||
if (node.status == NodeStatus.STALE) then
|
||||
node:cleanup()
|
||||
local prevListeningNode = ReactiveState.listeningNode
|
||||
ReactiveState.listeningNode = node
|
||||
local oldValue = node.value
|
||||
node.value = node.fn()
|
||||
ReactiveState.listeningNode = prevListeningNode
|
||||
for _, childNode in ipairs(node.children) do
|
||||
if (oldValue == node.value) then
|
||||
childNode.status = NodeStatus.CURRENT
|
||||
else
|
||||
childNode.status = NodeStatus.STALE
|
||||
end
|
||||
end
|
||||
end
|
||||
node.status = NodeStatus.CURRENT
|
||||
end
|
||||
|
||||
Reactive.subscribe = function(node)
|
||||
local listeningNode = ReactiveState.listeningNode
|
||||
if (listeningNode ~= nil) then
|
||||
table.insert(node.children, listeningNode)
|
||||
table.insert(listeningNode.parents, node)
|
||||
end
|
||||
end
|
||||
|
||||
Reactive.observable = function(initialValue)
|
||||
local node = Node.new()
|
||||
node.value = initialValue
|
||||
node.status = NodeStatus.CURRENT
|
||||
local get = function()
|
||||
Reactive.subscribe(node)
|
||||
return node.value
|
||||
end
|
||||
local set = function(newValue)
|
||||
if (node.value == newValue) then
|
||||
return
|
||||
end
|
||||
node.value = newValue
|
||||
node.status = ReactiveState.STALE
|
||||
if (not ReactiveState.transaction) then
|
||||
Reactive.pushUpdates()
|
||||
end
|
||||
end
|
||||
table.insert(ReactiveState.sourceNodes, node)
|
||||
return get, set
|
||||
end
|
||||
|
||||
Reactive.derived = function(fn)
|
||||
local node = Node.new()
|
||||
node.fn = fn
|
||||
return function()
|
||||
if (node.status ~= NodeStatus.CURRENT) then
|
||||
Reactive.pullNodeUpdates(node)
|
||||
end
|
||||
Reactive.subscribe(node)
|
||||
return node.value
|
||||
end
|
||||
end
|
||||
|
||||
Reactive.effect = function(fn)
|
||||
local node = Node.new()
|
||||
node.fn = fn
|
||||
table.insert(ReactiveState.effectNodes, node)
|
||||
Reactive.pushUpdates()
|
||||
end
|
||||
|
||||
Reactive.transaction = function(fn)
|
||||
ReactiveState.transaction = true
|
||||
fn()
|
||||
ReactiveState.transaction = false
|
||||
Reactive.pushUpdates()
|
||||
end
|
||||
|
||||
Reactive.untracked = function(fn)
|
||||
local prevListeningNode = ReactiveState.listeningNode
|
||||
ReactiveState.listeningNode = nil
|
||||
local value = fn()
|
||||
ReactiveState.listeningNode = prevListeningNode
|
||||
return value
|
||||
end
|
||||
|
||||
return Reactive
|
||||
@@ -74,4 +74,4 @@ local XMLParser = {
|
||||
end
|
||||
}
|
||||
|
||||
return XMLParser
|
||||
return XMLParser
|
||||
@@ -78,7 +78,7 @@ local getObject = function(objectName)
|
||||
return getObjects()[objectName]
|
||||
end
|
||||
|
||||
local createObject = function(basalt, objectName, id)
|
||||
local createObject = function(objectName, id)
|
||||
return getObject(objectName)(id, basalt)
|
||||
end
|
||||
|
||||
@@ -515,6 +515,9 @@ basalt = {
|
||||
|
||||
stop = stop,
|
||||
stopUpdate = stop,
|
||||
getTerm = function()
|
||||
return baseTerm
|
||||
end,
|
||||
|
||||
isKeyDown = function(key)
|
||||
if(activeKey[key]==nil)then return false end
|
||||
@@ -600,4 +603,4 @@ if(basaltPlugins~=nil)then
|
||||
end
|
||||
end
|
||||
|
||||
return basalt
|
||||
return basalt
|
||||
@@ -36,9 +36,6 @@ return function(name, basalt)
|
||||
end
|
||||
|
||||
local function getChild(self, name)
|
||||
if (type(name)=="table") then
|
||||
name = name:getName()
|
||||
end
|
||||
for _, v in ipairs(children) do
|
||||
if v.element:getName() == name then
|
||||
return v.element
|
||||
@@ -47,7 +44,7 @@ return function(name, basalt)
|
||||
end
|
||||
|
||||
local function getDeepChild(self, name)
|
||||
local maybeChild = getChild(name)
|
||||
local maybeChild = self:getChild(name)
|
||||
if (maybeChild ~= nil) then
|
||||
return maybeChild
|
||||
end
|
||||
@@ -87,19 +84,21 @@ return function(name, basalt)
|
||||
|
||||
local function removeChild(self, element)
|
||||
if (type(element)=="string") then
|
||||
element = getChild(element:getName())
|
||||
element = self:getChild(element)
|
||||
end
|
||||
if (element==nil) then
|
||||
return
|
||||
end
|
||||
for i, v in ipairs(children) do
|
||||
if v.element == element then
|
||||
if v.element:getName() == element:getName() then
|
||||
table.remove(children, i)
|
||||
self:removeEvents(element)
|
||||
sorted = false
|
||||
self:updateDraw()
|
||||
return true
|
||||
end
|
||||
end
|
||||
self:removeEvents(element)
|
||||
sorted = false
|
||||
return false
|
||||
end
|
||||
|
||||
local function removeChildren(self)
|
||||
@@ -384,7 +383,7 @@ return function(name, basalt)
|
||||
xO, yO = 0, 0
|
||||
end
|
||||
end
|
||||
if (obj.element[v[1]](obj.element, btn, x+xO, y+yO, ...)) then
|
||||
if (obj.element[v[1]](obj.element, btn, x+xO, y+yO, ...)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -420,7 +419,7 @@ return function(name, basalt)
|
||||
|
||||
for objectName, _ in pairs(basalt.getObjects()) do
|
||||
container["add" .. objectName] = function(self, id)
|
||||
return self:addChild(basalt:createObject(objectName, id))
|
||||
return self:addChild(basalt.createObject(objectName, id))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
local function flexObjectPlugin(base, basalt)
|
||||
local flexGrow = 0
|
||||
local flexShrink = 0
|
||||
local flexBasis = 6
|
||||
local flexBasis = 0
|
||||
|
||||
local baseWidth, baseHeight = base:getSize()
|
||||
|
||||
local object = {
|
||||
getFlexGrow = function(self)
|
||||
@@ -30,14 +32,31 @@ local function flexObjectPlugin(base, basalt)
|
||||
setFlexBasis = function(self, value)
|
||||
flexBasis = value
|
||||
return self
|
||||
end
|
||||
end,
|
||||
|
||||
getSize = function(self)
|
||||
return baseWidth, baseHeight
|
||||
end,
|
||||
|
||||
getWidth = function(self)
|
||||
return baseWidth
|
||||
end,
|
||||
|
||||
getHeight = function(self)
|
||||
return baseHeight
|
||||
end,
|
||||
|
||||
setSize = function(self, width, height, rel, internalCall)
|
||||
base.setSize(self, width, height, rel)
|
||||
if not internalCall then
|
||||
baseWidth, baseHeight = base:getSize()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
}
|
||||
|
||||
for k,v in pairs(object)do
|
||||
base[k] = v
|
||||
end
|
||||
|
||||
return base
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
|
||||
return function(name, basalt)
|
||||
@@ -61,6 +80,7 @@ return function(name, basalt)
|
||||
setPosition = function(self) end,
|
||||
setSize = function(self) end,
|
||||
})
|
||||
lineBreakFakeObject:setFlexBasis(0):setFlexGrow(0):setFlexShrink(0)
|
||||
|
||||
local function sortChildren(self)
|
||||
if(wrap=="nowrap")then
|
||||
@@ -79,7 +99,7 @@ return function(name, basalt)
|
||||
lineOffset = lineOffset + lineSize + spacing
|
||||
lineSize = 1
|
||||
index = index + 1
|
||||
sortedChildren[index] = {offset=lineOffset, v}
|
||||
sortedChildren[index] = {offset=lineOffset}
|
||||
else
|
||||
table.insert(sortedChildren[index], v)
|
||||
end
|
||||
@@ -93,30 +113,31 @@ return function(name, basalt)
|
||||
local usedSize = 0
|
||||
local index = 1
|
||||
|
||||
for _,v in pairs(children)do
|
||||
if(sortedChildren[index]==nil)then sortedChildren[index]={offset=1} end
|
||||
|
||||
local childHeight = direction == "row" and v:getHeight() or v:getWidth()
|
||||
if childHeight > lineSize then
|
||||
lineSize = childHeight
|
||||
end
|
||||
for _,v in pairs(children) do
|
||||
if(sortedChildren[index]==nil) then sortedChildren[index]={offset=1} end
|
||||
|
||||
if v == lineBreakFakeObject then
|
||||
lineOffset = lineOffset + lineSize + spacing
|
||||
usedSize = 0
|
||||
lineSize = 1
|
||||
index = index + 1
|
||||
sortedChildren[index] = {offset=lineOffset, v}
|
||||
sortedChildren[index] = {offset=lineOffset}
|
||||
else
|
||||
local objSize = direction == "row" and v:getWidth() or v:getHeight()
|
||||
if(objSize+usedSize>maxSize)then
|
||||
if(objSize+usedSize<=maxSize) then
|
||||
table.insert(sortedChildren[index], v)
|
||||
usedSize = usedSize + objSize + spacing
|
||||
else
|
||||
lineOffset = lineOffset + lineSize + spacing
|
||||
lineSize = direction == "row" and v:getHeight() or v:getWidth()
|
||||
index = index + 1
|
||||
usedSize = 0
|
||||
usedSize = objSize + spacing
|
||||
sortedChildren[index] = {offset=lineOffset, v}
|
||||
else
|
||||
usedSize = usedSize + objSize
|
||||
table.insert(sortedChildren[index], v)
|
||||
end
|
||||
|
||||
local childHeight = direction == "row" and v:getHeight() or v:getWidth()
|
||||
if childHeight > lineSize then
|
||||
lineSize = childHeight
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -145,19 +166,19 @@ return function(name, basalt)
|
||||
local flexGrow = child:getFlexGrow()
|
||||
local flexShrink = child:getFlexShrink()
|
||||
|
||||
local baseWidth = child:getFlexBasis() ~= 0 and child:getFlexBasis() or child:getWidth()
|
||||
if totalFlexGrow > 0 then
|
||||
childWidth = child:getFlexBasis() + flexGrow / totalFlexGrow * remainingSpace
|
||||
childWidth = baseWidth + flexGrow / totalFlexGrow * remainingSpace
|
||||
else
|
||||
childWidth = child:getFlexBasis()
|
||||
childWidth = baseWidth
|
||||
end
|
||||
|
||||
if remainingSpace < 0 and totalFlexShrink > 0 then
|
||||
childWidth = child:getFlexBasis() + flexShrink / totalFlexShrink * remainingSpace
|
||||
childWidth = baseWidth + flexShrink / totalFlexShrink * remainingSpace
|
||||
end
|
||||
|
||||
child:setPosition(currentX, children.offset or 1)
|
||||
child:setSize(childWidth, child:getHeight())
|
||||
basalt.log(children.offset)
|
||||
child:setSize(childWidth, child:getHeight(), false, true)
|
||||
currentX = currentX + childWidth + spacing
|
||||
end
|
||||
end
|
||||
@@ -234,18 +255,19 @@ return function(name, basalt)
|
||||
local flexGrow = child:getFlexGrow()
|
||||
local flexShrink = child:getFlexShrink()
|
||||
|
||||
local baseHeight = child:getFlexBasis() ~= 0 and child:getFlexBasis() or child:getHeight()
|
||||
if totalFlexGrow > 0 then
|
||||
childHeight = child:getFlexBasis() + flexGrow / totalFlexGrow * remainingSpace
|
||||
childHeight = baseHeight + flexGrow / totalFlexGrow * remainingSpace
|
||||
else
|
||||
childHeight = child:getFlexBasis()
|
||||
childHeight = baseHeight
|
||||
end
|
||||
|
||||
if remainingSpace < 0 and totalFlexShrink > 0 then
|
||||
childHeight = child:getFlexBasis() + flexShrink / totalFlexShrink * remainingSpace
|
||||
childHeight = baseHeight + flexShrink / totalFlexShrink * remainingSpace
|
||||
end
|
||||
|
||||
child:setPosition(children.offset, currentY)
|
||||
child:setSize(child:getWidth(), childHeight)
|
||||
child:setSize(child:getWidth(), childHeight, false, true)
|
||||
currentY = currentY + childHeight + spacing
|
||||
end
|
||||
end
|
||||
@@ -326,6 +348,7 @@ return function(name, basalt)
|
||||
setJustifyContent = function(self, value)
|
||||
justifyContent = value
|
||||
updateLayout = true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
@@ -336,6 +359,7 @@ return function(name, basalt)
|
||||
setDirection = function(self, value)
|
||||
direction = value
|
||||
updateLayout = true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
@@ -346,6 +370,7 @@ return function(name, basalt)
|
||||
setSpacing = function(self, value)
|
||||
spacing = value
|
||||
updateLayout = true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
@@ -353,19 +378,52 @@ return function(name, basalt)
|
||||
return spacing
|
||||
end,
|
||||
|
||||
setFlexWrap = function(self, value)
|
||||
setWrap = function(self, value)
|
||||
wrap = value
|
||||
updateLayout = true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getWrap = function(self)
|
||||
return wrap
|
||||
end,
|
||||
|
||||
updateLayout = function(self)
|
||||
updateLayout = true
|
||||
self:updateDraw()
|
||||
end,
|
||||
|
||||
addBreak = function(self)
|
||||
table.insert(children, lineBreakFakeObject)
|
||||
updateLayout = true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
customEventHandler = function(self, event, ...)
|
||||
base.customEventHandler(self, event, ...)
|
||||
if event == "basalt_FrameResize" then
|
||||
updateLayout = true
|
||||
end
|
||||
end,
|
||||
|
||||
removeChild = function(self, child)
|
||||
if (type(child)=="string") then
|
||||
child = self:getChild(child)
|
||||
end
|
||||
if (child==nil) then
|
||||
return
|
||||
end
|
||||
base.removeChild(self, child)
|
||||
for k, v in pairs(children) do
|
||||
if v:getName() == child:getName() then
|
||||
table.remove(children, k)
|
||||
break
|
||||
end
|
||||
end
|
||||
updateLayout = true
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
@@ -381,7 +439,8 @@ return function(name, basalt)
|
||||
|
||||
for k, _ in pairs(basalt.getObjects()) do
|
||||
object["add" .. k] = function(self, name)
|
||||
local child = flexObjectPlugin(base["add" .. k](self, name), basalt)
|
||||
local baseChild = base["add" .. k](self, name)
|
||||
local child = flexObjectPlugin(baseChild, basalt)
|
||||
table.insert(children, child)
|
||||
updateLayout = true
|
||||
return child
|
||||
@@ -391,4 +450,3 @@ return function(name, basalt)
|
||||
object.__index = object
|
||||
return setmetatable(object, base)
|
||||
end
|
||||
|
||||
|
||||
@@ -147,6 +147,8 @@ return function(name, basalt)
|
||||
loadImage = function(self, path)
|
||||
if(fs.exists(path))then
|
||||
local newBimg = images.loadBIMG(path)
|
||||
print(newBimg[1][1])
|
||||
sleep(1)
|
||||
bimgLibrary = bimg(newBimg)
|
||||
activeFrame = 1
|
||||
bimgFrame = bimgLibrary.getFrameObject(1)
|
||||
|
||||
@@ -145,6 +145,13 @@ return function(name, basalt)
|
||||
|
||||
registerEvent = function(self, event, func)
|
||||
if(parent~=nil)then
|
||||
if(event=="mouse_drag")then
|
||||
parent:addEvent("mouse_click", self)
|
||||
parent:addEvent("mouse_up", self)
|
||||
end
|
||||
if(event=="mouse_release")then
|
||||
parent:addEvent("mouse_up", self)
|
||||
end
|
||||
parent:addEvent(event, self)
|
||||
end
|
||||
eventSystem:registerEvent(event, func)
|
||||
|
||||
@@ -25,7 +25,7 @@ return function(name, basalt)
|
||||
end
|
||||
end
|
||||
|
||||
if (h + x - width >= amount) then
|
||||
if (w + x - width >= amount) then
|
||||
amount = max(w + x - width, 0)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,8 +10,10 @@ return function(name, basalt)
|
||||
|
||||
local barType = "horizontal"
|
||||
local symbol = " "
|
||||
local symbolFG = colors.black
|
||||
local symbolFG = colors.gray
|
||||
local symbolBG = colors.gray
|
||||
local bgSymbol = " "
|
||||
local symbolColor = colors.black
|
||||
local maxValue = 12
|
||||
local index = 1
|
||||
local symbolSize = 1
|
||||
@@ -130,6 +132,7 @@ return function(name, basalt)
|
||||
base.draw(self)
|
||||
self:addDraw("slider", function()
|
||||
local w,h = self:getSize()
|
||||
local obx, oby = self:getPosition()
|
||||
local bgCol,fgCol = self:getBackground(), self:getForeground()
|
||||
if (barType == "horizontal") then
|
||||
self:addText(index, oby, symbol:rep(symbolSize))
|
||||
@@ -145,7 +148,10 @@ return function(name, basalt)
|
||||
end
|
||||
else
|
||||
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
|
||||
self:addBlit(1, 1+n, bgSymbol, tHex[fgCol], tHex[bgCol])
|
||||
self:addText(1, 1+n, bgSymbol)
|
||||
if(bgCol~=false)then self:addBG(1, 1+n, tHex[bgCol]) end
|
||||
if(fgCol~=false)then self:addFG(1, 1+n, tHex[fgCol]) end
|
||||
--self:addBlit(1, 1+n, bgSymbol, tHex[fgCol], tHex[bgCol])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -61,7 +61,7 @@ return function(name, basalt)
|
||||
end
|
||||
|
||||
local function removeSelection(self)
|
||||
local sx, ex, sy, ey = getSelectionCoordinates(self)
|
||||
local sx, ex, sy, ey = getSelectionCoordinates()
|
||||
local startLine = lines[sy]
|
||||
local endLine = lines[ey]
|
||||
lines[sy] = startLine:sub(1, sx - 1) .. endLine:sub(ex + 1, endLine:len())
|
||||
@@ -305,7 +305,7 @@ return function(name, basalt)
|
||||
return self
|
||||
end,
|
||||
|
||||
getXOffset = function(self, xOff)
|
||||
getXOffset = function(self)
|
||||
return wIndex
|
||||
end,
|
||||
|
||||
@@ -313,7 +313,7 @@ return function(name, basalt)
|
||||
return self:setOffset(xOff, nil)
|
||||
end,
|
||||
|
||||
getYOffset = function(self, xOff)
|
||||
getYOffset = function(self)
|
||||
return hIndex
|
||||
end,
|
||||
|
||||
@@ -333,7 +333,7 @@ return function(name, basalt)
|
||||
end,
|
||||
|
||||
keyHandler = function(self, key)
|
||||
if (base.keyHandler(self, event, key)) then
|
||||
if (base.keyHandler(self, key)) then
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
@@ -586,29 +586,28 @@ return function(name, basalt)
|
||||
if (base.dragHandler(self, button, x, y)) then
|
||||
local parent = self:getParent()
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local anchx, anchy = self:getPosition()
|
||||
local ox, oy = self:getPosition()
|
||||
local w,h = self:getSize()
|
||||
if (lines[y - oby + hIndex] ~= nil) then
|
||||
if anchx <= x - obx + wIndex and anchx + w > x - obx + wIndex then
|
||||
if(x - obx + wIndex > 0)and(x - obx + wIndex <= w)then
|
||||
textX = x - obx + wIndex
|
||||
textY = y - oby + hIndex
|
||||
|
||||
|
||||
if textX > lines[textY]:len() then
|
||||
textX = lines[textY]:len() + 1
|
||||
end
|
||||
|
||||
endSelX = textX
|
||||
endSelY = textY
|
||||
|
||||
|
||||
if textX < wIndex then
|
||||
wIndex = textX - 1
|
||||
if wIndex < 1 then
|
||||
wIndex = 1
|
||||
end
|
||||
end
|
||||
parent:setCursor(not isSelected(), anchx + textX - wIndex, anchy + textY - hIndex, self:getForeground())
|
||||
parent:setCursor(not isSelected(), ox + textX - wIndex, oy + textY - hIndex, self:getForeground())
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
@@ -671,7 +670,6 @@ return function(name, basalt)
|
||||
mouseUpHandler = function(self, button, x, y)
|
||||
if (base.mouseUpHandler(self, button, x, y)) then
|
||||
local obx, oby = self:getAbsolutePosition()
|
||||
local anchx, anchy = self:getPosition()
|
||||
if (lines[y - oby + hIndex] ~= nil) then
|
||||
endSelX = x - obx + wIndex
|
||||
endSelY = y - oby + hIndex
|
||||
@@ -680,32 +678,31 @@ return function(name, basalt)
|
||||
end
|
||||
if(startSelX==endSelX)and(startSelY==endSelY)then
|
||||
startSelX, endSelX, startSelY, endSelY = nil, nil, nil, nil
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, paste, p2, p3, p4)
|
||||
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()
|
||||
eventHandler = function(self, event, paste, ...)
|
||||
base.eventHandler(self, event, paste, ...)
|
||||
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
|
||||
end
|
||||
end,
|
||||
@@ -713,8 +710,6 @@ return function(name, basalt)
|
||||
draw = function(self)
|
||||
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()]
|
||||
@@ -740,21 +735,24 @@ return function(name, basalt)
|
||||
end
|
||||
|
||||
if startSelX and endSelX and startSelY and endSelY then
|
||||
local sx, ex, sy, ey = getSelectionCoordinates(self)
|
||||
local sx, ex, sy, ey = getSelectionCoordinates()
|
||||
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)
|
||||
xOffset = sx - 1 - (wIndex - 1)
|
||||
line = line - (sx - 1 - (wIndex - 1)) - (line - ex + (wIndex - 1))
|
||||
elseif n == ey then
|
||||
line = line - (line - ex)
|
||||
line = line - (line - ex + (wIndex - 1))
|
||||
elseif n == sy then
|
||||
line = line - (sx - 1)
|
||||
xOffset = sx - 1
|
||||
xOffset = sx - 1 - (wIndex - 1)
|
||||
end
|
||||
self:addBG(1 + xOffset, n, rep(tHex[selectionBG], line))
|
||||
self:addFG(1 + xOffset, n, rep(tHex[selectionFG], line))
|
||||
|
||||
local visible_line_length = math.min(line, w - xOffset)
|
||||
|
||||
self:addBG(1 + xOffset, n, rep(tHex[selectionBG], visible_line_length))
|
||||
self:addFG(1 + xOffset, n, rep(tHex[selectionFG], visible_line_length))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -28,11 +28,11 @@ return function(name, basalt)
|
||||
local onSelect
|
||||
|
||||
node = {
|
||||
getChildren = function()
|
||||
getChildren = function(self)
|
||||
return children
|
||||
end,
|
||||
|
||||
setParent = function(p)
|
||||
setParent = function(self, p)
|
||||
if(parent~=nil)then
|
||||
parent.removeChild(parent.findChildrenByText(node.getText()))
|
||||
end
|
||||
@@ -41,11 +41,11 @@ return function(name, basalt)
|
||||
return node
|
||||
end,
|
||||
|
||||
getParent = function()
|
||||
getParent = function(self)
|
||||
return parent
|
||||
end,
|
||||
|
||||
addChild = function(text, expandable)
|
||||
addChild = function(self, text, expandable)
|
||||
local childNode = newNode(text, expandable)
|
||||
childNode.setParent(node)
|
||||
table.insert(children, childNode)
|
||||
@@ -53,7 +53,7 @@ return function(name, basalt)
|
||||
return childNode
|
||||
end,
|
||||
|
||||
setExpanded = function(exp)
|
||||
setExpanded = function(self, exp)
|
||||
if(expandable)then
|
||||
expanded = exp
|
||||
end
|
||||
@@ -61,11 +61,11 @@ return function(name, basalt)
|
||||
return node
|
||||
end,
|
||||
|
||||
isExpanded = function()
|
||||
isExpanded = function(self)
|
||||
return expanded
|
||||
end,
|
||||
|
||||
onSelect = function(...)
|
||||
onSelect = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
onSelect = v
|
||||
@@ -74,23 +74,23 @@ return function(name, basalt)
|
||||
return node
|
||||
end,
|
||||
|
||||
callOnSelect = function()
|
||||
callOnSelect = function(self)
|
||||
if(onSelect~=nil)then
|
||||
onSelect(node)
|
||||
end
|
||||
end,
|
||||
|
||||
setExpandable = function(expandable)
|
||||
setExpandable = function(self, expandable)
|
||||
expandable = expandable
|
||||
base:updateDraw()
|
||||
return node
|
||||
end,
|
||||
|
||||
isExpandable = function()
|
||||
isExpandable = function(self)
|
||||
return expandable
|
||||
end,
|
||||
|
||||
removeChild = function(index)
|
||||
removeChild = function(self, index)
|
||||
if(type(index)=="table")then
|
||||
for k,v in pairs(index)do
|
||||
if(v==index)then
|
||||
@@ -104,7 +104,7 @@ return function(name, basalt)
|
||||
return node
|
||||
end,
|
||||
|
||||
findChildrenByText = function(searchText)
|
||||
findChildrenByText = function(self, searchText)
|
||||
local foundNodes = {}
|
||||
for _, child in ipairs(children) do
|
||||
if string.find(child.getText(), searchText) then
|
||||
@@ -114,11 +114,11 @@ return function(name, basalt)
|
||||
return foundNodes
|
||||
end,
|
||||
|
||||
getText = function()
|
||||
getText = function(self)
|
||||
return text
|
||||
end,
|
||||
|
||||
setText = function(t)
|
||||
setText = function(self, t)
|
||||
text = t
|
||||
base:updateDraw()
|
||||
return node
|
||||
@@ -129,7 +129,7 @@ return function(name, basalt)
|
||||
end
|
||||
|
||||
local root = newNode("Root", true)
|
||||
root.setExpanded(true)
|
||||
root:setExpanded(true)
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
@@ -251,7 +251,7 @@ return function(name, basalt)
|
||||
local function checkNodeClick(node, level)
|
||||
if y == oby+currentLine-1 then
|
||||
if x >= obx and x < obx + w then
|
||||
node.setExpanded(not node.isExpanded())
|
||||
node:setExpanded(not node:isExpanded())
|
||||
self:selectionHandler(node)
|
||||
self:setValue(node)
|
||||
self:updateDraw()
|
||||
@@ -259,8 +259,8 @@ return function(name, basalt)
|
||||
end
|
||||
end
|
||||
currentLine = currentLine + 1
|
||||
if node.isExpanded() then
|
||||
for _, child in ipairs(node.getChildren()) do
|
||||
if node:isExpanded() then
|
||||
for _, child in ipairs(node:getChildren()) do
|
||||
if checkNodeClick(child, level + 1) then
|
||||
return true
|
||||
end
|
||||
@@ -269,7 +269,7 @@ return function(name, basalt)
|
||||
return false
|
||||
end
|
||||
|
||||
for _, item in ipairs(root.getChildren()) do
|
||||
for _, item in ipairs(root:getChildren()) do
|
||||
if checkNodeClick(item, 1) then
|
||||
return true
|
||||
end
|
||||
@@ -291,14 +291,14 @@ return function(name, basalt)
|
||||
local visibleLines = 0
|
||||
local function countVisibleLines(node, level)
|
||||
visibleLines = visibleLines + 1
|
||||
if node.isExpanded() then
|
||||
for _, child in ipairs(node.getChildren()) do
|
||||
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
|
||||
for _, item in ipairs(root:getChildren()) do
|
||||
countVisibleLines(item, 1)
|
||||
end
|
||||
|
||||
@@ -333,16 +333,16 @@ return function(name, basalt)
|
||||
self:addBlit(1 + level + xOffset, currentLine, text, tHex[fg]:rep(#text), tHex[bg]:rep(#text))
|
||||
end
|
||||
|
||||
currentLine = currentLine + 1
|
||||
currentLine = currentLine + 1
|
||||
|
||||
if node.isExpanded() then
|
||||
for _, child in ipairs(node.getChildren()) do
|
||||
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
|
||||
for _, item in ipairs(root:getChildren()) do
|
||||
drawNode(item, 1)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -267,7 +267,7 @@ return function(name, basalt)
|
||||
|
||||
isFocused = function(self)
|
||||
if (parent ~= nil) then
|
||||
return parent:getFocusedObject() == self
|
||||
return parent:getFocused() == self
|
||||
end
|
||||
return true
|
||||
end,
|
||||
@@ -337,11 +337,11 @@ return function(name, basalt)
|
||||
end,
|
||||
|
||||
dragHandler = function(self, button, x, y)
|
||||
if(isDragging)then
|
||||
if(isDragging)then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = self:sendEvent("mouse_drag", button, x - (objX-1), y - (objY-1), dragStartX-x, dragStartY-y, x, y)
|
||||
dragStartX, dragStartY = x, y
|
||||
if(val~=nil)then return val end
|
||||
if(val==false)then return false end
|
||||
if(parent~=nil)then
|
||||
parent:setFocusedChild(self)
|
||||
end
|
||||
|
||||
@@ -28,7 +28,7 @@ return {
|
||||
local parent = self:getParent()
|
||||
local objects = {}
|
||||
for k,v in pairs(objectGroup)do
|
||||
objects[v] = parent:getObject(v)
|
||||
objects[v] = parent:getChild(v)
|
||||
if(objects[v]==nil)then
|
||||
error("Dynamic Values - unable to find object: "..v)
|
||||
end
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
The MIT License (MIT)
|
||||
Copyright © 2022 Oliver Caha (9551Dev)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ?Software?), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
THE SOFTWARE IS PROVIDED ?AS IS?, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
]]
|
||||
local t_sort,t_cat,s_char = table.sort,table.concat,string.char
|
||||
local function sort(a,b) return a[2] > b[2] end
|
||||
|
||||
@@ -1,5 +1,72 @@
|
||||
local XMLParser = require("xmlParser")
|
||||
|
||||
local Reactive = {}
|
||||
|
||||
Reactive.currentEffect = nil
|
||||
|
||||
Reactive.observable = function(initialValue)
|
||||
local value = initialValue
|
||||
local observerEffects = {}
|
||||
local get = function()
|
||||
if (Reactive.currentEffect ~= nil) then
|
||||
table.insert(observerEffects, Reactive.currentEffect)
|
||||
table.insert(Reactive.currentEffect.dependencies, observerEffects)
|
||||
end
|
||||
return value
|
||||
end
|
||||
local set = function(newValue)
|
||||
value = newValue
|
||||
local observerEffectsCopy = {}
|
||||
for index, effect in ipairs(observerEffects) do
|
||||
observerEffectsCopy[index] = effect
|
||||
end
|
||||
for _, effect in ipairs(observerEffectsCopy) do
|
||||
effect.execute()
|
||||
end
|
||||
end
|
||||
return get, set
|
||||
end
|
||||
|
||||
Reactive.untracked = function(getter)
|
||||
local parentEffect = Reactive.currentEffect
|
||||
Reactive.currentEffect = nil
|
||||
local value = getter()
|
||||
Reactive.currentEffect = parentEffect
|
||||
return value
|
||||
end
|
||||
|
||||
Reactive.effect = function(effectFn)
|
||||
local effect = {dependencies = {}}
|
||||
local execute = function()
|
||||
Reactive.clearEffectDependencies(effect)
|
||||
local parentEffect = Reactive.currentEffect
|
||||
Reactive.currentEffect = effect
|
||||
effectFn()
|
||||
Reactive.currentEffect = parentEffect
|
||||
end
|
||||
effect.execute = execute
|
||||
effect.execute()
|
||||
end
|
||||
|
||||
Reactive.derived = function(computeFn)
|
||||
local getValue, setValue = Reactive.observable();
|
||||
Reactive.effect(function()
|
||||
setValue(computeFn())
|
||||
end)
|
||||
return getValue;
|
||||
end
|
||||
|
||||
Reactive.clearEffectDependencies = function(effect)
|
||||
for _, dependency in ipairs(effect.dependencies) do
|
||||
for index, backlink in ipairs(dependency) do
|
||||
if (backlink == effect) then
|
||||
table.remove(dependency, index)
|
||||
end
|
||||
end
|
||||
end
|
||||
effect.dependencies = {};
|
||||
end
|
||||
|
||||
local Layout = {
|
||||
fromXML = function(text)
|
||||
local nodes = XMLParser.parseText(text)
|
||||
@@ -31,22 +98,9 @@ local registerFunctionEvent = function(object, event, script, env)
|
||||
end)
|
||||
end
|
||||
|
||||
local currentEffect = nil
|
||||
|
||||
local clearEffectDependencies = function(effect)
|
||||
for _, dependency in ipairs(effect.dependencies) do
|
||||
for index, backlink in ipairs(dependency) do
|
||||
if (backlink == effect) then
|
||||
table.remove(dependency, index)
|
||||
end
|
||||
end
|
||||
end
|
||||
effect.dependencies = {};
|
||||
end
|
||||
|
||||
return {
|
||||
basalt = function(basalt)
|
||||
local createObjectsFromXMLNode = function(node, env)
|
||||
local function createObjectsFromXMLNode(node, env)
|
||||
local layout = env[node.tag]
|
||||
if (layout ~= nil) then
|
||||
local props = {}
|
||||
@@ -55,12 +109,20 @@ return {
|
||||
end
|
||||
return basalt.createObjectsFromLayout(layout, props)
|
||||
end
|
||||
|
||||
local objectName = node.tag:gsub("^%l", string.upper)
|
||||
local object = basalt:createObject(objectName, node.attributes["id"])
|
||||
local object = basalt.createObject(objectName, node.attributes["id"])
|
||||
for attribute, expression in pairs(node.attributes) do
|
||||
if (attribute:sub(1, 2) == "on") then
|
||||
registerFunctionEvent(object, object[attribute], expression .. "()", env)
|
||||
object[attribute](object, function(...)
|
||||
local basaltCallback = basalt.getVariable(expression:gsub("\"", ""):gsub("\'", ""))
|
||||
if(basaltCallback ~= nil) then
|
||||
basaltCallback()
|
||||
elseif(env[expression] ~= nil) then
|
||||
env[expression]()
|
||||
else
|
||||
registerFunctionEvent(object, object[attribute], expression .. "()", env)
|
||||
end
|
||||
end)
|
||||
else
|
||||
local update = function()
|
||||
local value = load("return " .. expression, nil, "t", env)()
|
||||
@@ -70,7 +132,7 @@ return {
|
||||
end
|
||||
end
|
||||
for _, child in ipairs(node.children) do
|
||||
local childObjects = basalt.createObjectsFromXMLNode(child, env)
|
||||
local childObjects = createObjectsFromXMLNode(child, env)
|
||||
for _, childObject in ipairs(childObjects) do
|
||||
object:addChild(childObject)
|
||||
end
|
||||
@@ -79,57 +141,10 @@ return {
|
||||
end
|
||||
|
||||
local object = {
|
||||
reactive = function(initialValue)
|
||||
local value = initialValue
|
||||
local observerEffects = {}
|
||||
local get = function()
|
||||
if (currentEffect ~= nil) then
|
||||
table.insert(observerEffects, currentEffect)
|
||||
table.insert(currentEffect.dependencies, observerEffects)
|
||||
end
|
||||
return value
|
||||
end
|
||||
local set = function(newValue)
|
||||
value = newValue
|
||||
local observerEffectsCopy = {}
|
||||
for index, effect in ipairs(observerEffects) do
|
||||
observerEffectsCopy[index] = effect
|
||||
end
|
||||
for _, effect in ipairs(observerEffectsCopy) do
|
||||
effect.execute()
|
||||
end
|
||||
end
|
||||
return get, set
|
||||
end,
|
||||
|
||||
untracked = function(getter)
|
||||
local parentEffect = currentEffect
|
||||
currentEffect = nil
|
||||
local value = getter()
|
||||
currentEffect = parentEffect
|
||||
return value
|
||||
end,
|
||||
|
||||
effect = function(effectFn)
|
||||
local effect = {dependencies = {}}
|
||||
local execute = function()
|
||||
clearEffectDependencies(effect)
|
||||
local parentEffect = currentEffect
|
||||
currentEffect = effect
|
||||
effectFn()
|
||||
currentEffect = parentEffect
|
||||
end
|
||||
effect.execute = execute
|
||||
effect.execute()
|
||||
end,
|
||||
|
||||
derived = function(computeFn)
|
||||
local getValue, setValue = basalt.reactive();
|
||||
basalt.effect(function()
|
||||
setValue(computeFn())
|
||||
end)
|
||||
return getValue;
|
||||
end,
|
||||
observable = Reactive.observable,
|
||||
untracked = Reactive.untracked,
|
||||
effect = Reactive.effect,
|
||||
derived = Reactive.derived,
|
||||
|
||||
layout = function(path)
|
||||
if (not fs.exists(path)) then
|
||||
@@ -152,6 +167,9 @@ return {
|
||||
end
|
||||
setmetatable(env.props, {
|
||||
__index = function(_, k)
|
||||
if(updateFns[k] == nil) then
|
||||
error("Property " .. k .. " not found")
|
||||
end
|
||||
return updateFns[k]()
|
||||
end
|
||||
})
|
||||
@@ -189,8 +207,26 @@ return {
|
||||
self:addChild(object)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
loadLayoutFromString = function(self, xmlContent, props)
|
||||
local wrappedProps = {}
|
||||
if (props == nil) then
|
||||
props = {}
|
||||
end
|
||||
for prop, value in pairs(props) do
|
||||
wrappedProps[prop] = function()
|
||||
return value
|
||||
end
|
||||
end
|
||||
local layout = Layout.fromXML(xmlContent)
|
||||
local objects = basalt.createObjectsFromLayout(layout, wrappedProps)
|
||||
for _, object in ipairs(objects) do
|
||||
self:addChild(object)
|
||||
end
|
||||
return self
|
||||
end
|
||||
}
|
||||
return object
|
||||
end
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ plugin[v] = function(base, name, basalt)
|
||||
if(base.init(self))then
|
||||
local parent = self:getParent() or self
|
||||
self:setBackground(parent:getTheme(v.."BG"))
|
||||
self:setForeground(parent:getTheme(v.."Text"))
|
||||
self:setForeground(parent:getTheme(v.."Text"))
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,507 +0,0 @@
|
||||
-- This file is able to minify and create a single file out of a project folder
|
||||
-- only works for basalt
|
||||
|
||||
|
||||
|
||||
|
||||
-- The minify part is fully made by stravant and can be found here: https://github.com/stravant/LuaMinify/blob/master/RobloxPlugin/Minify.lua
|
||||
-- Thanks to him for his awesome work!
|
||||
|
||||
--
|
||||
-- Minify.lua
|
||||
--
|
||||
-- A compilation of all of the neccesary code to Minify a source file, all into one single
|
||||
-- script for usage on Roblox. Needed to deal with Roblox' lack of `require`.
|
||||
--
|
||||
|
||||
--The minify part is also minified, if you're looking for the packaging part, check out the bottom!
|
||||
function lookupify(cd)for dd,__a in pairs(cd)do cd[__a]=true end;return cd end
|
||||
function CountTable(cd)local dd=0;for __a in pairs(cd)do dd=dd+1 end;return dd end
|
||||
function PrintTable(cd,dd)if cd.Print then return cd.Print()end;dd=dd or 0
|
||||
local __a=(CountTable(cd)>1)local a_a=string.rep(' ',dd+1)
|
||||
local b_a="{".. (__a and'\n'or'')
|
||||
for c_a,d_a in pairs(cd)do
|
||||
if type(d_a)~='function'then
|
||||
b_a=b_a.. (__a and a_a or'')
|
||||
if type(c_a)=='number'then elseif type(c_a)=='string'and
|
||||
c_a:match("^[A-Za-z_][A-Za-z0-9_]*$")then b_a=b_a..c_a.." = "elseif
|
||||
type(c_a)=='string'then b_a=b_a.."[\""..c_a.."\"] = "else b_a=b_a.."["..
|
||||
tostring(c_a).."] = "end
|
||||
if type(d_a)=='string'then b_a=b_a.."\""..d_a.."\""elseif type(d_a)==
|
||||
'number'then b_a=b_a..d_a elseif type(d_a)=='table'then b_a=b_a..
|
||||
PrintTable(d_a,dd+ (__a and 1 or 0))else
|
||||
b_a=b_a..tostring(d_a)end;if next(cd,c_a)then b_a=b_a..","end;if __a then b_a=b_a..'\n'end end end;b_a=b_a..
|
||||
(__a and string.rep(' ',dd)or'').."}"return b_a end;local bb=lookupify{' ','\n','\t','\r'}
|
||||
local cb={['\r']='\\r',['\n']='\\n',['\t']='\\t',['"']='\\"',["'"]="\\'"}
|
||||
local db=lookupify{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
|
||||
local _c=lookupify{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
|
||||
local ac=lookupify{'0','1','2','3','4','5','6','7','8','9'}
|
||||
local bc=lookupify{'0','1','2','3','4','5','6','7','8','9','A','a','B','b','C','c','D','d','E','e','F','f'}
|
||||
local cc=lookupify{'+','-','*','/','^','%',',','{','}','[',']','(',')',';','#'}
|
||||
local dc=lookupify{'and','break','do','else','elseif','end','false','for','function','goto','if','in','local','nil','not','or','repeat','return','then','true','until','while'}
|
||||
function LexLua(cd)local dd={}
|
||||
local __a,a_a=pcall(function()local _aa=1;local aaa=1;local baa=1
|
||||
local function caa()local cba=cd:sub(_aa,_aa)if cba=='\n'then baa=1
|
||||
aaa=aaa+1 else baa=baa+1 end;_aa=_aa+1;return cba end
|
||||
local function daa(cba)cba=cba or 0;return cd:sub(_aa+cba,_aa+cba)end;local function _ba(cba)local dba=daa()
|
||||
for i=1,#cba do if dba==cba:sub(i,i)then return caa()end end end;local function aba(cba)
|
||||
return error(">> :"..aaa..":"..
|
||||
baa..": "..cba,0)end
|
||||
local function bba()local cba=_aa
|
||||
if daa()=='['then local dba=0;while
|
||||
daa(dba+1)=='='do dba=dba+1 end
|
||||
if daa(dba+1)=='['then for _=0,dba+1 do caa()end
|
||||
local _ca=_aa
|
||||
while true do if daa()==''then
|
||||
aba("Expected `]"..string.rep('=',dba).."]` near <eof>.",3)end;local cca=true;if daa()==']'then for i=1,dba do if daa(i)~='='then
|
||||
cca=false end end
|
||||
if daa(dba+1)~=']'then cca=false end else cca=false end;if cca then break else
|
||||
caa()end end;local aca=cd:sub(_ca,_aa-1)for i=0,dba+1 do caa()end
|
||||
local bca=cd:sub(cba,_aa-1)return aca,bca else return nil end else return nil end end
|
||||
while true do local cba=''
|
||||
while true do local dca=daa()
|
||||
if bb[dca]then cba=cba..caa()elseif
|
||||
dca=='-'and daa(1)=='-'then caa()caa()cba=cba..'--'local _da,ada=bba()
|
||||
if ada then cba=cba..ada else while daa()~='\n'and
|
||||
daa()~=''do cba=cba..caa()end end else break end end;local dba=aaa;local _ca=baa
|
||||
local aca=":"..aaa..":"..baa..":> "local bca=daa()local cca=nil
|
||||
if bca==''then cca={Type='Eof'}elseif
|
||||
_c[bca]or db[bca]or bca=='_'then local dca=_aa;repeat caa()bca=daa()until not
|
||||
(_c[bca]or db[bca]or ac[bca]or bca=='_')
|
||||
local _da=cd:sub(dca,_aa-1)
|
||||
if dc[_da]then cca={Type='Keyword',Data=_da}else cca={Type='Ident',Data=_da}end elseif ac[bca]or(daa()=='.'and ac[daa(1)])then local dca=_aa
|
||||
if bca=='0'and
|
||||
daa(1)=='x'then caa()caa()while bc[daa()]do caa()end;if _ba('Pp')then
|
||||
_ba('+-')while ac[daa()]do caa()end end else
|
||||
while ac[daa()]do caa()end;if _ba('.')then while ac[daa()]do caa()end end;if _ba('Ee')then
|
||||
_ba('+-')while ac[daa()]do caa()end end end;cca={Type='Number',Data=cd:sub(dca,_aa-1)}elseif bca=='\''or bca==
|
||||
'\"'then local dca=_aa;local _da=caa()local ada=_aa;while true do local dda=caa()
|
||||
if dda=='\\'then caa()elseif
|
||||
dda==_da then break elseif dda==''then aba("Unfinished string near <eof>")end end;local bda=cd:sub(ada,
|
||||
_aa-2)local cda=cd:sub(dca,_aa-1)
|
||||
cca={Type='String',Data=cda,Constant=bda}elseif bca=='['then local dca,_da=bba()
|
||||
if _da then cca={Type='String',Data=_da,Constant=dca}else
|
||||
caa()cca={Type='Symbol',Data='['}end elseif _ba('>=<')then if _ba('=')then cca={Type='Symbol',Data=bca..'='}else
|
||||
cca={Type='Symbol',Data=bca}end elseif _ba('~')then
|
||||
if _ba('=')then
|
||||
cca={Type='Symbol',Data='~='}else aba("Unexpected symbol `~` in source.",2)end elseif _ba('.')then
|
||||
if _ba('.')then if _ba('.')then cca={Type='Symbol',Data='...'}else
|
||||
cca={Type='Symbol',Data='..'}end else cca={Type='Symbol',Data='.'}end elseif _ba(':')then if _ba(':')then cca={Type='Symbol',Data='::'}else
|
||||
cca={Type='Symbol',Data=':'}end elseif cc[bca]then caa()
|
||||
cca={Type='Symbol',Data=bca}else local dca,_da=bba()if dca then cca={Type='String',Data=_da,Constant=dca}else
|
||||
aba("Unexpected Symbol `"..
|
||||
bca.."` in source.",2)end end;cca.LeadingWhite=cba;cca.Line=dba;cca.Char=_ca
|
||||
cca.Print=function()
|
||||
return"<".. (cca.Type..string.rep(' ',7 -#
|
||||
cca.Type))..
|
||||
" ".. (cca.Data or'').." >"end;dd[#dd+1]=cca;if cca.Type=='Eof'then break end end end)if not __a then return false,a_a end;local b_a={}local c_a={}local d_a=1
|
||||
function b_a:Peek(_aa)_aa=_aa or 0;return dd[math.min(
|
||||
#dd,d_a+_aa)]end
|
||||
function b_a:Get()local _aa=dd[d_a]d_a=math.min(d_a+1,#dd)return _aa end;function b_a:Is(_aa)return b_a:Peek().Type==_aa end;function b_a:Save()c_a[
|
||||
#c_a+1]=d_a end
|
||||
function b_a:Commit()c_a[#c_a]=nil end;function b_a:Restore()d_a=c_a[#c_a]c_a[#c_a]=nil end
|
||||
function b_a:ConsumeSymbol(_aa)
|
||||
local aaa=self:Peek()
|
||||
if aaa.Type=='Symbol'then if _aa then
|
||||
if aaa.Data==_aa then self:Get()return true else return nil end else self:Get()return aaa end else return
|
||||
nil end end
|
||||
function b_a:ConsumeKeyword(_aa)local aaa=self:Peek()if
|
||||
aaa.Type=='Keyword'and aaa.Data==_aa then self:Get()return true else return nil end end;function b_a:IsKeyword(_aa)local aaa=b_a:Peek()return
|
||||
aaa.Type=='Keyword'and aaa.Data==_aa end
|
||||
function b_a:IsSymbol(_aa)
|
||||
local aaa=b_a:Peek()return aaa.Type=='Symbol'and aaa.Data==_aa end
|
||||
function b_a:IsEof()return b_a:Peek().Type=='Eof'end;return true,b_a end
|
||||
function ParseLua(cd)local dd,__a=LexLua(cd)if not dd then return false,__a end
|
||||
local function a_a(ada)local bda=">> :"..
|
||||
|
||||
__a:Peek().Line..":"..__a:Peek().Char..": "..ada.."\n"local cda=0
|
||||
for dda in
|
||||
cd:gmatch("[^\n]*\n?")do if dda:sub(-1,-1)=='\n'then dda=dda:sub(1,-2)end;cda=
|
||||
cda+1
|
||||
if cda==__a:Peek().Line then bda=bda..">> `"..
|
||||
dda:gsub('\t',' ').."`\n"for i=1,__a:Peek().Char
|
||||
do local __b=dda:sub(i,i)
|
||||
if __b=='\t'then bda=bda..' 'else bda=bda..' 'end end
|
||||
bda=bda.." ^---"break end end;return bda end;local b_a=0;local c_a={}local d_a={'_','a','b','c','d'}
|
||||
local function _aa(ada)local bda={}bda.Parent=ada
|
||||
bda.LocalList={}bda.LocalMap={}
|
||||
function bda:RenameVars()
|
||||
for cda,dda in pairs(bda.LocalList)do local __b;b_a=0
|
||||
repeat b_a=b_a+1;local a_b=b_a
|
||||
__b=''while a_b>0 do local b_b=a_b%#d_a;a_b=(a_b-b_b)/#d_a
|
||||
__b=__b..d_a[b_b+1]end until
|
||||
not c_a[__b]and
|
||||
not ada:GetLocal(__b)and not bda.LocalMap[__b]dda.Name=__b;bda.LocalMap[__b]=dda end end
|
||||
function bda:GetLocal(cda)local dda=bda.LocalMap[cda]if dda then return dda end;if bda.Parent then
|
||||
local __b=bda.Parent:GetLocal(cda)if __b then return __b end end;return nil end
|
||||
function bda:CreateLocal(cda)local dda={}dda.Scope=bda;dda.Name=cda;dda.CanRename=true;bda.LocalList[#
|
||||
bda.LocalList+1]=dda
|
||||
bda.LocalMap[cda]=dda;return dda end;bda.Print=function()return"<Scope>"end;return bda end;local aaa;local baa
|
||||
local function caa(ada)local bda=_aa(ada)if not __a:ConsumeSymbol('(')then return false,
|
||||
a_a("`(` expected.")end;local cda={}local dda=false
|
||||
while not
|
||||
__a:ConsumeSymbol(')')do
|
||||
if __a:Is('Ident')then
|
||||
local c_b=bda:CreateLocal(__a:Get().Data)cda[#cda+1]=c_b;if not __a:ConsumeSymbol(',')then
|
||||
if
|
||||
__a:ConsumeSymbol(')')then break else return false,a_a("`)` expected.")end end elseif
|
||||
__a:ConsumeSymbol('...')then dda=true
|
||||
if not __a:ConsumeSymbol(')')then return false,
|
||||
a_a("`...` must be the last argument of a function.")end;break else return false,a_a("Argument name or `...` expected")end end;local __b,a_b=baa(bda)if not __b then return false,a_b end;if not
|
||||
__a:ConsumeKeyword('end')then
|
||||
return false,a_a("`end` expected after function body")end;local b_b={}
|
||||
b_b.AstType='Function'b_b.Scope=bda;b_b.Arguments=cda;b_b.Body=a_b;b_b.VarArg=dda;return true,b_b end
|
||||
local function daa(ada)
|
||||
if __a:ConsumeSymbol('(')then local bda,cda=aaa(ada)
|
||||
if not bda then return false,cda end
|
||||
if not __a:ConsumeSymbol(')')then return false,a_a("`)` Expected.")end;cda.ParenCount=(cda.ParenCount or 0)+1;return true,cda elseif
|
||||
__a:Is('Ident')then local bda=__a:Get()local cda=ada:GetLocal(bda.Data)if not cda then
|
||||
c_a[bda.Data]=true end;local dda={}dda.AstType='VarExpr'dda.Name=bda.Data
|
||||
dda.Local=cda;return true,dda else return false,a_a("primary expression expected")end end
|
||||
local function _ba(ada,bda)local cda,dda=daa(ada)if not cda then return false,dda end
|
||||
while true do
|
||||
if __a:IsSymbol('.')or
|
||||
__a:IsSymbol(':')then local __b=__a:Get().Data;if not __a:Is('Ident')then return false,
|
||||
a_a("<Ident> expected.")end;local a_b=__a:Get()
|
||||
local b_b={}b_b.AstType='MemberExpr'b_b.Base=dda;b_b.Indexer=__b;b_b.Ident=a_b;dda=b_b elseif not
|
||||
bda and __a:ConsumeSymbol('[')then local __b,a_b=aaa(ada)if not __b then
|
||||
return false,a_b end;if not __a:ConsumeSymbol(']')then
|
||||
return false,a_a("`]` expected.")end;local b_b={}b_b.AstType='IndexExpr'
|
||||
b_b.Base=dda;b_b.Index=a_b;dda=b_b elseif not bda and __a:ConsumeSymbol('(')then local __b={}
|
||||
while not
|
||||
__a:ConsumeSymbol(')')do local b_b,c_b=aaa(ada)if not b_b then return false,c_b end
|
||||
__b[#__b+1]=c_b
|
||||
if not __a:ConsumeSymbol(',')then if __a:ConsumeSymbol(')')then break else return false,
|
||||
a_a("`)` Expected.")end end end;local a_b={}a_b.AstType='CallExpr'a_b.Base=dda;a_b.Arguments=__b;dda=a_b elseif not bda and
|
||||
__a:Is('String')then local __b={}__b.AstType='StringCallExpr'__b.Base=dda
|
||||
__b.Arguments={__a:Get()}dda=__b elseif not bda and __a:IsSymbol('{')then local __b,a_b=aaa(ada)if not __b then
|
||||
return false,a_b end;local b_b={}b_b.AstType='TableCallExpr'b_b.Base=dda
|
||||
b_b.Arguments={a_b}dda=b_b else break end end;return true,dda end
|
||||
local function aba(ada)
|
||||
if __a:Is('Number')then local bda={}bda.AstType='NumberExpr'bda.Value=__a:Get()return
|
||||
true,bda elseif __a:Is('String')then local bda={}bda.AstType='StringExpr'
|
||||
bda.Value=__a:Get()return true,bda elseif __a:ConsumeKeyword('nil')then local bda={}bda.AstType='NilExpr'
|
||||
return true,bda elseif __a:IsKeyword('false')or __a:IsKeyword('true')then local bda={}
|
||||
bda.AstType='BooleanExpr'bda.Value=(__a:Get().Data=='true')return true,bda elseif
|
||||
__a:ConsumeSymbol('...')then local bda={}bda.AstType='DotsExpr'return true,bda elseif __a:ConsumeSymbol('{')then local bda={}
|
||||
bda.AstType='ConstructorExpr'bda.EntryList={}
|
||||
while true do
|
||||
if __a:IsSymbol('[')then __a:Get()local cda,dda=aaa(ada)
|
||||
if not cda then return
|
||||
false,a_a("Key Expression Expected")end
|
||||
if not __a:ConsumeSymbol(']')then return false,a_a("`]` Expected")end
|
||||
if not __a:ConsumeSymbol('=')then return false,a_a("`=` Expected")end;local __b,a_b=aaa(ada)if not __b then
|
||||
return false,a_a("Value Expression Expected")end
|
||||
bda.EntryList[#bda.EntryList+1]={Type='Key',Key=dda,Value=a_b}elseif __a:Is('Ident')then local cda=__a:Peek(1)
|
||||
if
|
||||
cda.Type=='Symbol'and cda.Data=='='then local dda=__a:Get()if not __a:ConsumeSymbol('=')then
|
||||
return false,a_a("`=` Expected")end;local __b,a_b=aaa(ada)if not __b then return false,
|
||||
a_a("Value Expression Expected")end
|
||||
bda.EntryList[
|
||||
#bda.EntryList+1]={Type='KeyString',Key=dda.Data,Value=a_b}else local dda,__b=aaa(ada)
|
||||
if not dda then return false,a_a("Value Exected")end
|
||||
bda.EntryList[#bda.EntryList+1]={Type='Value',Value=__b}end elseif __a:ConsumeSymbol('}')then break else local cda,dda=aaa(ada)
|
||||
bda.EntryList[#bda.EntryList+1]={Type='Value',Value=dda}if not cda then return false,a_a("Value Expected")end end
|
||||
if __a:ConsumeSymbol(';')or __a:ConsumeSymbol(',')then elseif
|
||||
__a:ConsumeSymbol('}')then break else return false,a_a("`}` or table entry Expected")end end;return true,bda elseif __a:ConsumeKeyword('function')then local bda,cda=caa(ada)if not bda then
|
||||
return false,cda end;cda.IsLocal=true;return true,cda else return _ba(ada)end end;local bba=lookupify{'-','not','#'}local cba=8
|
||||
local dba={['+']={6,6},['-']={6,6},['%']={7,7},['/']={7,7},['*']={7,7},['^']={10,9},['..']={5,4},['==']={3,3},['<']={3,3},['<=']={3,3},['~=']={3,3},['>']={3,3},['>=']={3,3},['and']={2,2},['or']={1,1}}
|
||||
local function _ca(ada,bda)local cda,dda
|
||||
if bba[__a:Peek().Data]then local __b=__a:Get().Data
|
||||
cda,dda=_ca(ada,cba)if not cda then return false,dda end;local a_b={}a_b.AstType='UnopExpr'
|
||||
a_b.Rhs=dda;a_b.Op=__b;dda=a_b else cda,dda=aba(ada)if not cda then return false,dda end end
|
||||
while true do local __b=dba[__a:Peek().Data]
|
||||
if __b and __b[1]>bda then
|
||||
local a_b=__a:Get().Data;local b_b,c_b=_ca(ada,__b[2])if not b_b then return false,c_b end;local d_b={}
|
||||
d_b.AstType='BinopExpr'd_b.Lhs=dda;d_b.Op=a_b;d_b.Rhs=c_b;dda=d_b else break end end;return true,dda end;aaa=function(ada)return _ca(ada,0)end
|
||||
local function aca(ada)local bda=nil
|
||||
if
|
||||
__a:ConsumeKeyword('if')then local cda={}cda.AstType='IfStatement'cda.Clauses={}
|
||||
repeat local dda,__b=aaa(ada)if not dda then
|
||||
return false,__b end;if not __a:ConsumeKeyword('then')then return false,
|
||||
a_a("`then` expected.")end
|
||||
local a_b,b_b=baa(ada)if not a_b then return false,b_b end
|
||||
cda.Clauses[#cda.Clauses+1]={Condition=__b,Body=b_b}until not __a:ConsumeKeyword('elseif')
|
||||
if __a:ConsumeKeyword('else')then local dda,__b=baa(ada)
|
||||
if not dda then return false,__b end;cda.Clauses[#cda.Clauses+1]={Body=__b}end;if not __a:ConsumeKeyword('end')then
|
||||
return false,a_a("`end` expected.")end;bda=cda elseif __a:ConsumeKeyword('while')then
|
||||
local cda={}cda.AstType='WhileStatement'local dda,__b=aaa(ada)
|
||||
if not dda then return false,__b end;if not __a:ConsumeKeyword('do')then
|
||||
return false,a_a("`do` expected.")end;local a_b,b_b=baa(ada)
|
||||
if not a_b then return false,b_b end;if not __a:ConsumeKeyword('end')then
|
||||
return false,a_a("`end` expected.")end;cda.Condition=__b;cda.Body=b_b;bda=cda elseif
|
||||
__a:ConsumeKeyword('do')then local cda,dda=baa(ada)if not cda then return false,dda end
|
||||
if not
|
||||
__a:ConsumeKeyword('end')then return false,a_a("`end` expected.")end;local __b={}__b.AstType='DoStatement'__b.Body=dda;bda=__b elseif
|
||||
__a:ConsumeKeyword('for')then
|
||||
if not __a:Is('Ident')then return false,a_a("<ident> expected.")end;local cda=__a:Get()
|
||||
if __a:ConsumeSymbol('=')then local dda=_aa(ada)
|
||||
local __b=dda:CreateLocal(cda.Data)local a_b,b_b=aaa(ada)if not a_b then return false,b_b end
|
||||
if not
|
||||
__a:ConsumeSymbol(',')then return false,a_a("`,` Expected")end;local c_b,d_b=aaa(ada)if not c_b then return false,d_b end;local _ab,aab
|
||||
if
|
||||
__a:ConsumeSymbol(',')then _ab,aab=aaa(ada)if not _ab then return false,aab end end;if not __a:ConsumeKeyword('do')then
|
||||
return false,a_a("`do` expected")end;local bab,cab=baa(dda)
|
||||
if not bab then return false,cab end;if not __a:ConsumeKeyword('end')then
|
||||
return false,a_a("`end` expected")end;local dab={}
|
||||
dab.AstType='NumericForStatement'dab.Scope=dda;dab.Variable=__b;dab.Start=b_b;dab.End=d_b;dab.Step=aab
|
||||
dab.Body=cab;bda=dab else local dda=_aa(ada)
|
||||
local __b={dda:CreateLocal(cda.Data)}
|
||||
while __a:ConsumeSymbol(',')do if not __a:Is('Ident')then return false,
|
||||
a_a("for variable expected.")end
|
||||
__b[#__b+1]=dda:CreateLocal(__a:Get().Data)end;if not __a:ConsumeKeyword('in')then
|
||||
return false,a_a("`in` expected.")end;local a_b={}local b_b,c_b=aaa(ada)if not b_b then
|
||||
return false,c_b end;a_b[#a_b+1]=c_b
|
||||
while __a:ConsumeSymbol(',')do
|
||||
local bab,cab=aaa(ada)if not bab then return false,cab end;a_b[#a_b+1]=cab end;if not __a:ConsumeKeyword('do')then
|
||||
return false,a_a("`do` expected.")end;local d_b,_ab=baa(dda)
|
||||
if not d_b then return false,_ab end;if not __a:ConsumeKeyword('end')then
|
||||
return false,a_a("`end` expected.")end;local aab={}
|
||||
aab.AstType='GenericForStatement'aab.Scope=dda;aab.VariableList=__b;aab.Generators=a_b;aab.Body=_ab;bda=aab end elseif __a:ConsumeKeyword('repeat')then local cda,dda=baa(ada)
|
||||
if not cda then return false,dda end;if not __a:ConsumeKeyword('until')then
|
||||
return false,a_a("`until` expected.")end;local __b,a_b=aaa(ada)
|
||||
if not __b then return false,a_b end;local b_b={}b_b.AstType='RepeatStatement'b_b.Condition=a_b;b_b.Body=dda;bda=b_b elseif
|
||||
__a:ConsumeKeyword('function')then if not __a:Is('Ident')then
|
||||
return false,a_a("Function name expected")end;local cda,dda=_ba(ada,true)if not cda then
|
||||
return false,dda end;local __b,a_b=caa(ada)if not __b then return false,a_b end
|
||||
a_b.IsLocal=false;a_b.Name=dda;bda=a_b elseif __a:ConsumeKeyword('local')then
|
||||
if __a:Is('Ident')then
|
||||
local cda={__a:Get().Data}while __a:ConsumeSymbol(',')do if not __a:Is('Ident')then return false,
|
||||
a_a("local var name expected")end
|
||||
cda[#cda+1]=__a:Get().Data end;local dda={}if
|
||||
__a:ConsumeSymbol('=')then
|
||||
repeat local a_b,b_b=aaa(ada)if not a_b then return false,b_b end
|
||||
dda[#dda+1]=b_b until not __a:ConsumeSymbol(',')end;for a_b,b_b in
|
||||
pairs(cda)do cda[a_b]=ada:CreateLocal(b_b)end
|
||||
local __b={}__b.AstType='LocalStatement'__b.LocalList=cda;__b.InitList=dda;bda=__b elseif
|
||||
__a:ConsumeKeyword('function')then if not __a:Is('Ident')then
|
||||
return false,a_a("Function name expected")end;local cda=__a:Get().Data
|
||||
local dda=ada:CreateLocal(cda)local __b,a_b=caa(ada)if not __b then return false,a_b end;a_b.Name=dda
|
||||
a_b.IsLocal=true;bda=a_b else
|
||||
return false,a_a("local var or function def expected")end elseif __a:ConsumeSymbol('::')then if not __a:Is('Ident')then return false,
|
||||
a_a('Label name expected')end
|
||||
local cda=__a:Get().Data
|
||||
if not __a:ConsumeSymbol('::')then return false,a_a("`::` expected")end;local dda={}dda.AstType='LabelStatement'dda.Label=cda;bda=dda elseif
|
||||
__a:ConsumeKeyword('return')then local cda={}
|
||||
if not __a:IsKeyword('end')then local __b,a_b=aaa(ada)
|
||||
if __b then cda[1]=a_b;while
|
||||
__a:ConsumeSymbol(',')do local b_b,c_b=aaa(ada)if not b_b then return false,c_b end
|
||||
cda[#cda+1]=c_b end end end;local dda={}dda.AstType='ReturnStatement'dda.Arguments=cda;bda=dda elseif
|
||||
__a:ConsumeKeyword('break')then local cda={}cda.AstType='BreakStatement'bda=cda elseif __a:IsKeyword('goto')then
|
||||
if not
|
||||
__a:Is('Ident')then return false,a_a("Label expected")end;local cda=__a:Get().Data;local dda={}dda.AstType='GotoStatement'
|
||||
dda.Label=cda;bda=dda else local cda,dda=_ba(ada)if not cda then return false,dda end
|
||||
if
|
||||
__a:IsSymbol(',')or __a:IsSymbol('=')then
|
||||
if(dda.ParenCount or 0)>0 then return false,
|
||||
a_a("Can not assign to parenthesized expression, is not an lvalue")end;local __b={dda}
|
||||
while __a:ConsumeSymbol(',')do local _ab,aab=_ba(ada)
|
||||
if not _ab then return false,aab end;__b[#__b+1]=aab end
|
||||
if not __a:ConsumeSymbol('=')then return false,a_a("`=` Expected.")end;local a_b={}local b_b,c_b=aaa(ada)if not b_b then return false,c_b end;a_b[1]=c_b;while
|
||||
__a:ConsumeSymbol(',')do local _ab,aab=aaa(ada)if not _ab then return false,aab end
|
||||
a_b[#a_b+1]=aab end;local d_b={}
|
||||
d_b.AstType='AssignmentStatement'd_b.Lhs=__b;d_b.Rhs=a_b;bda=d_b elseif
|
||||
dda.AstType=='CallExpr'or
|
||||
dda.AstType=='TableCallExpr'or dda.AstType=='StringCallExpr'then local __b={}__b.AstType='CallStatement'__b.Expression=dda;bda=__b else return false,
|
||||
a_a("Assignment Statement Expected")end end;bda.HasSemicolon=__a:ConsumeSymbol(';')return true,bda end
|
||||
local bca=lookupify{'end','else','elseif','until'}
|
||||
baa=function(ada)local bda={}bda.Scope=_aa(ada)bda.AstType='Statlist'local cda={}
|
||||
while not
|
||||
bca[__a:Peek().Data]and not __a:IsEof()do
|
||||
local dda,__b=aca(bda.Scope)if not dda then return false,__b end;cda[#cda+1]=__b end;bda.Body=cda;return true,bda end;local function cca()local ada=_aa()return baa(ada)end;local dca,_da=cca()
|
||||
return dca,_da end
|
||||
local _d=lookupify{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
|
||||
local ad=lookupify{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
|
||||
local bd=lookupify{'0','1','2','3','4','5','6','7','8','9'}
|
||||
function Format_Mini(cd)local dd,__a;local a_a=0
|
||||
local function b_a(d_a,_aa,aaa)
|
||||
if a_a>150 then a_a=0;return d_a.."\n".._aa end;aaa=aaa or' 'local baa,caa=d_a:sub(-1,-1),_aa:sub(1,1)
|
||||
if
|
||||
ad[baa]or _d[baa]or baa=='_'then
|
||||
if not
|
||||
(ad[caa]or _d[caa]or caa=='_'or bd[caa])then return d_a.._aa elseif caa=='('then
|
||||
return d_a..aaa.._aa else return d_a..aaa.._aa end elseif bd[baa]then
|
||||
if caa=='('then return d_a.._aa else return d_a..aaa.._aa end elseif baa==''then return d_a.._aa else
|
||||
if caa=='('then return d_a..aaa.._aa else return d_a.._aa end end end
|
||||
__a=function(d_a)local _aa=string.rep('(',d_a.ParenCount or 0)
|
||||
if
|
||||
d_a.AstType=='VarExpr'then if d_a.Local then _aa=_aa..d_a.Local.Name else
|
||||
_aa=_aa..d_a.Name end elseif d_a.AstType=='NumberExpr'then _aa=_aa..
|
||||
d_a.Value.Data elseif d_a.AstType=='StringExpr'then
|
||||
_aa=_aa..d_a.Value.Data elseif d_a.AstType=='BooleanExpr'then _aa=_aa..tostring(d_a.Value)elseif
|
||||
d_a.AstType=='NilExpr'then _aa=b_a(_aa,"nil")elseif d_a.AstType=='BinopExpr'then
|
||||
_aa=b_a(_aa,__a(d_a.Lhs))_aa=b_a(_aa,d_a.Op)_aa=b_a(_aa,__a(d_a.Rhs))elseif d_a.AstType==
|
||||
'UnopExpr'then _aa=b_a(_aa,d_a.Op)
|
||||
_aa=b_a(_aa,__a(d_a.Rhs))elseif d_a.AstType=='DotsExpr'then _aa=_aa.."..."elseif d_a.AstType=='CallExpr'then _aa=_aa..
|
||||
__a(d_a.Base)_aa=_aa.."("for i=1,#d_a.Arguments do _aa=_aa..
|
||||
__a(d_a.Arguments[i])
|
||||
if i~=#d_a.Arguments then _aa=_aa..","end end;_aa=_aa..")"elseif d_a.AstType==
|
||||
'TableCallExpr'then _aa=_aa..__a(d_a.Base)_aa=_aa..
|
||||
__a(d_a.Arguments[1])elseif d_a.AstType=='StringCallExpr'then
|
||||
_aa=_aa..__a(d_a.Base)_aa=_aa..d_a.Arguments[1].Data elseif
|
||||
d_a.AstType=='IndexExpr'then
|
||||
_aa=_aa..__a(d_a.Base).."["..__a(d_a.Index).."]"elseif d_a.AstType=='MemberExpr'then _aa=_aa..__a(d_a.Base)..
|
||||
d_a.Indexer..d_a.Ident.Data elseif
|
||||
d_a.AstType=='Function'then d_a.Scope:RenameVars()
|
||||
_aa=_aa.."function("
|
||||
if#d_a.Arguments>0 then for i=1,#d_a.Arguments do
|
||||
_aa=_aa..d_a.Arguments[i].Name
|
||||
if i~=#d_a.Arguments then _aa=_aa..","elseif d_a.VarArg then _aa=_aa..",..."end end elseif
|
||||
d_a.VarArg then _aa=_aa.."..."end;_aa=_aa..")"_aa=b_a(_aa,dd(d_a.Body))
|
||||
_aa=b_a(_aa,"end")elseif d_a.AstType=='ConstructorExpr'then _aa=_aa.."{"
|
||||
for i=1,#d_a.EntryList do
|
||||
local aaa=d_a.EntryList[i]
|
||||
if aaa.Type=='Key'then _aa=_aa.."["..
|
||||
__a(aaa.Key).."]="..__a(aaa.Value)elseif aaa.Type==
|
||||
'Value'then _aa=_aa..__a(aaa.Value)elseif aaa.Type=='KeyString'then
|
||||
_aa=_aa..
|
||||
aaa.Key.."="..__a(aaa.Value)end;if i~=#d_a.EntryList then _aa=_aa..","end end;_aa=_aa.."}"end
|
||||
_aa=_aa..string.rep(')',d_a.ParenCount or 0)a_a=a_a+#_aa;return _aa end
|
||||
local c_a=function(d_a)local _aa=''
|
||||
if d_a.AstType=='AssignmentStatement'then
|
||||
for i=1,#d_a.Lhs do
|
||||
_aa=_aa..__a(d_a.Lhs[i])if i~=#d_a.Lhs then _aa=_aa..","end end;if#d_a.Rhs>0 then _aa=_aa.."="
|
||||
for i=1,#d_a.Rhs do
|
||||
_aa=_aa..__a(d_a.Rhs[i])if i~=#d_a.Rhs then _aa=_aa..","end end end elseif
|
||||
d_a.AstType=='CallStatement'then _aa=__a(d_a.Expression)elseif d_a.AstType=='LocalStatement'then
|
||||
_aa=_aa.."local "
|
||||
for i=1,#d_a.LocalList do _aa=_aa..d_a.LocalList[i].Name;if i~=#
|
||||
d_a.LocalList then _aa=_aa..","end end
|
||||
if#d_a.InitList>0 then _aa=_aa.."="for i=1,#d_a.InitList do _aa=_aa..
|
||||
__a(d_a.InitList[i])
|
||||
if i~=#d_a.InitList then _aa=_aa..","end end end elseif d_a.AstType=='IfStatement'then
|
||||
_aa=b_a("if",__a(d_a.Clauses[1].Condition))_aa=b_a(_aa,"then")
|
||||
_aa=b_a(_aa,dd(d_a.Clauses[1].Body))
|
||||
for i=2,#d_a.Clauses do local aaa=d_a.Clauses[i]
|
||||
if aaa.Condition then
|
||||
_aa=b_a(_aa,"elseif")_aa=b_a(_aa,__a(aaa.Condition))
|
||||
_aa=b_a(_aa,"then")else _aa=b_a(_aa,"else")end;_aa=b_a(_aa,dd(aaa.Body))end;_aa=b_a(_aa,"end")elseif d_a.AstType=='WhileStatement'then
|
||||
_aa=b_a("while",__a(d_a.Condition))_aa=b_a(_aa,"do")_aa=b_a(_aa,dd(d_a.Body))
|
||||
_aa=b_a(_aa,"end")elseif d_a.AstType=='DoStatement'then _aa=b_a(_aa,"do")
|
||||
_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"end")elseif d_a.AstType=='ReturnStatement'then _aa="return"
|
||||
for i=1,#d_a.Arguments
|
||||
do _aa=b_a(_aa,__a(d_a.Arguments[i]))if i~=
|
||||
#d_a.Arguments then _aa=_aa..","end end elseif d_a.AstType=='BreakStatement'then _aa="break"elseif d_a.AstType=='RepeatStatement'then
|
||||
_aa="repeat"_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"until")
|
||||
_aa=b_a(_aa,__a(d_a.Condition))elseif d_a.AstType=='Function'then d_a.Scope:RenameVars()if d_a.IsLocal then
|
||||
_aa="local"end;_aa=b_a(_aa,"function ")if d_a.IsLocal then
|
||||
_aa=_aa..d_a.Name.Name else _aa=_aa..__a(d_a.Name)end;_aa=
|
||||
_aa.."("
|
||||
if#d_a.Arguments>0 then
|
||||
for i=1,#d_a.Arguments do _aa=_aa..
|
||||
d_a.Arguments[i].Name;if i~=#d_a.Arguments then _aa=_aa..","elseif d_a.VarArg then
|
||||
_aa=_aa..",..."end end elseif d_a.VarArg then _aa=_aa.."..."end;_aa=_aa..")"_aa=b_a(_aa,dd(d_a.Body))
|
||||
_aa=b_a(_aa,"end")elseif d_a.AstType=='GenericForStatement'then d_a.Scope:RenameVars()
|
||||
_aa="for "
|
||||
for i=1,#d_a.VariableList do
|
||||
_aa=_aa..d_a.VariableList[i].Name;if i~=#d_a.VariableList then _aa=_aa..","end end;_aa=_aa.." in"
|
||||
for i=1,#d_a.Generators do
|
||||
_aa=b_a(_aa,__a(d_a.Generators[i]))if i~=#d_a.Generators then _aa=b_a(_aa,',')end end;_aa=b_a(_aa,"do")_aa=b_a(_aa,dd(d_a.Body))
|
||||
_aa=b_a(_aa,"end")elseif d_a.AstType=='NumericForStatement'then _aa="for "_aa=_aa..
|
||||
d_a.Variable.Name.."="_aa=_aa..
|
||||
__a(d_a.Start)..","..__a(d_a.End)if d_a.Step then
|
||||
_aa=_aa..","..__a(d_a.Step)end;_aa=b_a(_aa,"do")
|
||||
_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"end")end;a_a=a_a+#_aa;return _aa end
|
||||
dd=function(d_a)local _aa=''d_a.Scope:RenameVars()for aaa,baa in pairs(d_a.Body)do
|
||||
_aa=b_a(_aa,c_a(baa),';')end;return _aa end;cd.Scope:RenameVars()return dd(cd)end
|
||||
local minify = function(cd)local dd,__a=ParseLua(cd)if not dd then return false,__a end
|
||||
return true,Format_Mini(__a)end
|
||||
|
||||
-- Packaging part:
|
||||
local args = table.pack(...)
|
||||
local projectPath = args[1] or "Basalt"
|
||||
local minifyProject = args[2]=="true" and true or false
|
||||
local outputFileName = args[3] or "basalt.lua"
|
||||
|
||||
assert(fs.isDir(projectPath), "Unable to find directory: "..projectPath)
|
||||
|
||||
local projectFiles = {
|
||||
"objects",
|
||||
"libraries",
|
||||
"Frame.lua",
|
||||
"loadObjects.lua",
|
||||
"Object.lua",
|
||||
"theme.lua",
|
||||
}
|
||||
local subDirs = {
|
||||
"objects", "libraries"
|
||||
}
|
||||
local mainFile = "main.lua"
|
||||
|
||||
local outputFile = io.open(outputFileName, "w")
|
||||
|
||||
if(outputFile==nil)then
|
||||
error("Can't open file "..outputFileName)
|
||||
end
|
||||
|
||||
outputFile:write([[
|
||||
local project = {}
|
||||
local packaged = true
|
||||
local baseRequire = require
|
||||
local require = function(path)
|
||||
for _,v in pairs(project)do
|
||||
for name,b in pairs(v)do
|
||||
if(name==path)then
|
||||
return b()
|
||||
end
|
||||
end
|
||||
end
|
||||
return baseRequire(path);
|
||||
end
|
||||
local getProject = function(subDir)
|
||||
if(subDir~=nil)then
|
||||
return project[subDir]
|
||||
end
|
||||
return project
|
||||
end
|
||||
]])
|
||||
|
||||
for k,v in pairs(subDirs)do
|
||||
outputFile:write("project['"..v.."'] = {}")
|
||||
end
|
||||
outputFile:write("project['default'] = {}")
|
||||
|
||||
local function writeNewPackage(subdir, name, path)
|
||||
if not(fs.isDir(path))then
|
||||
outputFile:write("project['"..subdir.."']['"..name.."'] = ".."function(...)")
|
||||
local file = io.open(path, "r")
|
||||
local fileData = file:read("*all")
|
||||
if(minifyProject)then
|
||||
local success, data = minify(fileData)
|
||||
if(success)then
|
||||
outputFile:write(data:gsub("]]", "] ]"):gsub("]]", "] ]").."\n")
|
||||
else
|
||||
print("Error: Can't minify "..path)
|
||||
end
|
||||
else
|
||||
outputFile:write(fileData:gsub("]]", "] ]"):gsub("]]", "] ]").."\n")
|
||||
end
|
||||
file:close()
|
||||
outputFile:write("end; \n")
|
||||
end
|
||||
end
|
||||
|
||||
for _,v in pairs(projectFiles)do
|
||||
if(fs.isDir(fs.combine(projectPath, v)))then
|
||||
for _,b in pairs(fs.list(fs.combine(projectPath, v)))do
|
||||
writeNewPackage(v, b:gsub(".lua", ""), fs.combine(fs.combine(projectPath, v), b))
|
||||
end
|
||||
else
|
||||
writeNewPackage("default", v:gsub(".lua", ""), fs.combine(projectPath, v))
|
||||
end
|
||||
end
|
||||
|
||||
local main = io.open(fs.combine(projectPath, mainFile), "r")
|
||||
local mainData = main:read("*all")
|
||||
if(minifyProject)then
|
||||
local success,data = minify(mainData)
|
||||
if(success)then
|
||||
outputFile:write(data)
|
||||
else
|
||||
print("Error: Can't minify "..fs.combine(projectPath, mainFile).." "..data)
|
||||
end
|
||||
else
|
||||
outputFile:write(mainData)
|
||||
end
|
||||
main:close()
|
||||
outputFile:close()
|
||||
@@ -1 +0,0 @@
|
||||
basalt.madefor.cc
|
||||
@@ -1,3 +1,3 @@
|
||||
---
|
||||
|
||||
Thanks for checking out our wiki, join our discord for more help: [discord.gg/yM7kndJdJJ](discord.gg/yNNnmBVBpE)
|
||||
Thanks for checking out our wiki, join our discord for more help: [https://discord.gg/yM7kndJdJJ](discord.gg/yNNnmBVBpE)
|
||||
|
||||
BIN
docs/_media/flexbox-example.png
Normal file
BIN
docs/_media/flexbox-example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
docs/_media/flexgrow-property.mp4
Normal file
BIN
docs/_media/flexgrow-property.mp4
Normal file
Binary file not shown.
BIN
docs/_media/frame-flexgrow-property.mp4
Normal file
BIN
docs/_media/frame-flexgrow-property.mp4
Normal file
Binary file not shown.
@@ -37,5 +37,4 @@
|
||||
- [Timer](objects/Timer.md)
|
||||
- Guides
|
||||
- [Introduction to Basalt](guides/introduction.md)
|
||||
- [Dynamic Values](guides/dynamicvalues.md)
|
||||
- [XML](guides/xml.md)
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
## setTheme
|
||||
|
||||
Sets the base theme of the project! Make sure to cover all existing objects, otherwise it will result in errors. A good example is [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua). The theme can also be gotten with [`basalt.getTheme()`](objects/Basalt/getTheme)
|
||||
Sets the base theme of the project! Make sure to cover all existing objects, otherwise it will result in errors. A good example is [theme](https://github.com/Pyroxenium/Basalt/blob/bb1b1beb795e3cf06a84ca79408244bca715961e/Basalt/theme.lua). The theme can also be gotten with [`basalt.getTheme()`](objects/Basalt/getTheme)
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for a example
|
||||
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/bb1b1beb795e3cf06a84ca79408244bca715961e/Basalt/theme.lua) for a example
|
||||
|
||||
### Usage
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
## setTheme
|
||||
|
||||
Sets the default theme, of that frame children objects always try to get the theme of its parent frame, if it does not exist it goes to its parent parent frame, and so on until it reaches the basalt manager's theme - which is stored in theme.lua (Please checkout [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for how it could look like.
|
||||
Sets the default theme, of that frame children objects always try to get the theme of its parent frame, if it does not exist it goes to its parent parent frame, and so on until it reaches the basalt manager's theme - which is stored in theme.lua (Please checkout [theme](https://github.com/Pyroxenium/Basalt/blob/bb1b1beb795e3cf06a84ca79408244bca715961e/Basalt/theme.lua) for how it could look like.
|
||||
|
||||
#### Parameters:
|
||||
|
||||
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for a example
|
||||
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/bb1b1beb795e3cf06a84ca79408244bca715961e/Basalt/theme.lua) for a example
|
||||
|
||||
#### Returns:
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ Dynamic Values provide a way to define the size and position of UI elements in a
|
||||
|
||||
### Basic Syntax
|
||||
|
||||
Dynamic Values are defined using expressions enclosed in double quotes (" "). These expressions can include arithmetic operations, as well as references to properties of other UI elements, such as their width or height.
|
||||
Dynamic Values are defined by using expressions enclosed within double quotes (" ") and curly braces ({ }). These expressions can include arithmetic operations, as well as references to properties of other UI elements, such as their width or height.
|
||||
|
||||
Here's an example of a simple Dynamic Value expression:
|
||||
|
||||
```lua
|
||||
"parent.w / 2"
|
||||
"{parent.w / 2}"
|
||||
```
|
||||
|
||||
This expression calculates half of the parent container's width.
|
||||
@@ -20,7 +20,7 @@ Here's an example of how to use Dynamic Values to set the size of a frame:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local childFrame = mainFrame:addFrame():setSize("parent.w / 2", "parent.h / 2")
|
||||
local childFrame = mainFrame:addFrame():setSize("{parent.w / 2}", "{parent.h / 2}")
|
||||
```
|
||||
|
||||
In this example, the child frame's size is set to half of the parent frame's width and height.
|
||||
@@ -33,7 +33,7 @@ Here's an example of how to do this:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local childFrame = mainFrame:addFrame():setSize("parent.w / 2", 10)
|
||||
local childFrame = mainFrame:addFrame():setSize("{parent.w / 2}", 10)
|
||||
```
|
||||
|
||||
In this example, the child frame's width is set to half of the parent frame's width, while its height is set to a static value of 100 pixels.
|
||||
@@ -62,10 +62,10 @@ local main = basalt.createFrame()
|
||||
local childFrame = main:addFrame()
|
||||
|
||||
-- Set the size of the child frame to half the width and height of its parent frame
|
||||
childFrame:setSize("parent.w / 2", "parent.h / 2")
|
||||
childFrame:setSize("{parent.w / 2}", "parent.h / 2}")
|
||||
|
||||
-- Position the child frame at the center of its parent frame
|
||||
childFrame:setPosition("parent.w / 2 - self.w / 2", "parent.h / 2 - self.h / 2")
|
||||
childFrame:setPosition("{parent.w / 2 - self.w / 2}", "{parent.h / 2 - self.h / 2}")
|
||||
```
|
||||
|
||||
In this example, the child frame's size and position are dynamically calculated based on the parent frame's dimensions, ensuring a responsive layout that adapts to changes in the parent frame's size.
|
||||
@@ -78,7 +78,7 @@ local frameA = main:addFrame("frameA"):setSize(20, 20)
|
||||
local frameB = main:addFrame("frameB"):setSize(10, 10)
|
||||
|
||||
-- Position frameB to the right of frameA
|
||||
frameB:setPosition("frameA.x + frameA.w + 2", "frameA.y")
|
||||
frameB:setPosition("{frameA.x + frameA.w + 2}", "{frameA.y}")
|
||||
```
|
||||
|
||||
### Using Math Functions with Dynamic Values
|
||||
@@ -88,7 +88,7 @@ In addition to basic arithmetic operations, you can also use functions from the
|
||||
For example, you can use the `math.floor()` function to round down the result of a division operation:
|
||||
|
||||
```lua
|
||||
"math.floor(parent.w / 2)"
|
||||
"{math.floor(parent.w / 2)}"
|
||||
```
|
||||
|
||||
This expression calculates half of the parent container's width and rounds the result down to the nearest integer.
|
||||
@@ -97,7 +97,35 @@ Here's an example of how to use a Math function within a Dynamic Value expressio
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local childFrame = mainFrame:addFrame():setSize("math.floor(parent.w / 3)", "math.ceil(parent.h / 4)")
|
||||
local childFrame = mainFrame:addFrame():setSize("{math.floor(parent.w / 3)}", "{math.ceil(parent.h / 4)}")
|
||||
```
|
||||
|
||||
In this example, the child frame's width is set to one-third of the parent frame's width, rounded down to the nearest integer, and its height is set to one-fourth of the parent frame's height, rounded up to the nearest integer.
|
||||
|
||||
### Manipulating Background and Foreground Dynamically
|
||||
|
||||
With Dynamic Values, you can also manipulate the background and foreground color of your UI elements depending on certain conditions. This provides a way to give visual feedback to user interactions or state changes in the application.
|
||||
|
||||
Here's an example on how you can use Dynamic Values to change the background color of a UI element based on its clicked state:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local button = mainFrame:addButton():setBackground("{self.clicked ? blue : green}")
|
||||
```
|
||||
|
||||
In this example, the `setBackground` method is used with a Dynamic Value expression to change the background color of a button. The color is 'blue' when the button is clicked (`self.clicked` is true), and 'green' when it's not clicked (`self.clicked` is false).
|
||||
|
||||
Just like with sizes and positions, you can use the self keyword to refer to the current UI element. The clicked attribute is a boolean that indicates whether the UI element has been clicked or not.
|
||||
|
||||
The Dynamic Value expression for color uses a ternary operator, which takes the form of `condition ? value_if_true : value_if_false`. This allows you to specify different colors depending on whether the condition (in this case, `self.clicked`) is true or false.
|
||||
|
||||
The same approach can be used to change the foreground color, text properties, or any other attributes of a UI element. Just remember to use the correct method for the attribute you want to change, and to format your Dynamic Value expression appropriately.
|
||||
|
||||
Here's an example of changing the foreground color:
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local button = mainFrame:addButton():setForeground("{self.clicked ? white : black}")
|
||||
```
|
||||
|
||||
In this example, the button's text color is 'white' when clicked and 'black' when not clicked. This helps provide visual feedback to the user about the button's state.
|
||||
|
||||
@@ -89,23 +89,23 @@ This layout can be passed props like any other object in the layout, as seen in
|
||||
|
||||
## Reactivity (BETA)
|
||||
|
||||
Reacting to user input is easier than ever with Basalt XML's concept of reactive values and observers for said values. This powerful feature allows for properties to be derived automatically from reactive values, without needing the programmer to manually call functions to update the object.
|
||||
Reacting to user input is easier than ever with Basalt XML's concept of observable values and observers for said values. This powerful feature allows for properties to be updated automatically from observable values, without needing the programmer to manually call functions to update the object.
|
||||
|
||||
To create a reactive value, simply use the `basalt.reactive(initialValue)` function, which returns getter and setter functions. For example:
|
||||
To create an observable value, simply use the `basalt.observable(initialValue)` function, which returns getter and setter functions. For example:
|
||||
|
||||
```xml
|
||||
<script>
|
||||
local basalt = require("basalt")
|
||||
getTimesClicked, setTimesClicked = basalt.reactive(0)
|
||||
getTimesClicked, setTimesClicked = basalt.observable(0)
|
||||
</script>
|
||||
```
|
||||
|
||||
You could then hook up this reactive value to a property.
|
||||
You could then hook up this observable value to a property.
|
||||
|
||||
```xml
|
||||
<script>
|
||||
local basalt = require("basalt")
|
||||
getTimesClicked, setTimesClicked = basalt.reactive(0)
|
||||
getTimesClicked, setTimesClicked = basalt.observable(0)
|
||||
</script>
|
||||
|
||||
<button text={"Times clicked: " .. getTimesClicked()} />
|
||||
@@ -116,7 +116,7 @@ This subscribes the button text to the value of times clicked. If this value is
|
||||
```xml
|
||||
<script>
|
||||
local basalt = require("basalt")
|
||||
getTimesClicked, setTimesClicked = basalt.reactive(0)
|
||||
getTimesClicked, setTimesClicked = basalt.observable(0)
|
||||
onClick = function()
|
||||
setTimesClicked(getTimesClicked() + 1)
|
||||
end
|
||||
@@ -129,16 +129,16 @@ Voila. You now have a button that displays the number of times it's been clicked
|
||||
|
||||
# Effects
|
||||
|
||||
In addition to reactive values, there are effects that are triggered by them. You can think about it like this: reactive values produce updates, while effects detect them and do something in response.
|
||||
In addition to observable values, there are effects that are triggered by them. You can think about it like this: observable values produce updates, while effects detect them and do something in response.
|
||||
|
||||
Effects are created using the `basalt.effect(function)` function. Any reactive values that are accessed during the effect's execution are automatically subscribed to, and the effect will re-run in response to updates to these values.
|
||||
Effects are created using the `basalt.effect(function)` function. Any observable values that are accessed during the effect's execution are automatically subscribed to, and the effect will re-run in response to updates to these values.
|
||||
|
||||
For example, you could create an effect that writes a message to the logs whenever the times clicked updates:
|
||||
|
||||
```xml
|
||||
<script>
|
||||
local basalt = require("basalt")
|
||||
getTimesClicked, setTimesClicked = basalt.reactive(0)
|
||||
getTimesClicked, setTimesClicked = basalt.observable(0)
|
||||
onClick = function()
|
||||
setTimesClicked(getTimesClicked() + 1)
|
||||
end
|
||||
@@ -150,20 +150,20 @@ For example, you could create an effect that writes a message to the logs whenev
|
||||
<button text={"Times clicked: " .. getTimesClicked()} onClick={onClick} />
|
||||
```
|
||||
|
||||
In fact, props are internally implemented using effects! Effects that set the corresponding property in the object to the new reactive value.
|
||||
In fact, props are internally implemented using effects! Effects that set the corresponding property in the object to the new observable value.
|
||||
|
||||
# Derived values
|
||||
|
||||
If reactive values are the source of truth, derived values can be thought of as a dependency that uses them and transforms them. Similarly to effects, they also update whenever the reactive values they observe update.
|
||||
If observable values are the source of truth, derived values can be thought of as a dependency that uses them and transforms them. Similarly to effects, they also update whenever the observable values they observe update.
|
||||
|
||||
To create a derived value, use the `basalt.derived(function)` function, which returns a getter function for the value. Any effect observing this derived value will update if the derived value updates, which itself updates in response to a source reactive value updating, in a chain reaction.
|
||||
To create a derived value, use the `basalt.derived(function)` function, which returns a getter function for the value. Any effect observing this derived value will update if the derived value updates, which itself updates in response to a source observable value updating, in a chain reaction.
|
||||
|
||||
The above button example could be rewritten as:
|
||||
|
||||
```xml
|
||||
<script>
|
||||
local basalt = require("basalt")
|
||||
getTimesClicked, setTimesClicked = basalt.reactive(0)
|
||||
getTimesClicked, setTimesClicked = basalt.observable(0)
|
||||
onClick = function()
|
||||
setTimesClicked(getTimesClicked() + 1)
|
||||
end
|
||||
@@ -175,14 +175,14 @@ The above button example could be rewritten as:
|
||||
<button text={getButtonText()} onClick={onClick} />
|
||||
```
|
||||
|
||||
# Untracked reactive value access
|
||||
# Untracked observable value access
|
||||
|
||||
Sometimes you might want to use a reactive value in an unreactive way. Perhaps you would like a property to be computed based on it only once, never updating afterwards. This can be accomplished using the `basalt.untracked(function)` function:
|
||||
Sometimes you might want to use a observable value without subscribing to updates. Perhaps you would like a property to be computed based on it only once, never updating afterwards. This can be accomplished using the `basalt.untracked(function)` function:
|
||||
|
||||
```xml
|
||||
<script>
|
||||
basalt = require("basalt")
|
||||
getTimesClicked, setTimesClicked = basalt.reactive(0)
|
||||
getTimesClicked, setTimesClicked = basalt.observable(0)
|
||||
onClick = function()
|
||||
setTimesClicked(getTimesClicked() + 1)
|
||||
end
|
||||
|
||||
@@ -6,11 +6,11 @@ The Release version provides a specific, stable version of Basalt. Use this vers
|
||||
|
||||
To download the Release version, use the following command:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua release [remote_filename] [local_filename]`
|
||||
`wget run https://raw.githubusercontent.com/Pyroxenium/Basalt/refs/heads/master/docs/install.lua release [remote_filename] [local_filename]`
|
||||
|
||||
In most cases, you'll likely want to use:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua release latest.lua`
|
||||
`wget run https://raw.githubusercontent.com/Pyroxenium/Basalt/refs/heads/master/docs/install.lua release latest.lua`
|
||||
|
||||
- `remote_filename`: The file name of the Basalt release you want to download (e.g., basalt-1.6.6.lua, latest.lua).
|
||||
- `local_filename` (optional): The file name for the Basalt installation on your local system (e.g., basalt.lua).
|
||||
@@ -23,7 +23,7 @@ The Minified/Packed version is a compressed version of the Basalt code directly
|
||||
|
||||
To download the Minified/Packed version, use the following command:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua packed [filename] [branch]`
|
||||
`wget run https://raw.githubusercontent.com/Pyroxenium/Basalt/refs/heads/master/docs/install.lua packed [filename] [branch]`
|
||||
|
||||
- `filename` (optional): The file name for the Basalt installation (default: `basalt.lua`).
|
||||
- `branch` (optional): Choose between `master` and `dev` branches (default: `master`).
|
||||
@@ -34,7 +34,7 @@ The Source version, as the name suggests, contains the unmodified source code of
|
||||
|
||||
To download the Source version, use the following command:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua source [foldername] [branch]`
|
||||
`wget run https://raw.githubusercontent.com/Pyroxenium/Basalt/refs/heads/master/docs/install.lua source [foldername] [branch]`
|
||||
|
||||
- `foldername` (optional): The folder name for the Basalt installation (default: `basalt`).
|
||||
- `branch` (optional): Choose between `master` and `dev` branches (default: `master`).
|
||||
@@ -45,9 +45,9 @@ The Web version is designed for minimal project size and fetches the required co
|
||||
|
||||
To download the Web version, use the following command:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua web [version] [filename]`
|
||||
`wget run https://raw.githubusercontent.com/Pyroxenium/Basalt/refs/heads/master/docs/install.lua web [version] [filename]`
|
||||
|
||||
- `version` (optional): Specify the desired version of Basalt (default: latest version). [Click here](https://github.com/Pyroxenium/Basalt/tree/master/docs/versions) to see the available versions.
|
||||
- `filename` (optional): The file name for the Basalt installation (default: `basaltWeb.lua`).
|
||||
|
||||
**Note**: If using the Web version, remember to change `local basalt = require("basalt")` to `local basalt = require("basaltWeb")` in your code.
|
||||
**Note**: If using the Web version, remember to change `local basalt = require("basalt")` to `local basalt = require("basaltWeb")` in your code.
|
||||
|
||||
@@ -21,7 +21,7 @@ You are now able to access the following list of methods:
|
||||
|[getVersion](objects/Basalt/getVersion.md)|Returns the Basalt version
|
||||
|[isKeyDown](objects/Basalt/isKeyDown.md)|Returns if the key is held down
|
||||
|[log](objects/Basalt/log.md)|Writes something into the log file
|
||||
|[memory](objects/Basalt/log.md)|Returns the current memory usage of Basalt
|
||||
|[memory](objects/Basalt/memory.md)|Returns the current memory usage of Basalt
|
||||
|[onEvent](objects/Basalt/onEvent.md)|Event listener
|
||||
|[removeFrame](objects/Basalt/removeFrame.md)|Removes a previously created base frame
|
||||
|[schedule](objects/Basalt/schedule.md)|Schedules a new task
|
||||
@@ -29,7 +29,7 @@ You are now able to access the following list of methods:
|
||||
|[setTheme](objects/Basalt/setTheme.md)|Changes the base theme of basalt
|
||||
|[setMouseDragThrottle](objects/Basalt/setMouseDragThrottle.md)|Changes the mouse drag throttle amount
|
||||
|[setMouseMoveThrottle](objects/Basalt/setMouseMoveThrottle.md)|CraftOS-PC: Changes the mouse move throttle amount
|
||||
|[setRenderingThrottle](objects/Basalt/setMouseMoveThrottle.md)|Sets the rendering throttle amount
|
||||
|[setRenderingThrottle](objects/Basalt/setRenderingThrottle.md)|Sets the rendering throttle amount
|
||||
|[setVariable](objects/Basalt/setVariable.md)|Sets a variable which you can access via XML
|
||||
|[stopUpdate / stop](objects/Basalt/stopUpdate.md)|Stops the currently active event and draw listener
|
||||
|[update](objects/Basalt/update.md)|Starts the event and draw listener once
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
### Description
|
||||
|
||||
Sets the base theme of the project! Make sure to cover all existing objects, otherwise it will result in errors. A good example is [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua). The theme can also be retrieved with [`basalt.getTheme()`](objects/Basalt/getTheme)
|
||||
Sets the base theme of the project! Make sure to cover all existing objects, otherwise it will result in errors. A good example is [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/plugins/themes.lua). The theme can also be retrieved with [`basalt.getTheme()`](objects/Basalt/getTheme)
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `table` theme - A table containing the theme layout. Look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for an example
|
||||
1. `table` theme - A table containing the theme layout. Look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/plugins/themes.lua) for an example
|
||||
|
||||
### Usage
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@ Sets the frame's offset, this offset is beeing used to move all children object'
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number` x position
|
||||
2. `number` y position
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The Checkbox object is derived from the VisualObject class and allows users to set a boolean value to true or false by clicking on it. Checkboxes are commonly used in forms and settings to enable or disable specific options.
|
||||
The Checkbox object is derived from the ChangeableObject class and allows users to set a boolean value to true or false by clicking on it. Checkboxes are commonly used in forms and settings to enable or disable specific options.
|
||||
|
||||
In addition to the Object and VisualObject methods, checkboxes also have the following method:
|
||||
In addition to the Object, VisualObject and ChangeableObject methods, checkboxes also have the following method:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|
||||
@@ -6,7 +6,7 @@ Sets the specified object as "important" within the container. This means the ob
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `string` The object to set as important
|
||||
1. `string|object` The object ID or object to set as important
|
||||
|
||||
### Returns
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## setFocusedObject
|
||||
## updateZIndex
|
||||
|
||||
### Description
|
||||
|
||||
|
||||
@@ -1,30 +1,170 @@
|
||||
A Flexbox is a layout container that is designed to make it easier to create flexible and responsive UI designs. It allows you to arrange and align its children (elements) within it in a more efficient way.
|
||||
A Flexbox is a layout container designed to facilitate the creation of flexible and responsive UI designs. It allows you to efficiently arrange and align its child elements within it.
|
||||
|
||||
In addition to the methods inherited from Frame, Container, VisualObject and Object, Flexbox has the following methods:
|
||||
The Flexbox Container is still a WIP and i will add more methods from the CSS Flexbox Implementation.
|
||||
|
||||
In addition to the methods inherited from ScrollableFrame, Frame, Container, VisualObject and Object, Flexbox has the following methods:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|[setSpacing](objects/Flexbox/setSpacing.md)|Sets the space between objects
|
||||
|[getSpacing](objects/Flexbox/getSpacing.md)|Returns the space between objects
|
||||
|[setFlexDirection](objects/Flexbox/setFlexDirection.md)|Sets the direction in which the children will be placed
|
||||
|[setJustifyContent](objects/Flexbox/setJustifyContent.md)|Determines how the children are aligned along the main axis
|
||||
|[setAlignItems](objects/Flexbox/setAlignItems.md)|Determines how the children are aligned along the off axis
|
||||
|[setSpacing](objects/Flexbox/setSpacing.md)|Defines the gap between child objects within the Flexbox
|
||||
|[getSpacing](objects/Flexbox/getSpacing.md)|Returns the current gap size between child objects
|
||||
|[setDirection](objects/Flexbox/setDirection.md)|Sets the direction for the arrangement of child objects (row/column)
|
||||
|[getDirection](objects/Flexbox/getDirection.md)|Returns the currently set arrangement direction of child objects
|
||||
|[setJustifyContent](objects/Flexbox/setJustifyContent.md)|Sets the alignment of child objects along the main axis (flex-start, center, flex-end, space-between, space-around, space-evenly)
|
||||
|[getJustifyContent](objects/Flexbox/getJustifyContent.md)|Returns the current alignment setting for child objects along the main axis
|
||||
|[setWrap](objects/Flexbox/setWrap.md)|Determines if child objects should wrap onto the next line when they run out of space
|
||||
|[getWrap](objects/Flexbox/getWrap.md)|Returns the current wrapping behavior for child objects
|
||||
|[updateLayout](objects/Flexbox/updateLayout.md)|Manually triggers a layout update for the Flexbox
|
||||
|[addBreak](objects/Flexbox/addBreak.md)|Introduces a line break within the Flexbox, forcing subsequent child objects to the next line
|
||||
|
||||
### Example
|
||||
Child objects added via the Flexbox have the following additional methods:
|
||||
|
||||
Here's an example of how to create a Flexbox object:
|
||||
| | |
|
||||
|---|---|
|
||||
|[getFlexGrow](objects/Flexbox/getFlexGrow.md)|Returns the flex grow factor of the child object
|
||||
|[setFlexGrow](objects/Flexbox/setFlexGrow.md)|Sets the flex grow factor of the child object
|
||||
|[getFlexShrink](objects/Flexbox/getFlexShrink.md)|Returns the flex shrink factor of the child object
|
||||
|[setFlexShrink](objects/Flexbox/setFlexShrink.md)|Sets the flex shrink factor of the child object
|
||||
|[getFlexBasis](objects/Flexbox/getFlexBasis.md)|Returns the flex basis of the child object
|
||||
|[setFlexBasis](objects/Flexbox/setFlexBasis.md)|Sets the flex basis of the child object
|
||||
|
||||
## Examples
|
||||
|
||||
### Nested Flexbox
|
||||
|
||||
Flexboxes can be nested within each other to create more complex layouts. This example demonstrates how to nest flexboxes.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
```lua
|
||||
local flex = main:addFlexbox():setWrap("wrap"):setBackground(colors.lightGray):setPosition(1, 1):setSize("parent.w", "parent.h")
|
||||
|
||||
flex:addButton():setSize(10, 3)
|
||||
flex:addButton():setSize(15, 3)
|
||||
flex:addButton():setSize(8, 3)
|
||||
flex:addButton():setSize(20, 3)
|
||||
flex:addButton()
|
||||
flex:addButton():setSize(10, 3)
|
||||
flex:addButton():setSize(15, 3)
|
||||
flex:addButton():setSize(8, 3)
|
||||
flex:addButton():setSize(20, 3)
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
### FlexGrow Property
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = main:addFlexbox()
|
||||
:setFlexDirection("column")
|
||||
:setJustifyContent("space-between")
|
||||
:setAlignItems("center")
|
||||
:setSpacing(5)
|
||||
|
||||
local function makeResizeable(frame, minW, minH, maxW, maxH)
|
||||
minW = minW or 4
|
||||
minH = minH or 4
|
||||
maxW = maxW or 99
|
||||
maxH = maxH or 99
|
||||
local btn = frame:addButton()
|
||||
:ignoreOffset()
|
||||
:setPosition("parent.w", "parent.h")
|
||||
:setSize(1, 1)
|
||||
:setText("/")
|
||||
:setForeground(colors.black)
|
||||
:setBackground(colors.gray)
|
||||
:onDrag(function(self, _, _, xOffset, yOffset)
|
||||
local w, h = frame:getSize()
|
||||
local wOff, hOff = w, h
|
||||
if(w+xOffset-1>=minW)and(w+xOffset-1<=maxW)then
|
||||
wOff = w+xOffset-1
|
||||
end
|
||||
if(h+yOffset-1>=minH)and(h+yOffset-1<=maxH)then
|
||||
hOff = h+yOffset-1
|
||||
end
|
||||
frame:setSize(wOff, hOff)
|
||||
end)
|
||||
end
|
||||
|
||||
local flexFrame = main:addMovableFrame():setSize(23, 12):setPosition(2, 2):setBackground(colors.gray):setBorder(colors.black)
|
||||
local flex = flexFrame:addFlexbox():setWrap("wrap"):setPosition(2, 2):setSize("parent.w - 2", "parent.h - 2"):setBackground(colors.gray):setForeground(colors.black):setTheme({ButtonBG=colors.black, ButtonText=colors.lightGray})
|
||||
flex:addButton():setFlexBasis(1):setFlexGrow(1)
|
||||
flex:addButton():setFlexBasis(1):setFlexGrow(1)
|
||||
flex:addButton():setFlexBasis(1):setFlexGrow(1)
|
||||
flex:addButton():setFlexBasis(1):setFlexGrow(1)
|
||||
flex:addButton():setFlexBasis(1):setFlexGrow(1)
|
||||
flex:addButton():setFlexBasis(1):setFlexGrow(1)
|
||||
flex:addButton():setFlexBasis(1):setFlexGrow(1)
|
||||
flex:addButton():setFlexBasis(1):setFlexGrow(1)
|
||||
|
||||
makeResizeable(flexFrame, 11, 6)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
Alternatively, you can create a flexbox using an XML layout:
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/flexgrow-property.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
```xml
|
||||
<flexbox flexDirection="column" justifyContent="space-between" alignItems="center" spacing="5">
|
||||
#### Another example
|
||||
|
||||
This is another example, which shows how frames work with flexbox
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
```lua
|
||||
local basalt = require("BasaltDev2")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
|
||||
local function makeResizeable(frame, minW, minH, maxW, maxH)
|
||||
minW = minW or 4
|
||||
minH = minH or 4
|
||||
maxW = maxW or 99
|
||||
maxH = maxH or 99
|
||||
local btn = frame:addButton()
|
||||
:ignoreOffset()
|
||||
:setPosition("parent.w", "parent.h")
|
||||
:setSize(1, 1)
|
||||
:setText("/")
|
||||
:setForeground(colors.black)
|
||||
:setBackground(colors.gray)
|
||||
:onDrag(function(self, _, _, xOffset, yOffset)
|
||||
local w, h = frame:getSize()
|
||||
local wOff, hOff = w, h
|
||||
if(w+xOffset-1>=minW)and(w+xOffset-1<=maxW)then
|
||||
wOff = w+xOffset-1
|
||||
end
|
||||
if(h+yOffset-1>=minH)and(h+yOffset-1<=maxH)then
|
||||
hOff = h+yOffset-1
|
||||
end
|
||||
frame:setSize(wOff, hOff)
|
||||
end)
|
||||
end
|
||||
|
||||
local flexFrame = main:addMovableFrame():setSize(23, 12):setPosition(2, 2):setBackground(colors.gray):setBorder(colors.black)
|
||||
local flex = flexFrame:addFlexbox():setWrap("wrap"):setPosition(2, 2):setSize("parent.w - 2", "parent.h - 2"):setBackground(colors.gray):setForeground(colors.black):setTheme({ButtonBG=colors.black, ButtonText=colors.lightGray})
|
||||
local f1 = flex:addFrame():setBackground(colors.black):setSize(25, 10):setFlexBasis(1):setFlexGrow(1)
|
||||
local f2 = flex:addFrame():setBackground(colors.black):setSize(25, 10):setFlexBasis(1):setFlexGrow(1)
|
||||
|
||||
f1:addLabel():setForeground(colors.lightGray):setText("Frame 1"):setPosition("parent.w/2-self.w/2", 2)
|
||||
f1:addButton():setText("Button"):setPosition(2, 4):setBackground(colors.gray):setForeground(colors.black):setSize("math.floor(parent.w - 2)", 3)
|
||||
f2:addLabel():setForeground(colors.lightGray):setSize("parent.w", "parent.h"):setText("lorem ipsum dolor sit amet, consectetur adipiscing elit. sed non risus. suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. cras elementum ultrices diam. maecenas ligula massa, varius a, semper congue, euismod non, mi. proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit.")
|
||||
makeResizeable(flexFrame, 11, 6)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/frame-flexgrow-property.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
22
docs/objects/Flexbox/addBreak.md
Normal file
22
docs/objects/Flexbox/addBreak.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## addBreak
|
||||
|
||||
### Description
|
||||
|
||||
The `addBreak` method adds a line break to the Flexbox container. This causes the subsequent children to start on a new line or column, depending on the flex direction. This is helpful when you want to control the arrangement of children within the Flexbox container.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, adds some objects to it, and then adds a break before adding more objects.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
flexbox:addButton()
|
||||
flexbox:addButton()
|
||||
flexbox:addBreak() -- adds a line break
|
||||
flexbox:addButton() -- this object will start on a new line
|
||||
```
|
||||
20
docs/objects/Flexbox/getDirection.md
Normal file
20
docs/objects/Flexbox/getDirection.md
Normal file
@@ -0,0 +1,20 @@
|
||||
## getDirection
|
||||
|
||||
### Description
|
||||
|
||||
Returns the current direction in which the child objects are arranged within the Flexbox.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `string` The direction in which the child objects are arranged. Possible values are: row, column.
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, sets the direction, and then retrieves it.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
:setDirection("column")
|
||||
local direction = flexbox:getDirection() -- returns "column"
|
||||
```
|
||||
21
docs/objects/Flexbox/getFlexBasis.md
Normal file
21
docs/objects/Flexbox/getFlexBasis.md
Normal file
@@ -0,0 +1,21 @@
|
||||
## getFlexBasis
|
||||
|
||||
### Description
|
||||
|
||||
The `getFlexBasis` method retrieves the initial main size of a child object within the Flexbox container. This value represents the starting point for further calculations. If the Flexbox has a direction of 'row', the flex basis is akin to the width. For 'column', it's akin to height.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number` The current flex basis of the object
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, adds some objects to it, sets the flex basis for the first object, and retrieves it.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
local object1 = flexbox:addButton()
|
||||
object1:setFlexBasis(10) -- this object will have an initial size of 50 pixels along the main axis
|
||||
basalt.debug(object1:getFlexBasis()) -- prints: 50
|
||||
```
|
||||
21
docs/objects/Flexbox/getFlexGrow.md
Normal file
21
docs/objects/Flexbox/getFlexGrow.md
Normal file
@@ -0,0 +1,21 @@
|
||||
## getFlexGrow
|
||||
|
||||
### Description
|
||||
|
||||
The `getFlexGrow` method retrieves the grow factor of a child object within the Flexbox container. This value determines how much of the remaining space along the main axis the child should take up, in relation to the other children.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number` The grow factor of the child object.
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, adds some objects to it, sets the flexGrow for the first object, and then retrieves this value.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
local object1 = flexbox:addButton()
|
||||
object1:setFlexGrow(1) -- this object will grow to take up remaining space
|
||||
basalt.debug(object1:getFlexGrow()) -- prints 1
|
||||
```
|
||||
21
docs/objects/Flexbox/getFlexShrink.md
Normal file
21
docs/objects/Flexbox/getFlexShrink.md
Normal file
@@ -0,0 +1,21 @@
|
||||
## getFlexShrink
|
||||
|
||||
### Description
|
||||
|
||||
The `getFlexShrink` method retrieves the current shrink factor of a child object within the Flexbox container. This value represents how much the object would shrink compared to other objects in the container, in case there isn't enough space.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number` The current shrink factor of the object.
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, adds some objects to it, sets the flexShrink for the first object, and retrieves it.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
local object1 = flexbox:addButton()
|
||||
object1:setFlexShrink(2) -- this object will shrink twice as much as the others if necessary
|
||||
basalt.debug(object1:getFlexShrink()) -- prints: 2
|
||||
```
|
||||
20
docs/objects/Flexbox/getJustifyContent.md
Normal file
20
docs/objects/Flexbox/getJustifyContent.md
Normal file
@@ -0,0 +1,20 @@
|
||||
## getJustifyContent
|
||||
|
||||
### Description
|
||||
|
||||
Returns the current method used for aligning the child objects along the main axis within the Flexbox.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `string` The method used for aligning the child objects. Possible values are: `flex-start`, `flex-end`, `center`, `space-between`, `space-around`, and `space-evenly`.
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, sets the justify content, and then retrieves it.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
:setJustifyContent("space-between")
|
||||
local justifyContent = flexbox:getJustifyContent() -- returns "space-between"
|
||||
```
|
||||
20
docs/objects/Flexbox/getWrap.md
Normal file
20
docs/objects/Flexbox/getWrap.md
Normal file
@@ -0,0 +1,20 @@
|
||||
## getWrap
|
||||
|
||||
### Description
|
||||
|
||||
Returns the current setting for whether the child objects should wrap onto the next line if there isn't enough room on the main axis within the Flexbox.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `string` returns `nowrap` or `wrap`
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, sets the wrap, and then retrieves it.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
:setWrap("wrap")
|
||||
local wrapSetting = flexbox:getWrap() -- returns wrap
|
||||
```
|
||||
@@ -1,23 +0,0 @@
|
||||
## setJustifyContent
|
||||
|
||||
### Description
|
||||
|
||||
Determines how the children are aligned along the off axis
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `string` One of ("flex-start", "flex-end", "center", "space-between", "space-around") - default is flex-start. Works the same as the property of the same name in [CSS flexboxes](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-flexbox-properties)
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default flexbox and sets the align items to space-between.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
:setAlignItems("space-between")
|
||||
```
|
||||
@@ -1,4 +1,4 @@
|
||||
## setFlexDirection
|
||||
## setDirection
|
||||
|
||||
### Description
|
||||
|
||||
@@ -19,5 +19,5 @@ Sets the direction in which the children will be placed
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
:setFlexDirection("column")
|
||||
:setDirection("column")
|
||||
```
|
||||
24
docs/objects/Flexbox/setFlexBasis.md
Normal file
24
docs/objects/Flexbox/setFlexBasis.md
Normal file
@@ -0,0 +1,24 @@
|
||||
## setFlexBasis
|
||||
|
||||
### Description
|
||||
|
||||
The `setFlexBasis` method sets the initial main size of a child object within the Flexbox container. This value represents the starting point for further calculations. If the Flexbox has a direction of 'row', the flex basis is akin to the width. For 'column', it's akin to height.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `number` Flex basis. Currently only numbers available.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, adds some objects to it, and sets the flex basis for the first object.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
local object1 = flexbox:addButton()
|
||||
object1:setFlexBasis(10) -- this object will have an initial size of 10 pixels along the main axis
|
||||
```
|
||||
25
docs/objects/Flexbox/setFlexGrow.md
Normal file
25
docs/objects/Flexbox/setFlexGrow.md
Normal file
@@ -0,0 +1,25 @@
|
||||
## setFlexGrow
|
||||
|
||||
### Description
|
||||
|
||||
The `setFlexGrow` method sets the grow factor of a child object within the Flexbox container. This determines how much of the remaining space along the main axis the child should take up, in relation to the other children. A larger grow factor means the child will take up more of the remaining space.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `number` The grow factor for the child object. This should be a non-negative number. A value of 0 means the child will not grow beyond its initial size. Default is 0.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, adds some objects to it, and sets the flexGrow for the first object.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
local object1 = flexbox:addButton()
|
||||
object1:setFlexGrow(1) -- this object will grow to take up remaining space
|
||||
local object2 = flexbox:addButton() -- this object will not grow
|
||||
```
|
||||
24
docs/objects/Flexbox/setFlexShrink.md
Normal file
24
docs/objects/Flexbox/setFlexShrink.md
Normal file
@@ -0,0 +1,24 @@
|
||||
## setFlexShrink
|
||||
|
||||
### Description
|
||||
|
||||
The `setFlexShrink` method sets the shrink factor of a child object within the Flexbox container. This value determines how much the child should shrink relative to the rest of the objects in the flex container, if necessary.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `number` The shrink factor of the child object. The default is 0. A higher value will cause the object to shrink more.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, adds some objects to it, and sets the flexShrink for the first object.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
local object1 = flexbox:addButton()
|
||||
object1:setFlexShrink(2) -- this object will shrink twice as much as the others if necessary
|
||||
```
|
||||
@@ -6,7 +6,7 @@ Determines how the children are aligned along the main axis
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `string` One of ("flex-start", "flex-end", "center", "space-between", "space-around") - default is flex-start. Works the same as the property of the same name in [CSS flexboxes](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-flexbox-properties)
|
||||
1. `string` One of ("flex-start", "flex-end", "center", "space-between", "space-around", "space-evenly") - default is flex-start. Works the same as the property of the same name in [CSS flexboxes](https://css-tricks.com/snippets/css/a-guide-to-flexbox/#aa-flexbox-properties)
|
||||
|
||||
### Returns
|
||||
|
||||
|
||||
25
docs/objects/Flexbox/setWrap.md
Normal file
25
docs/objects/Flexbox/setWrap.md
Normal file
@@ -0,0 +1,25 @@
|
||||
## setWrap
|
||||
|
||||
### Description
|
||||
|
||||
Determines whether the child objects should wrap onto the next line when there isn't enough room along the main axis. The default value is 'nowrap'.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `string` If set to `wrap`, the child objects will wrap onto the next line when they run out of space. If set to `nowrap`, they will not.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox and sets the wrapping to `wrap`.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
:setWrap("wrap")
|
||||
```
|
||||
|
||||
If the contents of the Flexbox exceed its size, they will automatically move to the next line, creating a wrapping effect. This is particularly useful when designing responsive layouts that adapt to different screen sizes or window dimensions.
|
||||
22
docs/objects/Flexbox/updateLayout.md
Normal file
22
docs/objects/Flexbox/updateLayout.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## updateLayout
|
||||
|
||||
### Description
|
||||
|
||||
The `updateLayout` method forces the Flexbox container to manually update its layout. This is particularly useful in situations where dynamic changes occur within the Flexbox and you want to ensure that the layout correctly reflects these changes.
|
||||
|
||||
By default this is not necessarily required. Because the flexbox automatically updates it's layout.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default Flexbox, adds an object to it, and then forces a manual layout update.
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
local flexbox = mainFrame:addFlexbox()
|
||||
flexbox:addObject(myObject)
|
||||
flexbox:updateLayout() -- forces a manual update of the layout
|
||||
```
|
||||
@@ -6,3 +6,292 @@ In addition to the methods inherited from Container, VisualObject and Object, Fr
|
||||
|---|---|
|
||||
|[getOffset](objects/BaseFrame/getOffset.md)|Returns the current offset of the BaseFrame object
|
||||
|[setOffset](objects/BaseFrame/setOffset.md)|Sets a new offset for the BaseFrame object
|
||||
|
||||
## Examples
|
||||
|
||||
Here are some examples on how you can use frames to create very advanced programs. Because of the screen size limitation of CC:Tweaked frames can become very useful in almost every scenario. You will find some examples here on how you could implement them.
|
||||
|
||||
### Menubar for switching frames
|
||||
|
||||
In this example, we create a menubar that helps you switch between frames, without any animations involved.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") -- we need basalt here
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black}) -- we change the default bg and fg color for frames
|
||||
|
||||
local sub = { -- here we create a table where we gonna add some frames
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"), -- obviously the first one should be shown on program start
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"):hide(),
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"):hide(),
|
||||
}
|
||||
|
||||
local function openSubFrame(id) -- we create a function which switches the frame for us
|
||||
if(sub[id]~=nil)then
|
||||
for k,v in pairs(sub)do
|
||||
v:hide()
|
||||
end
|
||||
sub[id]:show()
|
||||
end
|
||||
end
|
||||
|
||||
local menubar = main:addMenubar():setScrollable() -- we create a menubar in our main frame.
|
||||
:setSize("parent.w")
|
||||
:onChange(function(self, val)
|
||||
openSubFrame(self:getItemIndex()) -- here we open the sub frame based on the table index
|
||||
end)
|
||||
:addItem("Example 1")
|
||||
:addItem("Example 2")
|
||||
:addItem("Example 3")
|
||||
|
||||
-- Now we can change our sub frames, if you want to access a sub frame just use sub[subid], some examples:
|
||||
sub[1]:addButton():setPosition(2, 2)
|
||||
|
||||
sub[2]:addLabel():setText("Hello World!"):setPosition(2, 2)
|
||||
|
||||
sub[3]:addLabel():setText("Now we're on example 3!"):setPosition(2, 2)
|
||||
sub[3]:addButton():setText("No functionality"):setPosition(2, 4):setSize(18, 3)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/frames-with-menubars.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Sidebar with buttons to switch frames
|
||||
|
||||
This example illustrates how to create a sidebar with buttons that can be used to switch between frames. Also note that :setZIndex(25) is used to ensure that the sidebar frame is always displayed on top of the normal subframes.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") -- we need basalt here
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black})
|
||||
|
||||
--[[
|
||||
Here we create the sidebar, on focus it should change the position to parent.w - (self.w-1) which "opens the frame"
|
||||
when the focus gets lost we simply change the position to "parent.w"
|
||||
As you can see we add :setZIndex(25) - this makes sure the sidebar frame is always more important than our normal sub frames.
|
||||
:setScrollable just makes the sidebar frame scrollable (in case you're adding more frames)
|
||||
]]
|
||||
local sidebar = main:addFrame():setBackground(colors.gray):setPosition("parent.w", 1):setSize(15, "parent.h"):setZIndex(25):setScrollable()
|
||||
:onGetFocus(function(self)
|
||||
self:setPosition("parent.w - (self.w-1)")
|
||||
end)
|
||||
:onLoseFocus(function(self)
|
||||
self:setPosition("parent.w")
|
||||
end)
|
||||
|
||||
-- Once again we add 3 frames, the first one should be immediatly visible
|
||||
local sub = {
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"),
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"):hide(),
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"):hide(),
|
||||
}
|
||||
|
||||
--This part of the code adds buttons based on the sub table.
|
||||
local y = 2
|
||||
for k,v in pairs(sub)do
|
||||
sidebar:addButton():setText("Example "..k) -- creating the button and adding a name k is just the index
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.lightGray)
|
||||
:setSize("parent.w - 2", 3)
|
||||
:setPosition(2, y)
|
||||
:onClick(function() -- here we create a on click event which hides ALL sub frames and then shows the one which is linked to the button
|
||||
for a, b in pairs(sub)do
|
||||
b:hide()
|
||||
v:show()
|
||||
end
|
||||
end)
|
||||
y = y + 4
|
||||
end
|
||||
|
||||
sub[1]:addButton():setPosition(2, 2)
|
||||
|
||||
sub[2]:addLabel():setText("Hello World!"):setPosition(2, 2)
|
||||
|
||||
sub[3]:addLabel():setText("Now we're on example 3!"):setPosition(2, 2)
|
||||
sub[3]:addButton():setText("No functionality"):setPosition(2, 4):setSize(18, 3)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/frames-with-sidebar.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Movable frames with a program object
|
||||
|
||||
In this example, we will demonstrate how to create movable frames with a program object inside. This will also demonstrate how you can dynamically add new frames.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black})
|
||||
|
||||
local id = 1
|
||||
local processes = {}
|
||||
|
||||
local function openProgram(path, title, x, y, w, h)
|
||||
local pId = id
|
||||
id = id + 1
|
||||
local f = main:addMovableFrame()
|
||||
:setSize(w or 30, h or 12)
|
||||
:setPosition(x or math.random(2, 12), y or math.random(2, 8))
|
||||
|
||||
f:addLabel()
|
||||
:setSize("parent.w", 1)
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.lightGray)
|
||||
:setText(title or "New Program")
|
||||
|
||||
f:addProgram()
|
||||
:setSize("parent.w-1", "parent.h - 2")
|
||||
:setPosition(1, 2)
|
||||
:execute(path or "rom/programs/shell.lua")
|
||||
|
||||
f:addButton()
|
||||
:setSize(1, 1)
|
||||
:setText("X")
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.red)
|
||||
:setPosition("parent.w-1", 1)
|
||||
:onClick(function()
|
||||
f:remove()
|
||||
processes[pId] = nil
|
||||
end)
|
||||
processes[pId] = f
|
||||
return f
|
||||
end
|
||||
|
||||
openProgram("rom/programs/fun/worm.lua")
|
||||
|
||||
main:addButton():setPosition("parent.w - 16", 2):setText("Open"):onClick(function()
|
||||
openProgram()
|
||||
end)
|
||||
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/dynamic-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
|
||||
### Resizable frames
|
||||
|
||||
This example shows how to make your frames resizable manually, as Basalt does not offer a built-in way to do this. It is, however, a straightforward process.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.black, FrameFG = colors.lightGray})
|
||||
|
||||
local sub = main:addFrame():setSize(25, 12):setPosition(3, 3)
|
||||
|
||||
local function makeResizeable(frame, minW, minH, maxW, maxH)
|
||||
minW = minW or 4
|
||||
minH = minH or 4
|
||||
maxW = maxW or 99
|
||||
maxH = maxH or 99
|
||||
local btn = frame:addButton()
|
||||
:setPosition("parent.w-1", "parent.h-1")
|
||||
:setSize(1, 1)
|
||||
:setText("/")
|
||||
:setForeground(colors.blue)
|
||||
:setBackground(colors.black)
|
||||
:onDrag(function(self, event, btn, xOffset, yOffset)
|
||||
local w, h = frame:getSize()
|
||||
local wOff, hOff = w, h
|
||||
if(w+xOffset-1>=minW)and(w+xOffset-1<=maxW)then
|
||||
wOff = w+xOffset-1
|
||||
end
|
||||
if(h+yOffset-1>=minH)and(h+yOffset-1<=maxH)then
|
||||
hOff = h+yOffset-1
|
||||
end
|
||||
frame:setSize(wOff, hOff)
|
||||
end)
|
||||
end
|
||||
|
||||
makeResizeable(sub, 8, 4)
|
||||
|
||||
sub:addLabel():setText("Hello World")
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/resizable-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Scrollable frames
|
||||
|
||||
In this example, you will see how to make frames scrollable. Basalt only supports vertical scrolling, but we will also provide an example of how to implement horizontal scrolling.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.black, FrameFG = colors.lightGray})
|
||||
|
||||
-- Vertical scrolling is pretty simple, as you can tell:
|
||||
local sub1 = main:addFrame():setScrollable():setSize(20, 15):setPosition(2, 2)
|
||||
|
||||
sub1:addLabel():setPosition(3, 2):setText("Scrollable")
|
||||
sub1:addLabel():setPosition(3, 12):setText("Inside")
|
||||
sub1:addLabel():setPosition(3, 20):setText("Outside")
|
||||
|
||||
-- Here we create a custom scroll event as you can see we dont add a :setScrollable() method to our frame, instead we add a custom scroll event
|
||||
local objects = {}
|
||||
|
||||
local sub2 = main:addFrame():setPosition(23, 2):setSize(25, 5):onScroll(function(self, event, dir)
|
||||
local maxScroll = 0
|
||||
for k,v in pairs(objects)do -- here we iterate trough every object and get their x position + width this way we can find out what's the maximum allowed value to scroll
|
||||
local x = v:getX()
|
||||
local w = v:getWidth()
|
||||
maxScroll = x + w > maxScroll and x + w or maxScroll -- if you don't understand this line, http://lua-users.org/wiki/TernaryOperator
|
||||
end
|
||||
local xOffset = self:getOffset()
|
||||
if(xOffset+dir>=0 and xOffset+dir<=maxScroll-self:getWidth())then
|
||||
self:setOffset(xOffset+dir, 0)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Because we need to iterate the objects, we add them into a table.
|
||||
table.insert(objects, sub2:addButton():setPosition(2, 2):setText("Scrollable"))
|
||||
table.insert(objects, sub2:addButton():setPosition(16, 2):setText("Inside"))
|
||||
table.insert(objects, sub2:addButton():setPosition(30, 2):setText("Outside"))
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/scrollable-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
## add<Object>
|
||||
Adds a new object. Don't use add<Object> please use addTheObjectYouNeed For example if you want a new Frame, use
|
||||
addFrame, if you want to add a button, use addButton
|
||||
Adds a new object. Don't use add<Object> please use addTheObjectYouNeed. For example if you want a new Frame, use
|
||||
addFrame, if you want to add a button, use addButton.
|
||||
|
||||
#### Parameters:
|
||||
1. `string` optional - the id if you don't add a id it will autimatically generate one for you
|
||||
1. `string` optional - the id if you don't add a id it will automatically generate one for you
|
||||
|
||||
#### Returns:
|
||||
1. `object` The new object you've created
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
## setTheme
|
||||
|
||||
Sets the default theme, of that frame children objects always try to get the theme of its parent frame, if it does not exist it goes to its parent parent frame, and so on until it reaches the basalt manager's theme - which is stored in theme.lua (Please checkout [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for how it could look like.
|
||||
Sets the default theme, of that frame children objects always try to get the theme of its parent frame, if it does not exist it goes to its parent parent frame, and so on until it reaches the basalt manager's theme - which is stored in theme.lua (Please checkout [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/plugins/themes.lua) for how it could look like.
|
||||
|
||||
#### Parameters:
|
||||
|
||||
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for a example
|
||||
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/plugins/themes.lua) for a example
|
||||
|
||||
#### Returns:
|
||||
|
||||
|
||||
@@ -19,5 +19,5 @@ Sets a data point in the graph with specified value.
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aGraph = mainFrame:addGraph()
|
||||
aGraph:setDataPoint(13)
|
||||
aGraph:addDataPoint(13)
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The Image object is designed for adding more advanced backgrounds to your interface. It supports the loading of .nfp and .bimg images, allowing for greater customization of your interface's appearance.
|
||||
|
||||
In addition to the Object and VisualObject methods, Progressbar objects have the following methods:
|
||||
In addition to the Object and VisualObject methods, Image objects have the following methods:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|
||||
27
docs/objects/Image/blit.md
Normal file
27
docs/objects/Image/blit.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## blit
|
||||
|
||||
### Description
|
||||
|
||||
Sets or modifies text, foreground and background color.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `string` text - The text to be placed at the specified position
|
||||
1. `string` foreground - A string representing the foreground color
|
||||
1. `string` background - A string representing the background color
|
||||
2. `number` x - The x-coordinate of the text position.
|
||||
3. `number` y - The y-coordinate of the text position.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a new image object, adds a frame, and sets the text in the active frame.
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aImage = mainFrame:addImage():addFrame():blit("Hello", "fffff", "00000", 1, 1)
|
||||
|
||||
```
|
||||
9
docs/objects/Input/getOffset.md
Normal file
9
docs/objects/Input/getOffset.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## getOffset
|
||||
|
||||
### Description
|
||||
|
||||
Returns the current offset
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number` the offset
|
||||
9
docs/objects/Input/getTextOffset.md
Normal file
9
docs/objects/Input/getTextOffset.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## getTextOffset
|
||||
|
||||
### Description
|
||||
|
||||
Returns the current text offset
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number` the text offset
|
||||
22
docs/objects/Input/setOffset.md
Normal file
22
docs/objects/Input/setOffset.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## setOffset
|
||||
|
||||
### Description
|
||||
|
||||
Sets the input offset
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `number` offset - The offset you want it to be
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default input and changes the offset to 2
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aInput = mainFrame:addInput():setOffset(2)
|
||||
```
|
||||
22
docs/objects/Input/setTextOffset.md
Normal file
22
docs/objects/Input/setTextOffset.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## setTextOffset
|
||||
|
||||
### Description
|
||||
|
||||
Sets the input text offset
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `number` text offset - The offset you want it to be
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Creates a default input and changes the text offset to 2
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aInput = mainFrame:addInput():setTextOffset(2)
|
||||
```
|
||||
@@ -2,7 +2,6 @@ A Label object is used to display simple text on the interface.
|
||||
|
||||
In addition to the Object and VisualObject methods, Label objects have the following methods:
|
||||
|
||||
[Object](objects/Object.md) methods also apply for labels.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|
||||
@@ -49,7 +49,7 @@ aList:addItem("Item 1")
|
||||
aList:addItem("Item 2", colors.yellow)
|
||||
aList:addItem("Item 3", colors.yellow, colors.green)
|
||||
|
||||
aList:onSelect(function(self, item)
|
||||
aList:onSelect(function(self, event, item)
|
||||
basalt.debug("Selected item: ", item.text)
|
||||
end)
|
||||
```
|
||||
|
||||
@@ -12,13 +12,13 @@ In addition to the Object and VisualObject methods, Textfield objects have the f
|
||||
|[getTextCursor](objects/Textfield/getTextCursor.md)|Returns the current text cursor position
|
||||
|[addKeywords](objects/Textfield/addKeywords.md)|Adds syntax highlighting keywords
|
||||
|[addRule](objects/Textfield/addRule.md)|Adds a custom syntax highlighting rule
|
||||
|[editRule](objects/Textfield/addRule.md)|Edits an existing syntax highlighting rule
|
||||
|[removeRule](objects/Textfield/addRule.md)|Removes an existing syntax highlighting rule
|
||||
|[getOffset](objects/Textfield/addRule.md)|Returns the current offset inside the Textfield
|
||||
|[setOffset](objects/Textfield/addRule.md)|Changes the offset inside the Textfield
|
||||
|[clear](objects/Textfield/addRule.md)|Clears the Textfield content
|
||||
|[setSelection](objects/Textfield/addRule.md)|Sets the selection color (text color and background color)
|
||||
|[getSelection](objects/Textfield/addRule.md)|Returns the current selection color
|
||||
|[editRule](objects/Textfield/editRule.md)|Edits an existing syntax highlighting rule
|
||||
|[removeRule](objects/Textfield/removeRule.md)|Removes an existing syntax highlighting rule
|
||||
|[getOffset](objects/Textfield/getOffset.md)|Returns the current offset inside the Textfield
|
||||
|[setOffset](objects/Textfield/setOffset.md)|Changes the offset inside the Textfield
|
||||
|[clear](objects/Textfield/clear.md)|Clears the Textfield content
|
||||
|[setSelection](objects/Textfield/setSelection.md)|Sets the selection color (text color and background color)
|
||||
|[getSelection](objects/Textfield/getSelection.md)|Returns the current selection color
|
||||
|
||||
In version 1.7, Textfields now allow the user to select text with the mouse. The setSelection method is used to choose the text color and background color for selected text.
|
||||
|
||||
|
||||
23
docs/objects/Textfield/clear.md
Normal file
23
docs/objects/Textfield/clear.md
Normal file
@@ -0,0 +1,23 @@
|
||||
## clear
|
||||
|
||||
### Description
|
||||
|
||||
Clears the entire content of a Textfield object, removing all text currently displayed within it.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object ` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aTextfield = mainFrame:addTextfield()
|
||||
|
||||
-- Assume there is some content in the Textfield
|
||||
aTextfield:clear() -- Clear the entire content
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
30
docs/objects/Textfield/editRule.md
Normal file
30
docs/objects/Textfield/editRule.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## addRule
|
||||
|
||||
### Description
|
||||
|
||||
Edits an existing rule for special coloring in a Textfield object. This allows you to modify the color and/or background color applied to text matching a specific pattern.
|
||||
|
||||
### Parameteres
|
||||
|
||||
1. `string` pattern - The Lua pattern used to match the text you want to edit the coloring for.
|
||||
2. `number|color` textColor - The new color you want to apply to the text matching the pattern.
|
||||
3. `number|color` backgroundColor - (optional) The new background color you want to apply to the text matching the pattern.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Modifies the color of all numbers in a Textfield object.
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aTextfield = mainFrame:addTextfield()
|
||||
|
||||
aTextfield:editRule("%d", colors.red) -- Changes the color of numbers to red
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
26
docs/objects/Textfield/getOffset.md
Normal file
26
docs/objects/Textfield/getOffset.md
Normal file
@@ -0,0 +1,26 @@
|
||||
## getOffset
|
||||
|
||||
### Description
|
||||
|
||||
Retrieves the current offset within a Textfield object, providing information about the current viewable portion of the text.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number` The current horizontal offset within the Textfield.
|
||||
2. `number` The current vertical offset within the Textfield.
|
||||
|
||||
### Usage
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aTextfield = mainFrame:addTextfield()
|
||||
|
||||
-- Assume the Textfield has been scrolled previously
|
||||
local xOffset, yOffset = aTextfield:getOffset()
|
||||
basalt.debug("Horizontal Offset: "..xOffset)
|
||||
basalt.debug("Vertical Offset: "..yOffset)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
10
docs/objects/Textfield/getSelection.md
Normal file
10
docs/objects/Textfield/getSelection.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## setSelection
|
||||
|
||||
### Description
|
||||
|
||||
Returns the colors when selecting a text.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number|color` foreground color - The text color.
|
||||
2. `number|color` background color - ´The background color.
|
||||
28
docs/objects/Textfield/removeRule.md
Normal file
28
docs/objects/Textfield/removeRule.md
Normal file
@@ -0,0 +1,28 @@
|
||||
## removeRule
|
||||
|
||||
### Description
|
||||
|
||||
Removes an existing rule for special coloring in a Textfield object. This allows you to remove the coloring applied to text matching a specific pattern.
|
||||
|
||||
### Parameteres
|
||||
|
||||
1. `string` pattern - The Lua pattern used to match the text for which the rule was applied.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
* Removes the rule for coloring all numbers in a Textfield object
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aTextfield = mainFrame:addTextfield()
|
||||
|
||||
aTextfield:removeRule("%d") -- Removes the rule for coloring numbers
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
28
docs/objects/Textfield/setOffset.md
Normal file
28
docs/objects/Textfield/setOffset.md
Normal file
@@ -0,0 +1,28 @@
|
||||
## setOffset
|
||||
|
||||
### Description
|
||||
|
||||
Sets the offset within a Textfield object, allowing you to adjust the viewable portion of the text.
|
||||
|
||||
### Parameteres
|
||||
|
||||
1. `number` xOffset - The horizontal offset to set within the Textfield
|
||||
2. `number` yOffset - The vertical offset to set within the Textfield
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aTextfield = mainFrame:addTextfield()
|
||||
|
||||
-- Scroll 10 units down vertically
|
||||
aTextfield:setOffset(0, 10)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
27
docs/objects/Textfield/setSelection.md
Normal file
27
docs/objects/Textfield/setSelection.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## setSelection
|
||||
|
||||
### Description
|
||||
|
||||
Changes the color when selecting text.
|
||||
|
||||
### Parameteres
|
||||
|
||||
1. `number|color` foreground color - The text color.
|
||||
2. `number|color` background color - ´The background color.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
### Usage
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aTextfield = mainFrame:addTextfield()
|
||||
|
||||
aTextfield:setSelection(colors.white, colors.blue)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
3033
docs/versions/basalt-1.7.0.lua
Normal file
3033
docs/versions/basalt-1.7.0.lua
Normal file
File diff suppressed because one or more lines are too long
3299
docs/versions/basalt-1.7.1.lua
Normal file
3299
docs/versions/basalt-1.7.1.lua
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,79 +0,0 @@
|
||||
--Basalt configurated installer
|
||||
local filePath = "basalt.lua" --here you can change the file path default: basalt
|
||||
if not(fs.exists(filePath))then
|
||||
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
|
||||
end
|
||||
local basalt = require(filePath:gsub(".lua", ""))
|
||||
|
||||
local w, h = term.getSize()
|
||||
|
||||
|
||||
local main = basalt.createFrame("mainFrame")
|
||||
local objFrame = main:addFrame("objectFrame"):setPosition(1,2):setBackground(colors.lightGray):setSize(w, h-1)
|
||||
local programFrame = main:addFrame("programFrame"):setPosition(1,2):setBackground(colors.lightGray):setSize(w, h-1):hide()
|
||||
local editorFrame = main:addFrame("editorFrame"):setPosition(1,2):setBackground(colors.lightGray):setSize(w, h-1):hide()
|
||||
|
||||
local menuBar = main:addMenubar("mainMenuBar"):addItem("Object"):addItem("Program"):addItem("Editor"):setBackground(colors.gray):setSize(w, 1):setSpace(5):setScrollable():show()
|
||||
menuBar:onChange(function(self)
|
||||
objFrame:hide()
|
||||
programFrame:hide()
|
||||
editorFrame:hide()
|
||||
if(self:getValue().text=="Object")then
|
||||
objFrame:show()
|
||||
elseif(self:getValue().text=="Program")then
|
||||
programFrame:show()
|
||||
elseif(self:getValue().text=="Editor")then
|
||||
editorFrame:show()
|
||||
end
|
||||
end)
|
||||
|
||||
local function visualButton(btn)
|
||||
btn:onClick(function(self) btn:setBackground(colors.black) btn:setForeground(colors.lightGray) end)
|
||||
btn:onClickUp(function(self) btn:setBackground(colors.gray) btn:setForeground(colors.black) end)
|
||||
btn:onLoseFocus(function(self) btn:setBackground(colors.gray) btn:setForeground(colors.black) end)
|
||||
end
|
||||
|
||||
--Object Frame:
|
||||
|
||||
visualButton(objFrame:addButton("exampleButton"):setText("Button"):setSize(12,3):setPosition(2,2):onClick(function() end):show())
|
||||
local sliderValue = objFrame:addLabel("sliderValueLabel"):setPosition(11,6):setText("1"):show()
|
||||
objFrame:addSlider("exampleSlider"):setPosition(2,6):onChange(function(self) sliderValue:setText(self:getValue()) end):show()
|
||||
objFrame:addInput("exampleText"):setPosition(2,8):setSize(16,1):setBackground(colors.black):setForeground(colors.lightGray):setDefaultText("Text Example", colors.gray):show()
|
||||
objFrame:addInput("exampleNumber"):setPosition(2,10):setSize(16,1):setBackground(colors.black):setForeground(colors.lightGray):setDefaultText("Number Example", colors.gray):setInputType("number"):show()
|
||||
objFrame:addInput("examplePassword"):setPosition(2,12):setSize(16,1):setBackground(colors.black):setForeground(colors.lightGray):setDefaultText("Password Example", colors.gray):setInputType("password"):show()
|
||||
|
||||
objFrame:addList("exampleList"):setPosition(20,2):addItem("1. Entry"):addItem("2. Entry"):addItem("3. Entry"):addItem("4. Entry"):addItem("5. Entry"):addItem("6. Entry"):addItem("7. Entry"):addItem("8. Entry"):show()
|
||||
objFrame:addDropdown("exampleDropdown"):setPosition(37,2):addItem("1. Entry"):addItem("2. Entry"):addItem("3. Entry"):addItem("4. Entry"):addItem("5. Entry"):addItem("6. Entry"):addItem("7. Entry"):addItem("8. Entry"):show()
|
||||
objFrame:addCheckbox("exampleCheckbox1"):setPosition(20,10):show()
|
||||
objFrame:addLabel("checkbox1Label"):setPosition(22,10):setText("Checkbox 1"):show()
|
||||
objFrame:addCheckbox("exampleCheckbox2"):setPosition(20,12):show()
|
||||
objFrame:addLabel("checkbox2Label"):setPosition(22,12):setText("Checkbox 2"):show()
|
||||
|
||||
objFrame:addRadio("exampleRadio"):setPosition(35,10):addItem("", 1, 1):addItem("", 1, 3):addItem("", 1, 5):setSelectedItem(colors.gray, colors.black):show()
|
||||
objFrame:addLabel("radio1Label"):setPosition(37,10):setText("Radio 1"):show()
|
||||
objFrame:addLabel("radio2Label"):setPosition(37,12):setText("Radio 2"):show()
|
||||
objFrame:addLabel("radio3Label"):setPosition(37,14):setText("Radio 3"):show()
|
||||
|
||||
objFrame:addScrollbar("exampleScrollbar"):setPosition(objFrame:getWidth(),1):setMaxValue(objFrame:getHeight()):setSize(1,objFrame:getHeight()):setSymbolSize(3):ignoreOffset():onChange(function(self) objFrame:setOffset(0, (self:getValue()-1)) end):setAnchor("topRight"):show():setZIndex(15)
|
||||
local prog = objFrame:addProgressbar("exampleProgressbar"):setAnchor("bottomLeft"):setSize(30, 3):setBackground(colors.gray):setPosition(2,3):onProgressDone(function()
|
||||
basalt.debug("Progress done!")
|
||||
end):show()
|
||||
|
||||
|
||||
local timer = objFrame:addTimer("exampleTimer"):setTime(1, -1):onCall(function()
|
||||
prog:setProgress(prog:getProgress()+2)
|
||||
end):start()
|
||||
|
||||
--Program Frame:
|
||||
local programCount = 1
|
||||
visualButton(programFrame:addButton("exampleButton"):setText("Add Shell"):setSize(13,3):setPosition(2,2):onClick(function()
|
||||
local newProgramWindow = programFrame:addFrame("programFrame"..programCount):setMovable(true):setBar("Console", colors.black, colors.lightGray):showBar():setPosition(3,3):setSize(26,12):show()
|
||||
local program = newProgramWindow:addProgram("exampleProgram"..programCount):setSize(26,11):setPosition(1,2):setBackground(colors.black):show()
|
||||
program:execute("rom/programs/shell.lua")
|
||||
programCount = programCount + 1
|
||||
end):show())
|
||||
|
||||
-- Editor Frame:
|
||||
editorFrame:addTextfield("exampleTextfield"):setPosition(2,2):setBackground(colors.black):setSize(w-2,h-3):setForeground(colors.white):show()
|
||||
|
||||
basalt.autoUpdate()
|
||||
@@ -1,167 +0,0 @@
|
||||
--Basalt configurated installer
|
||||
local filePath = "basalt.lua" --here you can change the file path default: basalt
|
||||
if not(fs.exists(filePath))then
|
||||
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
|
||||
end
|
||||
local basalt = require(filePath:gsub(".lua", ""))
|
||||
|
||||
basalt.setVariable("buttonColor", basalt.schedule(function(self)
|
||||
self:setBackground(colors.black)
|
||||
self:setForeground(colors.lightGray)
|
||||
os.sleep(0.1)
|
||||
self:setBackground(colors.gray)
|
||||
self:setForeground(colors.black)
|
||||
end))
|
||||
|
||||
local main
|
||||
|
||||
basalt.setVariable("ex1", function()
|
||||
main:addAnimation():setObject(main):setAutoDestroy():offset(0,0,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("ex1Top", function()
|
||||
local example1 = main:getDeepObject("example1")
|
||||
example1:addAnimation():setObject(example1):setAutoDestroy():offset(0,0,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("ex2", function()
|
||||
main:addAnimation():setObject(main):setAutoDestroy():offset(main:getWidth(),0,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("p1", function()
|
||||
local example2 = main:getDeepObject("example2")
|
||||
example2:addAnimation():setObject(example2):setAutoDestroy():offset(0,0,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("p2", function()
|
||||
local example2 = main:getDeepObject("example2")
|
||||
example2:addAnimation():setObject(example2):setAutoDestroy():offset(0,example2:getHeight(),1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("p3", function()
|
||||
local example2 = main:getDeepObject("example2")
|
||||
example2:addAnimation():setObject(example2):setAutoDestroy():offset(0,example2:getHeight()*2,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("ex3", function()
|
||||
main:addAnimation():setObject(main):setAutoDestroy():offset(main:getWidth()*2,0,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("e1", function()
|
||||
local example3 = main:getDeepObject("example3")
|
||||
example3:addAnimation():setObject(example3):setAutoDestroy():offset(0,0,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("e2", function()
|
||||
local example3 = main:getDeepObject("example3")
|
||||
example3:addAnimation():setObject(example3):setAutoDestroy():offset(0,example3:getHeight(),1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("e3", function()
|
||||
local example3 = main:getDeepObject("example3")
|
||||
example3:addAnimation():setObject(example3):setAutoDestroy():offset(0,example3:getHeight()*2,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("ex4", function()
|
||||
main:addAnimation():setObject(main):setAutoDestroy():offset(main:getWidth()*3,0,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("progressChange", function(self)
|
||||
main:getDeepObject("progressLabel"):setText(self:getValue().."%")
|
||||
end)
|
||||
|
||||
basalt.setVariable("pauseP2", function()
|
||||
main:getDeepObject("program2"):pause()
|
||||
end)
|
||||
|
||||
basalt.setVariable("pauseP3", function()
|
||||
main:getDeepObject("program3"):pause()
|
||||
end)
|
||||
|
||||
basalt.setVariable("startAnimation", function()
|
||||
main:getDeepObject("animation1"):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("disableStartButton", function()
|
||||
main:getDeepObject("animationButton"):disable()
|
||||
end)
|
||||
|
||||
basalt.setVariable("enableStartButton", function()
|
||||
main:getDeepObject("animationButton"):enable()
|
||||
end)
|
||||
|
||||
basalt.setVariable("onTextfieldFocus", function()
|
||||
main:getDeepObject("coolTextfield"):setForeground(colors.lightGray)
|
||||
main:getDeepObject("textfieldAnimLoseFocus"):cancel()
|
||||
main:getDeepObject("textfieldAnimFocus"):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("onTextfieldLoseFocus", function()
|
||||
main:getDeepObject("coolTextfield"):setForeground(colors.gray)
|
||||
main:getDeepObject("textfieldAnimFocus"):cancel()
|
||||
main:getDeepObject("textfieldAnimLoseFocus"):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("makeButtonVisible", function()
|
||||
main:getDeepObject("showAnimBtn1"):show()
|
||||
main:getDeepObject("showAnimBtn2"):show()
|
||||
main:getDeepObject("showAnimBtn3"):show()
|
||||
end)
|
||||
|
||||
basalt.setVariable("dragPosition", function(ob, ev, bt, x, y, dragStartX, dragStartY, mouseX, mouseY)
|
||||
ob:setPosition(x, y)
|
||||
end)
|
||||
|
||||
|
||||
local function inject(prog, key)
|
||||
local events = prog:getQueuedEvents()
|
||||
table.insert(events, 1, {event="key", args = {key}})
|
||||
prog:injectEvents(events)
|
||||
prog:updateQueuedEvents({})
|
||||
end
|
||||
|
||||
basalt.setVariable("p3Up", function()
|
||||
local program = main:getDeepObject("program3")
|
||||
inject(program, keys.w)
|
||||
end)
|
||||
|
||||
basalt.setVariable("p3Down", function()
|
||||
local program = main:getDeepObject("program3")
|
||||
inject(program, keys.s)
|
||||
end)
|
||||
|
||||
basalt.setVariable("p3Left", function()
|
||||
local program = main:getDeepObject("program3")
|
||||
inject(program, keys.a)
|
||||
end)
|
||||
|
||||
basalt.setVariable("p3Right", function()
|
||||
local program = main:getDeepObject("program3")
|
||||
inject(program, keys.d)
|
||||
end)
|
||||
|
||||
basalt.setVariable("noDrag", function(self)
|
||||
return false
|
||||
end)
|
||||
|
||||
basalt.setVariable("openSidebar", function(self)
|
||||
main:addAnimation():setObject(main:getDeepObject("sidebar")):setAutoDestroy():move(-12,1,1):play()
|
||||
end)
|
||||
basalt.setVariable("closeSidebar", function(self)
|
||||
main:addAnimation():setObject(main:getDeepObject("sidebar")):setAutoDestroy():move(2,1,1):play()
|
||||
end)
|
||||
|
||||
basalt.setVariable("progressTheProgressbar", function()
|
||||
os.sleep(1)
|
||||
local progressbar = main:getDeepObject("progressBar")
|
||||
local progress = 0
|
||||
while true do
|
||||
progressbar:setProgress(progress)
|
||||
progress = progress+0.25
|
||||
os.sleep(1)
|
||||
end
|
||||
end)
|
||||
|
||||
main = basalt.createFrame():addLayout("basaltPreview2.xml")
|
||||
|
||||
basalt.autoUpdate()
|
||||
@@ -1,209 +0,0 @@
|
||||
<frame id="example1" width="parent.w" height="parent.h" bg="lightGray" scrollable="true">
|
||||
<label text="Objects" font="2" x="16" y="3" />
|
||||
<button onClick="buttonColor" onClick="ex2" anchor="topRight" height="1" width="8" x="-7" y="2" text="Next" />
|
||||
<button onDrag="dragPosition" x="2" y="6" width="parent.w/2-2" height="5" />
|
||||
<button onDrag="dragPosition" x="parent.w/2+1" y="6" width="parent.w/2-2" height="5" />
|
||||
<frame y="13" x="2" width="parent.w/2-2" height="16" bg="black" scrollable="true">
|
||||
<button onClick="buttonColor" width="parent.w-2" x="2" y="2" text="Example Button 1" />
|
||||
<button onClick="buttonColor" width="parent.w-2" x="2" y="6" text="Example Button 2" />
|
||||
<button onClick="buttonColor" width="parent.w-2" x="2" y="10" text="Example Button 3" />
|
||||
<button onClick="buttonColor" width="parent.w-2" x="2" y="14" text="Example Button 4" />
|
||||
<button onClick="buttonColor" width="parent.w-2" x="2" y="18" text="Example Button 5" />
|
||||
<button onClick="buttonColor" width="parent.w-2" x="2" y="22" text="Example Button 6" />
|
||||
</frame>
|
||||
<frame y="13" x="parent.w/2+1" width="parent.w/2-2" height="16" bg="black" scrollable="true">
|
||||
<label x="2" y="2" text="Radios and Checkboxes:" fg="lightGray" />
|
||||
<radio x="2" y="4" bg="gray" fg="lightGray" boxBG="black" boxFG="lightGray" selectionBG="black" inactiveBoxBG="black">
|
||||
<item><text>Radio 1</text><x>2</x><y>1</y><bg>black</bg></item>
|
||||
<item><text>Radio 2</text><x>2</x><y>3</y><bg>black</bg></item>
|
||||
<item><text>Radio 3</text><x>2</x><y>5</y><bg>black</bg></item>
|
||||
<item><text>Radio 4</text><x>2</x><y>7</y><bg>black</bg></item>
|
||||
<item><text>Radio 5</text><x>2</x><y>9</y><bg>black</bg></item>
|
||||
</radio>
|
||||
<checkbox x="3" y="15" /><label x="5" y="15" text="Checkbox 1" fg="lightGray" />
|
||||
<checkbox x="3" y="17" /><label x="5" y="17" text="Checkbox 2" fg="lightGray" />
|
||||
<checkbox x="3" y="19" /><label x="5" y="19" text="Checkbox 3" fg="lightGray" />
|
||||
<checkbox x="3" y="21" /><label x="5" y="21" text="Checkbox 4" fg="lightGray" />
|
||||
</frame>
|
||||
<progressbar onChange="progressChange" width="parent.w-2" height="3" x="2" y="30" id="progressBar" />
|
||||
<label x="parent.w/2-7" y="31" zIndex="6" bg="false" text="Progressbar Example" fg="lightGray" />
|
||||
<label id="progressLabel" x="3" y="31" zIndex="6" bg="false" text="0%" fg="lightGray" />
|
||||
<thread thread="progressTheProgressbar" start="true" />
|
||||
<frame zIndex="16" y="34" x="4" width="32" height="12" movable="true" bar="true" barText="Movable Frame" barBG="black" barFG="lightGray" shadow="true">
|
||||
<label x="2" y="3" text="Input:" fg="lightGray" />
|
||||
<input default="Default Text" defaultFG="gray" width="parent.w-2" x="2" y="5" bg="black" fg="lightGray" />
|
||||
<input default="Only numbers" defaultFG="gray" width="parent.w-2" x="2" y="7" type="number" bg="black" fg="lightGray" />
|
||||
<input default="Password" defaultFG="gray" width="parent.w-2" x="2" y="9" type="password" bg="black" fg="lightGray" />
|
||||
</frame>
|
||||
<frame zIndex="16" y="36" x="6" width="32" height="12" movable="true" bar="true" barText="Movable Frame 2" barBG="black" barFG="lightGray" border="true" borderTop="false">
|
||||
<label x="2" y="3" text="Dropdowns, Lists and Menubars" fg="lightGray" />
|
||||
<dropdown x="2" y="5" bg="black" fg="lightGray">
|
||||
<item><text>Entry 1</text></item>
|
||||
<item><text>Entry 2</text></item>
|
||||
<item><text>Entry 3</text></item>
|
||||
<item><text>Entry 4</text></item>
|
||||
<item><text>Entry 5</text></item>
|
||||
<item><text>Entry 6</text></item>
|
||||
<item><text>Entry 7</text></item>
|
||||
<item><text>Entry 8</text></item>
|
||||
</dropdown>
|
||||
<list x="parent.w/2" y="5" width="parent.w/2-1" bg="black" fg="gray" selectionFG="lightGray">
|
||||
<item><text>Entry 1</text></item>
|
||||
<item><text>Entry 2</text></item>
|
||||
<item><text>Entry 3</text></item>
|
||||
<item><text>Entry 4</text></item>
|
||||
<item><text>Entry 5</text></item>
|
||||
<item><text>Entry 6</text></item>
|
||||
<item><text>Entry 7</text></item>
|
||||
<item><text>Entry 8</text></item>
|
||||
</list>
|
||||
<menubar x="2" y="1" anchor="bottomLeft" width="parent.w-2" bg="black" fg="gray" selectionFG="lightGray" scrollable="true">
|
||||
<item><text>Entry 1</text></item>
|
||||
<item><text>Entry 2</text></item>
|
||||
<item><text>Entry 3</text></item>
|
||||
<item><text>Entry 4</text></item>
|
||||
<item><text>Entry 5</text></item>
|
||||
<item><text>Entry 6</text></item>
|
||||
<item><text>Entry 7</text></item>
|
||||
<item><text>Entry 8</text></item>
|
||||
</menubar>
|
||||
</frame>
|
||||
<button onClick="buttonColor" onClick="ex1Top" x="parent.w-12" y="48" text="Top" />
|
||||
</frame>
|
||||
<frame id="example3" x="parent.w*2+1" width="parent.w" height="parent.h" bg="lightGray" >
|
||||
<label text="Editor" font="2" x="16" y="3" />
|
||||
<textfield x="2" y="6" width="parent.w-2" height="parent.h-7"/>
|
||||
<frame ignoreOffset="true" id="sidebar" anchor="topRight" x="3" width="14" height="parent.h" bg="black" >
|
||||
<button onClick="buttonColor" onClick="closeSidebar" anchor="bottomLeft" width="5" height="1" x="1" y="1" fg="black" bg="gray" text="Close" />
|
||||
<button onClick="buttonColor" onClick="e1" onClick="closeSidebar" width="parent.w-2" x="2" y="2" text="Example 1" />
|
||||
<button onClick="buttonColor" onClick="e2" onClick="closeSidebar" width="parent.w-2" x="2" y="6" text="Example 2" />
|
||||
<button onClick="buttonColor" onClick="e3" onClick="closeSidebar" width="parent.w-2" x="2" y="10" text="Example 3" />
|
||||
</frame>
|
||||
<textfield x="2" y="parent.h+2" width="parent.w-2" height="parent.h-3">
|
||||
<keywords>
|
||||
<purple>
|
||||
<keyword>if</keyword>
|
||||
<keyword>then</keyword>
|
||||
<keyword>else</keyword>
|
||||
<keyword>elseif</keyword>
|
||||
<keyword>repeat</keyword>
|
||||
<keyword>do</keyword>
|
||||
<keyword>while</keyword>
|
||||
<keyword>end</keyword>
|
||||
<keyword>function</keyword>
|
||||
<keyword>for</keyword>
|
||||
</purple>
|
||||
<blue>
|
||||
<keyword>local</keyword>
|
||||
<keyword>true</keyword>
|
||||
<keyword>false</keyword>
|
||||
<keyword>nil</keyword>
|
||||
</blue>
|
||||
<yellow>
|
||||
<keyword>print</keyword>
|
||||
<keyword>pairs</keyword>
|
||||
<keyword>ipairs</keyword>
|
||||
</yellow>
|
||||
</keywords>
|
||||
<rules>
|
||||
<rule>
|
||||
<pattern>%d</pattern>
|
||||
<fg>lightBlue</fg>
|
||||
</rule>
|
||||
<rule>
|
||||
<pattern>%"%a+%"</pattern>
|
||||
<fg>red</fg>
|
||||
</rule>
|
||||
<rule>
|
||||
<pattern>[-]+[%w*%s*%p*]*</pattern>
|
||||
<fg>green</fg>
|
||||
</rule>
|
||||
</rules>
|
||||
</textfield>
|
||||
|
||||
<textfield id="coolTextfield" onGetFocus="onTextfieldFocus" onLoseFocus="onTextfieldLoseFocus" x="2" y="parent.h*2+2" width="20" height="3" bg="black" fg="gray">
|
||||
<lines>
|
||||
<line>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna </line>
|
||||
<line>aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata </line>
|
||||
<line>sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor </line>
|
||||
<line>invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet</line>
|
||||
<line>clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</line>
|
||||
</lines>
|
||||
</textfield>
|
||||
<button id="anotherRandomButton" onClick="buttonColor" x="coolTextfield.x" y="coolTextfield.y + coolTextfield.h + 1" text="Button" />
|
||||
<button onClick="buttonColor" x="coolTextfield.x + coolTextfield.w + 2" y="coolTextfield.y" text="Button" />
|
||||
|
||||
|
||||
<animation id="textfieldAnimFocus" object="coolTextfield"><size width="40" height="12" duration="1"/></animation>
|
||||
<animation id="textfieldAnimLoseFocus" object="coolTextfield"><size width="20" height="3" duration="1"/></animation>
|
||||
<button ignoreOffset="true" onClick="buttonColor" onClick="openSidebar" anchor="bottomRight" width="5" height="1" x="-3" y="1" text="Open" />
|
||||
<button onClick="buttonColor" onClick="ex2" x="2" y="2" width="8" height="1" text="Back" />
|
||||
<button onClick="buttonColor" onClick="ex4" anchor="topRight" x="-7" y="2" width="8" height="1" text="Next" />
|
||||
</frame>
|
||||
|
||||
<frame zIndex="17" id="example4" x="parent.w*3+1" width="parent.w" height="parent.h" bg="lightGray" >
|
||||
<label text="Animations" font="2" x="16" y="3" />
|
||||
<button onClick="buttonColor" onClick="ex3" x="2" y="2" width="8" height="1" text="Back" />
|
||||
|
||||
|
||||
<frame id="showAnimFrame1" x="15" y="30" width="2" height="2" bg="black" >
|
||||
<label id="animFrameLabel" text="Hello" x="-5" y="-1" fg="lightGray" />
|
||||
<button anchor="bottomLeft" id="animFrameBtn1" text="Cool" x="-5" y="15" fg="lightGray" bg="gray" />
|
||||
<button anchor="bottomRight" id="animFrameBtn2" text="Button" x="50" y="15" fg="lightGray" bg="gray" />
|
||||
</frame>
|
||||
|
||||
<animation id="animation19" onDone="enableStartButton" object="animationButton"><move x="22" y="10" duration="0.5"/> <size width="12" height="3" duration="1"/></animation>
|
||||
<animation id="animation18" onDone="#animation19" object="showAnimFrame1"><move x="50" y="20" duration="0.5"/><size width="2" height="2" duration="0.5"/></animation>
|
||||
<animation id="animation17" onDone="#animation18" object="showAnimFrame1"><move x="5" y="6" duration="1"/><size width="30" height="8" duration="1"/></animation>
|
||||
<animation id="animation16" onDone="#animation17" object="showAnimFrame1"><move x="2" y="6" duration="1"/><size width="48" height="13" duration="1"/></animation>
|
||||
<animation id="animation15" onDone="#animation16" object="showAnimFrame1"><size width="36" height="10" duration="1"/></animation>
|
||||
<animation id="animation14" onDone="#animation15" object="animFrameBtn2"><move x="-12" y="-2" duration="0.7"/></animation>
|
||||
<animation id="animation13" onDone="#animation14" object="animFrameBtn1"><move x="3" y="-2" duration="0.7"/></animation>
|
||||
<animation id="animation12" onDone="#animation13" object="animFrameLabel"><move x="3" y="3" duration="1"/><text duration="2"><text>Hello, i</text><text>Hello, i am</text><text>Hello, i am just</text><text>Hello, i am just a</text><text>Hello, i am just a label</text></text></animation>
|
||||
<animation id="animation11" onDone="#animation12" object="showAnimFrame1"><move x="5" y="6" duration="1"/><size width="42" height="12" duration="1"/></animation>
|
||||
|
||||
<button id="showAnimBtn1" x="25" y="-6" width="16" text="Button 1" visible="false" />
|
||||
<button id="showAnimBtn2" x="0" y="-6" width="16" text="Button 2" visible="false" />
|
||||
<button id="showAnimBtn3" x="50" y="-6" width="16" text="Button 3" visible="false" />
|
||||
<animation id="animation10" onDone="#animation11" object="showAnimBtn1"><move x="60" y="6" duration="1"/><size width="2" height="2" duration="1"/></animation>
|
||||
<animation id="animation9" onDone="#animation10" object="showAnimBtn1"><move x="5" y="6" duration="0.5"/><size width="42" height="9" duration="1"/></animation>
|
||||
<animation id="btn2PosAnim2" object="showAnimBtn2"><move x="-15" y="22" duration="0.5"/></animation>
|
||||
<animation id="btn3PosAnim2" object="showAnimBtn3"><move x="55" y="22" duration="0.5"/></animation>
|
||||
<animation mode="linear" id="animation8" onDone="#animation9" onDone="#btn2PosAnim2" onDone="#btn3PosAnim2" object="showAnimBtn3"><textColor duration="1"><color>yellow</color><color>green</color><color>red</color><color>blue</color><color>purple</color><color>orange</color><color>brown</color><color>black</color></textColor>
|
||||
<background duration="3"><color>red</color><color>blue</color><color>green</color><color>purple</color><color>orange</color><color>black</color><color>lightBlue</color><color>gray</color></background></animation>
|
||||
<animation mode="linear" id="animation7" object="showAnimBtn2"><textColor duration="3"><color>yellow</color><color>green</color><color>red</color><color>blue</color><color>purple</color><color>orange</color><color>brown</color><color>black</color></textColor></animation>
|
||||
<animation mode="linear" id="animation6" object="showAnimBtn1"><background duration="3"><color>red</color><color>blue</color><color>green</color><color>purple</color><color>orange</color><color>black</color><color>brown</color><color>gray</color></background></animation>
|
||||
<animation id="btn3PosAnim" onDone="#animation6" object="showAnimBtn3"><move x="9" y="14" duration="0.8"/><size width="35" height="3" duration="1.2"/></animation>
|
||||
<animation id="btn2PosAnim" onDone="#animation7" object="showAnimBtn2"><move x="9" y="10" duration="0.6"/><size width="35" height="3" duration="1.2"/></animation>
|
||||
<animation id="btn1PosAnim" onDone="#animation8" object="showAnimBtn1"><move x="9" y="6" duration="0.4"/><size width="35" height="3" duration="1.2"/></animation>
|
||||
<animation mode="linear" id="animation4" onDone="#btn1PosAnim" onDone="#btn2PosAnim" onDone="#btn3PosAnim" onDone="makeButtonVisible" object="animationButton"><move x="-15" y="4" duration="0.5"/><size width="1" height="1" duration="0.5"/></animation>
|
||||
<animation mode="linear" id="animation3" onDone="#animation4" object="animationButton"><move x="12" y="14" duration="0.7"/></animation>
|
||||
<animation mode="linear" id="animation2" onDone="#animation3" object="animationButton"><move x="32" y="16" duration="1"/></animation>
|
||||
<animation mode="linear" id="animation1" onStart="disableStartButton" onDone="#animation2" object="animationButton"><move x="34" y="9" duration="1.2"/></animation>
|
||||
|
||||
<button id="animationButton" onClick="startAnimation" onClick="buttonColor" x="22" y="10" text="Start" />
|
||||
</frame>
|
||||
|
||||
<frame id="example2" x="parent.w+1" width="parent.w" height="parent.h" bg="lightGray" >
|
||||
<label text="Program" font="2" x="16" y="3" />
|
||||
<program x="2" y="6" width="parent.w-12" height="parent.h-6" path="rom/programs/shell.lua" execute="true" />
|
||||
<button onClick="buttonColor" onClick="p2" anchor="bottomRight" width="8" x="-7" y="-2" text="Down" />
|
||||
<frame movable="true" bar="true" barText="Program" x="2" y="parent.h+2" width="28" height="12" bg="black" >
|
||||
<program id="program2" x="1" y="2" width="parent.w" height="parent.h-1" path="rom/programs/fun/worm.lua" execute="true" />
|
||||
</frame>
|
||||
<frame movable="true" bar="true" barText="Program" x="6" y="parent.h+4" width="28" height="12" bg="black" >
|
||||
<program id="program2" x="1" y="2" width="parent.w" height="parent.h-1" path="rom/programs/shell.lua" execute="true" />
|
||||
</frame>
|
||||
<button onClick="buttonColor" onClick="p1" width="8" x="parent.w-8" y="parent.h+2" text="Up" />
|
||||
<button onClick="buttonColor" onClick="p3" width="8" x="parent.w-8" y="parent.h*2-3" text="Down" />
|
||||
<button onClick="buttonColor" onClick="p2" width="8" x="parent.w-8" y="parent.h*2+2" text="Up" />
|
||||
<program id="program3" onClick="test" x="2" y="parent.h*2+2" width="parent.w-12" height="parent.h-2" path="rom/programs/fun/worm.lua" execute="true" />
|
||||
<button onClick="buttonColor" onClick="pauseP3" width="8" x="parent.w-8" y="parent.w*2+7" text="Pause" />
|
||||
<button onClick="buttonColor" onClick="p3Up" width="1" height="1" x="parent.w-5" y="parent.h*2+11" text="^" />
|
||||
<button onClick="buttonColor" onClick="p3Down" width="1" height="1" x="parent.w-5" y="parent.h*2+13" text="v" />
|
||||
<button onClick="buttonColor" onClick="p3Left" width="1" height="1" x="parent.w-7" y="parent.h*2+12" text="<" />
|
||||
<button onClick="buttonColor" onClick="p3Right" width="1" height="1" x="parent.w-3" y="parent.h*2+12" text=">" />
|
||||
|
||||
<button onClick="buttonColor" onClick="ex1" x="2" y="2" width="8" height="1" text="Back" />
|
||||
<button onClick="buttonColor" onClick="ex3" anchor="topRight" x="-7" y="2" width="8" height="1" text="Next" />
|
||||
</frame>
|
||||
@@ -1,291 +0,0 @@
|
||||
local bot_id = "" -- put the bot id between the ""!
|
||||
local servers = { -- setup the server/channels here, look at the example.
|
||||
[""] = {
|
||||
"",
|
||||
},
|
||||
|
||||
--[[ Example:
|
||||
["SERVER_ID"] = {
|
||||
"CHANNEL_ID",
|
||||
"CHANNEL_ID",
|
||||
"CHANNEL_ID",
|
||||
},
|
||||
["SERVER_ID"] = {
|
||||
"CHANNEL_ID",
|
||||
"CHANNEL_ID",
|
||||
"CHANNEL_ID",
|
||||
},
|
||||
]]
|
||||
}
|
||||
|
||||
if(bot_id=="")then
|
||||
error("Please setup the bot id and servers/channels first!")
|
||||
end
|
||||
|
||||
--Basalt configurated installer
|
||||
local filePath = "basalt.lua" --here you can change the file path default: basalt.lua
|
||||
if not(fs.exists(filePath))then
|
||||
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
|
||||
end
|
||||
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
|
||||
|
||||
local main = basalt.createFrame():setBackground(colors.lightGray)
|
||||
local loginFrame = main:addFrame():setBackground(colors.lightGray)
|
||||
local messageFrameList = main:addFrame():setPosition("parent.w+1", 1):setBackground(colors.black):setScrollable(true):setImportantScroll(true)
|
||||
|
||||
local refreshRate = 2
|
||||
local messageFrames = {}
|
||||
local availableGuilds = {}
|
||||
|
||||
local channel_id = ""
|
||||
for k,v in pairs(servers)do
|
||||
if(v[1]~=nil)then
|
||||
channel_id = v[1]
|
||||
end
|
||||
break
|
||||
end
|
||||
|
||||
local function getAllGuilds(bot)
|
||||
local content = http.get("https://discord.com/api/users/@me/guilds", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
|
||||
if(content~=nil)then
|
||||
return textutils.unserializeJSON(content.readAll())
|
||||
end
|
||||
end
|
||||
|
||||
local function getAllChannels(bot, guild)
|
||||
local content = http.get("https://discord.com/api/guilds/"..guild.."/channels", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
|
||||
if(content~=nil)then
|
||||
local t = {}
|
||||
for k,v in pairs(textutils.unserializeJSON(content.readAll()))do
|
||||
table.insert(t, v.position, v)
|
||||
end
|
||||
return t
|
||||
end
|
||||
end
|
||||
|
||||
local splitString = function(str, sep)
|
||||
if sep == nil then
|
||||
sep = "%s"
|
||||
end
|
||||
local t={}
|
||||
for v in string.gmatch(str, "([^"..sep.."]+)") do
|
||||
table.insert(t, v)
|
||||
end
|
||||
if(#t==0)then table.insert(t,str) end
|
||||
return t
|
||||
end
|
||||
|
||||
local function createText(str, width)
|
||||
local uniqueLines = splitString(str, "\n")
|
||||
local lines = {}
|
||||
for k,v in pairs(uniqueLines)do
|
||||
local line = ""
|
||||
local words = splitString(v, " ")
|
||||
for a,b in pairs(words)do
|
||||
if(#line+#b <= width)then
|
||||
line = line=="" and b or line.." "..b
|
||||
if(a==#words)then table.insert(lines, line) end
|
||||
else
|
||||
table.insert(lines, line)
|
||||
line = b:sub(1,width)
|
||||
if(a==#words)then table.insert(lines, line) end
|
||||
end
|
||||
end
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
local maxOffset = 0
|
||||
local autoOffset = true
|
||||
local function newMessage(position, msg, username, sendTime)
|
||||
local lines = createText(msg, messageFrameList:getWidth()-5)
|
||||
if(messageFrames[position]==nil)then
|
||||
if(messageFrames[position-1]~=nil)then
|
||||
messageFrames[position] = messageFrameList:addFrame("message"..tostring(position)):setPosition(2, "message"..(position-1)..".y + message"..(position-1)..".h")
|
||||
else
|
||||
messageFrames[position] = messageFrameList:addFrame("message"..tostring(position)):setPosition(2, 1)
|
||||
end
|
||||
messageFrames[position]:addLabel("title")
|
||||
messageFrames[position]:addLabel("body")
|
||||
end
|
||||
maxOffset = maxOffset + #lines+3
|
||||
if(autoOffset)then
|
||||
messageFrameList:setOffset(0, maxOffset - messageFrameList:getHeight()+1)
|
||||
end
|
||||
messageFrames[position]:setSize("parent.w-1", #lines+3):setBackground(colors.black)
|
||||
messageFrames[position]:getObject("title"):setSize("parent.w-2", 1):setPosition(2,1):setText(username):setForeground(colors.lightGray):setBackground(colors.gray)
|
||||
messageFrames[position]:getObject("body"):setSize("parent.w-2", #lines+1):setPosition(2,3):setText(msg):setForeground(colors.lightGray)
|
||||
end
|
||||
|
||||
local function updateDiscordMessages(channel, bot)
|
||||
if(channel~=nil)and(bot~=nil)then
|
||||
currentMessages = {}
|
||||
local content = http.get("https://discord.com/api/channels/"..channel.."/messages?limit=25", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
|
||||
if(content~=nil)then
|
||||
local t = textutils.unserializeJSON(content.readAll())
|
||||
local tR = {}
|
||||
for i=#t, 1, -1 do
|
||||
tR[#tR+1] = t[i]
|
||||
end
|
||||
for k,v in pairs(tR)do
|
||||
newMessage(k, v.content, v.author.username, v.time)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local animations = {}
|
||||
|
||||
local function offsetAnimation(obj, x, y, t)
|
||||
if(animations[obj:getName()]~=nil)then animations[obj:getName()]:cancel() end
|
||||
animations[obj:getName()] = main:addAnimation():setAutoDestroy(true):setObject(obj):offset(x, y, t or 1):play()
|
||||
end
|
||||
|
||||
local function positionAnimation(obj, x, y, t)
|
||||
if(animations[obj:getName()]~=nil)then animations[obj:getName()]:cancel() end
|
||||
animations[obj:getName()] = main:addAnimation():setAutoDestroy(true):setObject(obj):move(x, y, t or 1):play()
|
||||
end
|
||||
|
||||
local sideBar = messageFrameList:addFrame():setPosition(-18, 1):setSize(20, "parent.h"):setZIndex(17):ignoreOffset():setScrollable(true):setImportantScroll(true)
|
||||
sideBar:addButton():setText("Back"):setForeground(colors.lightGray):setBackground(colors.black):setPosition(3,2):setSize("parent.w - 4", 3):onClick(function()
|
||||
offsetAnimation(main, 0, 0)
|
||||
positionAnimation(sideBar, -18, 1)
|
||||
end)
|
||||
sideBar:addLabel():setText("Channels:"):setForeground(colors.black):setPosition(2,6)
|
||||
sideBar:onClick(function(self, event)
|
||||
if(event=="mouse_click")then
|
||||
positionAnimation(self, 1, 1)
|
||||
messageFrameList:setImportantScroll(false)
|
||||
end
|
||||
end)
|
||||
sideBar:onLoseFocus(function()
|
||||
positionAnimation(sideBar, -18, 1)
|
||||
messageFrameList:setImportantScroll(true)
|
||||
end)
|
||||
|
||||
|
||||
local newTextFrame = messageFrameList:addFrame():setSize("parent.w - 4", 10):setPosition(3, 1):setZIndex(16):ignoreOffset():setBackground(colors.gray):setAnchor("bottomLeft")
|
||||
local msgInfo = newTextFrame:addLabel():setText("Click here to write a message")
|
||||
|
||||
local messageField = newTextFrame:addTextfield():setSize("parent.w-2", "parent.h-4"):setPosition(2,3):setBackground(colors.lightGray)
|
||||
newTextFrame:onClick(function(self, event)
|
||||
if(event=="mouse_click")then
|
||||
positionAnimation(self, 3, -8, 0.5)
|
||||
messageFrameList:setImportantScroll(false)
|
||||
msgInfo:setText("New Message:")
|
||||
end
|
||||
end)
|
||||
|
||||
messageFrameList:onScroll(function()
|
||||
local xO, yO = messageFrameList:getOffset()
|
||||
messageFrameList:getMaxScroll()
|
||||
if(yO==messageFrameList:getMaxScroll())then
|
||||
autoOffset = true
|
||||
else
|
||||
autoOffset = false
|
||||
end
|
||||
end)
|
||||
|
||||
local function messageBoxLoseFocus()
|
||||
positionAnimation(newTextFrame, 3, 1, 0.5)
|
||||
messageFrameList:setImportantScroll(true)
|
||||
msgInfo:setText("Click here to write a message")
|
||||
messageField:clear()
|
||||
end
|
||||
|
||||
newTextFrame:addButton():setText("Cancel"):setAnchor("bottomLeft"):setBackground(colors.black):setForeground(colors.lightGray):setSize(12,1):setPosition(2,1):onClick(function()
|
||||
messageBoxLoseFocus()
|
||||
end)
|
||||
|
||||
newTextFrame:onLoseFocus(messageBoxLoseFocus)
|
||||
|
||||
loginFrame:addLabel():setAnchor("center"):setPosition(-2, -1):setText("Username:")
|
||||
local nameInput = loginFrame:addInput():setAnchor("center"):setPosition(3,0):setBackground(colors.black):setForeground(colors.lightGray):setSize(16,1):setDefaultText("Username...", colors.gray)
|
||||
|
||||
local serverList = loginFrame:addList():setPosition(3, 6):setSize(16, 10)
|
||||
local channelRadio = sideBar:addRadio():setForeground(colors.black):setBackground(colors.gray):setSelectedItem(colors.gray, colors.lightGray):setActiveSymbol(" ")
|
||||
local channelObjects = {}
|
||||
local updateChannels = basalt.shedule(function()
|
||||
if(bot_id~=nil)then
|
||||
for k,v in pairs(channelObjects)do
|
||||
sideBar:removeObject(v)
|
||||
end
|
||||
channelObjects = {}
|
||||
if(serverList:getValue().args~=nil)then
|
||||
local y = 8
|
||||
local maxScroll = 2
|
||||
for k,v in pairs(servers[serverList:getValue().args[1]])do
|
||||
local content = http.get("https://discord.com/api/channels/"..v, {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot_id})
|
||||
local channel = textutils.unserializeJSON(content.readAll())
|
||||
if(channel~=nil)then
|
||||
channelRadio:addItem("#"..channel.name,1, y, nil,nil,v)
|
||||
y = y + 1
|
||||
maxScroll = maxScroll + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
serverList:onChange(updateChannels)
|
||||
basalt.shedule(function()
|
||||
if(bot_id~=nil)then
|
||||
for k,v in pairs(servers)do
|
||||
local content = http.get("https://discord.com/api/guilds/"..k, {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot_id})
|
||||
local guild = textutils.unserializeJSON(content.readAll())
|
||||
if(guild~=nil)then
|
||||
serverList:addItem(guild.name,nil,nil,k)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)()
|
||||
|
||||
updateChannels()
|
||||
|
||||
|
||||
|
||||
channelRadio:onChange(function(self)
|
||||
local val = self:getValue()
|
||||
if(val~=nil)and(val.args[1]~=nil)then
|
||||
channel_id = val.args[1]
|
||||
end
|
||||
end)
|
||||
|
||||
loginFrame:addButton():setAnchor("bottomRight"):setPosition(-10, -2):setSize(11,3):setText("Login"):onClick(function()
|
||||
offsetAnimation(main, main:getWidth(), 0)
|
||||
end)
|
||||
loginFrame:addLabel():setPosition(3, 5):setText("Servers:")
|
||||
|
||||
|
||||
|
||||
local function sendDiscordMessage(msg, channel, bot)
|
||||
if(channel~=nil)and(bot~=nil)then
|
||||
if(nameInput:getValue()~="")then
|
||||
msg = string.gsub(msg, "\n", "\\n")
|
||||
http.post("https://discord.com/api/channels/"..channel.."/messages", '{ "content": "['..nameInput:getValue()..']: '..msg..'" }', {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newTextFrame:addButton():setText("Send"):setAnchor("bottomRight"):setBackground(colors.black):setForeground(colors.lightGray):setSize(12,1):setPosition(-11,1)
|
||||
:onClick(function()
|
||||
local msg = table.concat(messageField:getLines(), "\n")
|
||||
if(#msg>0)then
|
||||
sendDiscordMessage(msg, channel_id, bot_id)
|
||||
end
|
||||
messageBoxLoseFocus()
|
||||
end)
|
||||
|
||||
local function refreshMessages()
|
||||
while true do
|
||||
maxOffset = 0
|
||||
updateDiscordMessages(channel_id, bot_id)
|
||||
maxOffset = maxOffset - messageFrameList:getHeight()+1
|
||||
messageFrameList:setMaxScroll(maxOffset)
|
||||
sleep(refreshRate)
|
||||
end
|
||||
end
|
||||
|
||||
local thread = main:addThread():start(refreshMessages)
|
||||
|
||||
basalt.autoUpdate()
|
||||
@@ -1,51 +0,0 @@
|
||||
-- This is a example on how to use progressbars for energy. I used the Mekanism Ultimate Energy Cube.
|
||||
|
||||
|
||||
--Basalt configurated installer
|
||||
local filePath = "basalt.lua" --here you can change the file path default: basalt
|
||||
if not(fs.exists(filePath))then
|
||||
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
|
||||
end
|
||||
local basalt = require(filePath:gsub(".lua", ""))
|
||||
|
||||
local energyCube = peripheral.find("ultimateEnergyCube")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
|
||||
local progressText = main:addLabel()
|
||||
:setText(0)
|
||||
:setForeground(colors.gray)
|
||||
:setBackground(false)
|
||||
:setPosition(10, 3)
|
||||
:setZIndex(6)
|
||||
|
||||
local energyProgress = main:addProgressbar()
|
||||
:setSize(20,3)
|
||||
:setPosition(2,2)
|
||||
:setBackground(colors.black)
|
||||
:setProgressBar(colors.green)
|
||||
|
||||
energyProgress:onChange(function()
|
||||
local energy = tostring(energyCube.getEnergy())
|
||||
progressText:setText(energy)
|
||||
progressText:setPosition(energyProgress:getWidth()/2+1 - math.floor(energy:len()/2), 3)
|
||||
end)
|
||||
|
||||
|
||||
local function checkCurrentEnergy()
|
||||
while true do
|
||||
energyCube = peripheral.find("ultimateEnergyCube")
|
||||
if(energyCube~=nil)then
|
||||
local energyCalculation = energyCube.getEnergy() / energyCube.getMaxEnergy() * 100
|
||||
energyProgress:setProgress(energyCalculation)
|
||||
else
|
||||
energyProgress:setProgress(0)
|
||||
os.sleep(3)
|
||||
end
|
||||
os.sleep(1)
|
||||
end
|
||||
end
|
||||
|
||||
main:addThread():start(checkCurrentEnergy)
|
||||
|
||||
basalt.autoUpdate()
|
||||
@@ -1,49 +0,0 @@
|
||||
--Basalt configurated installer
|
||||
local filePath = "basalt.lua" --here you can change the file path default: basalt
|
||||
if not(fs.exists(filePath))then
|
||||
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
|
||||
end
|
||||
|
||||
-- toastonrye's example: Redstone Analog Output
|
||||
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
|
||||
local w, h = term.getSize() -- dimensions to use when drawing the sub frame
|
||||
|
||||
local main = basalt.createFrame()
|
||||
:show()
|
||||
:setBackground(colours.blue) -- using colours to easily determine what frame I'm in
|
||||
|
||||
local sub = main:addFrame()
|
||||
:setPosition(2,2)
|
||||
:setSize(w-2,h-2)
|
||||
:setBackground(colours.lightBlue)
|
||||
|
||||
local rFrame = sub:addFrame("redstoneFrame")
|
||||
:setPosition(1,1)
|
||||
:setSize(25,5)
|
||||
:setMovable(true)
|
||||
:setBackground(colours.red)
|
||||
|
||||
-- Redstone Analog Output
|
||||
local redstoneAnalog = rFrame:addLabel() -- label that displays the value of the slider & Redstone output
|
||||
:setPosition(18,3):setText("1")
|
||||
|
||||
redstone.setAnalogOutput("left", 1) -- initialize the redstone output to 1, to match the above label
|
||||
|
||||
rFrame:addLabel() -- draw a label on the frame
|
||||
:setText("Redstone Analog Output")
|
||||
:setPosition(1,2)
|
||||
|
||||
rFrame:addSlider()
|
||||
:setPosition(1,3)
|
||||
:onChange(function(self) -- when a player interacts with the slider, update the variable redstoneAnalog
|
||||
redstoneAnalog:setText(self:getValue())
|
||||
end)
|
||||
:setMaxValue(15) -- max value of the slider, default 8. Redstone has 15 levels (16 including 0)
|
||||
:setSize(15,1) -- draw the slider to this size, without this redstoneAnalog value can have decimals
|
||||
|
||||
redstoneAnalog:onChange(function(self) -- when the slider value changes, change the Redstone output to match
|
||||
redstone.setAnalogOutput("left", tonumber(self:getValue()))
|
||||
basalt.debug(self:getValue())
|
||||
end)
|
||||
|
||||
basalt.autoUpdate()
|
||||
@@ -1,38 +0,0 @@
|
||||
-- Hello, here is a small example on how to create resizeable frames, the default anchor (where you have to click on) will be bottom right.
|
||||
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
|
||||
local sub = main:addFrame() -- the frame we want to resize
|
||||
:setPosition(3,3)
|
||||
:setSize(25,8)
|
||||
:setMovable()
|
||||
:setBorder(colors.black)
|
||||
|
||||
sub:addLabel() -- the new way to create a bar on the top
|
||||
:setText("Topbar")
|
||||
:setSize("parent.w",1)
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.lightGray)
|
||||
|
||||
sub:addButton()
|
||||
:setAnchor("bottomRight")
|
||||
:setPosition(1, 1)
|
||||
:setText("/")
|
||||
:setSize(1,1)
|
||||
:onDrag(function(self, button, x, y, xOffset, yOffset)
|
||||
local w, h = sub:getSize()
|
||||
if(w-xOffset>5)and(h-yOffset>3)then -- dont allow it to be smaller than w5 and h3
|
||||
sub:setSize(-xOffset, -yOffset, true) -- x-/yOffset is always -1 0 or 1, true means add the value to the current size instead of set it
|
||||
end
|
||||
end)
|
||||
|
||||
sub:addButton() -- just a random button to show dynamic values
|
||||
:setPosition(2,3)
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.lightGray)
|
||||
:setSize("parent.w-2", 3) -- parent.w means get the parent's width which is the sub frame in this case, -2 means remove 2 from it's result. You could also use * / % or even math.random(12)
|
||||
|
||||
|
||||
basalt.autoUpdate()
|
||||
Reference in New Issue
Block a user