77 Commits
v1.7 ... master

Author SHA1 Message Date
Robert Jelic
14c0630c1e Added xml :loadLayoutFromString 2025-09-25 15:53:49 +02:00
Robert Jelic
64cb0d15e8 Update download.md
Updated install link
2025-04-06 01:15:52 +02:00
Robert Jelic
322ddb6158 Delete CNAME 2025-03-14 16:50:47 +01:00
Robert Jelic
c71557feb7 Small fix for programs 2025-02-15 18:12:08 +01:00
Robert Jelic
98b4191504 small fixxes for xml
Small fixxes for xml usage
2025-02-12 08:49:37 +01:00
quittung
8dd8e63d21 Fix typo in dynamic value syntax in Frame documentation (#112)
In Frame.md the dynamic values are surrounded by curly braces - "{parent.w-1}" instead of just "parent.w-1". This lead to the example code not running on any version of Basalt. 

I simply removed the curly braces in this file, not sure if that broke something else or if there are other files that need the same treatment.
2024-05-13 21:27:16 +02:00
Robert Jelic
28d35559c8 forgot to upload flexbox :x 2024-04-16 19:07:28 +02:00
Robert Jelic
f3eb0accf8 bugfix
Fixed :removeChild()
2024-04-16 19:02:54 +02:00
Robert Jelic
599edf55dd slider fix
small fixes for slider
2024-04-04 17:52:51 +02:00
Robert Jelic
303d0e65ff small fix
small fix for sliders throwing errors on creation
2024-03-24 04:00:58 +01:00
Robert Jelic
12e981a0e2 Small fix
Very small fix for onRelease events not registering a mouse_up event to it's parent container
2024-03-20 14:08:55 +01:00
Robert Jelic
ca2fd64302 Container removeChild fix
- fixed containers removeChild call
- fixed using remove on flexbox childrens
2024-03-20 00:51:12 +01:00
Robert Jelic
4fefe5734c fixes
Fixes for relase/latest version, latest now points to 1.7.0 again
2024-03-13 10:08:24 +01:00
Robert Jelic
8168fa4465 1.7 stuff
The master branch was reverted to 1.7 because it was very unstable (bugs and stuff that wasn't mentioned on the documentation page yet) - features will come back with 2.0

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

- small docs updates for 1.7
- removed the examples because the are outdated
2024-03-13 09:57:07 +01:00
Robert Jelic
33753f6d8f Update Progressbar.lua
small setProgressBar fix
2023-10-09 21:05:19 +02:00
cyberbit
1c7558d133 Fix typo in Graph/addDataPoint (#97) 2023-10-05 17:13:47 +02:00
Robert Jelic
8d4e96a128 Update Textfield.lua
Small fix
2023-09-22 06:53:18 +02:00
Robert Jelic
42aa1059cf Update main.lua
fixed basalt.getFrame(name)
2023-07-24 18:45:24 +02:00
Robert Jelic
a3886d34b0 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2023-07-06 00:32:00 +02:00
Robert Jelic
5f8cbc90f3 small docs fix
another small update for docus
2023-07-06 00:31:47 +02:00
Robert Jelic
82dcceda05 Update Treeview.lua
forgot to remove the if statement
2023-07-05 16:53:12 +02:00
Robert Jelic
8ebede1430 Update Treeview.lua 2023-07-05 16:50:41 +02:00
Robert Jelic
31cda3d672 small frames-docs update
updated frames example
fixed bug in process for programs
2023-07-05 15:49:52 +02:00
Robert Jelic
b794612017 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2023-07-02 03:35:34 +02:00
Robert Jelic
9aa3663f90 Fixes
MultiMonitor fix
Small fixes
2023-07-02 03:35:32 +02:00
Robert Jelic
71b4d6e01a Update Graph.lua
Small fix, removed hard cap and changed it to maxentries
2023-06-30 22:36:02 +02:00
Robert Jelic
2970451fc6 Update bigfonts.lua
fixed an issue when changing the text on while using bigfonts
2023-06-30 21:03:26 +02:00
Robert Jelic
193616c20d dyn value docs update 2023-06-29 16:25:33 +02:00
Robert Jelic
df40fb496c Updated release to 1.7.1 2023-06-29 16:09:16 +02:00
Robert Jelic
9dc7449ace Update main.lua
small version update (forgot to update..)
2023-06-29 16:06:47 +02:00
Robert Jelic
24b31a091a Fix
Small term size fix
2023-06-29 14:53:10 +02:00
Robert Jelic
45f4d99db1 Update Timer.lua
Small bugfix
2023-06-18 15:30:08 +02:00
Robert Jelic
fe9d1f44a1 Update Flexbox.lua
Small renaming fix
2023-06-17 23:17:41 +02:00
Robert Jelic
958b962ada Update Label.lua
Small fix when calculating the size for labels
2023-06-17 18:02:50 +02:00
Robert Jelic
cbe67c3919 Update bigfonts.lua
Size fix
2023-06-17 17:03:29 +02:00
Robert Jelic
63f88f8184 Small fixes
bigfonts crash fix
flexbox crash fix when using setJustifyContent
2023-06-17 16:31:00 +02:00
Robert Jelic
cc43817f34 Update dynamicValues.lua
Small fix-fix
2023-06-15 20:33:38 +02:00
Robert Jelic
c583eb666d Update dynamicValues.lua 2023-06-15 20:24:18 +02:00
Robert Jelic
f16e172fb1 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2023-06-15 18:22:45 +02:00
Robert Jelic
4d2aad4155 1.7.1
- Dyn Values Update
- Template Update
- Property System
- Texture System Update
2023-06-15 18:22:43 +02:00
Robert Jelic
dd7c26d4c3 Small bugfix
supporting \n for richtext wrapping
2023-06-13 21:10:59 +02:00
Robert Jelic
8f370a0106 Update bigfonts.lua
small fix when using setBackground after setFontSize
2023-06-10 15:25:34 +02:00
Robert Jelic
26567debd6 Small color fix for labels
fixed bug with foreground/background colors, when using xml
2023-06-08 09:13:03 +02:00
Marcus
af14c7b867 fix erroring when object has no parent (#94) 2023-06-08 08:47:33 +02:00
SeaSide53
1339337e6e Fixed typos and cleaned up code in the Images library (#93)
* Updated setTheme.md

* Updated 1.6 setTheme.md

* Fixed typo

* Cleaned up loadImage functions

* Changed it to use the new function

* More typos

---------

Co-authored-by: SeaSide53 <https://github.com/SeaSide53>
2023-06-04 15:53:19 +02:00
SeaSide53
84096eeca5 Updated links on the site not to point to 404. (#92)
* Updated setTheme.md

* Updated 1.6 setTheme.md

---------

Co-authored-by: SeaSide53 <https://github.com/SeaSide53>
2023-06-03 20:19:56 +02:00
Robert Jelic
5bbed5be5c Update Slider.lua
Small fix-fix
2023-06-03 14:14:55 +02:00
Robert Jelic
c945931c3c Update Slider.lua
Small fix for sliders
2023-06-03 14:14:25 +02:00
Sabine Lim
716debd419 Fix (#90) 2023-05-28 09:47:06 +02:00
Sabine Lim
f7e55c9f52 New Reactive system (#89)
Simplify

Move out shared code

Wrap render functions and event functions in transactions

Rename
2023-05-25 18:48:54 +02:00
Robert Jelic
555ab6217c Image Palette Fix
used wrong keys for palettes (color strings instead of 0-15)
2023-05-24 20:12:12 +02:00
Robert Jelic
5373dab682 Update Image.lua
Small mistake in images
2023-05-24 17:33:47 +02:00
Robert Jelic
de94f8266f Input paste
forgot to reimplement paste
2023-05-23 06:22:42 +02:00
Robert Jelic
d3db685573 Update Flexbox.md
Didn't want to remove this - oops!
2023-05-22 20:14:03 +02:00
Robert Jelic
cfb4a197cd Small docs update 2023-05-22 20:12:19 +02:00
Robert Jelic
4feeaa7942 Update Flexbox.lua
Fixed dynamic values not working
2023-05-22 17:28:17 +02:00
Robert Jelic
42972f3c2c Fixes
Small fixes
2023-05-22 17:03:31 +02:00
Robert Jelic
e67945fccf Updated (probably the last update for 1.7.0) 2023-05-21 20:02:31 +02:00
Robert Jelic
1b7f61323b Update Treeview.lua
Small change for treeview
2023-05-21 19:45:14 +02:00
Robert Jelic
2293aacdec Update Flexbox.lua
- Forgot to add getWrap
- Objects do have now the default size instead of using the basis value
- Forgot to update draw handler after something gets changed
2023-05-21 17:50:19 +02:00
Robert Jelic
2d9efbbb5a Update Textfield.lua
Fixed small bug when position is bigger than container size
Fixed paste event not working
2023-05-21 15:45:02 +02:00
Robert Jelic
9b0af8fcb3 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2023-05-21 15:24:41 +02:00
Robert Jelic
87105c4856 Small docs fix 2023-05-21 15:24:39 +02:00
Sabine Lim
a5e3191fde Fix (#88) 2023-05-20 15:04:42 +02:00
Robert Jelic
afe6639200 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2023-05-20 13:38:54 +02:00
Robert Jelic
01a8226721 Small rename 2023-05-20 13:38:52 +02:00
Sabine Lim
86972e21ab Change reactive to observable (#87)
* Change reactive to observable

* Fix typo
2023-05-20 13:26:00 +02:00
Robert Jelic
ad7a15af7c Release fix
Small fixes added to release
2023-05-20 10:43:40 +02:00
Robert Jelic
e22c2dfcd5 Update Flexbox.lua
Another small offset bug on very small flexbox sizes got fixed
2023-05-19 19:37:24 +02:00
Robert Jelic
1f9734ef5f Update Flexbox.lua
Another small mistake got fixed.
2023-05-19 19:21:46 +02:00
Robert Jelic
f4c469d64e Update Flexbox.lua
Fixed bug when resizing the flexbox
2023-05-19 19:11:45 +02:00
Robert Jelic
cfec78f6f7 Update Flexbox.lua
- fixed small offset calculation bug
2023-05-19 18:55:11 +02:00
Robert Jelic
67a408a4c8 Update Flexbox.lua 2023-05-19 17:21:39 +02:00
Robert Jelic
cbc8ca5c5b Update Flexbox.md
very small fix
2023-05-19 15:52:13 +02:00
Robert Jelic
631eef525c Flexbox docs
Updated the flexbox documentation for the current flexbox implementation
2023-05-19 15:50:05 +02:00
Robert Jelic
930d2ad0c8 Fixes
Small bug fixes
2023-05-19 12:41:59 +02:00
Robert Jelic
df1569af39 Added 1.7 release
Added v1.7 as the latest release
2023-05-19 11:38:27 +02:00
81 changed files with 10785 additions and 5941 deletions

View 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

View File

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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -5,11 +5,11 @@
The MIT License (MIT)
Copyright © 2022 Oliver Caha (9551Dev)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ?Software?), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED ?AS IS?, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local t_sort,t_cat,s_char = table.sort,table.concat,string.char
local function sort(a,b) return a[2] > b[2] end

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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()

View File

@@ -1 +0,0 @@
basalt.madefor.cc

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Binary file not shown.

View File

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

View File

@@ -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

View File

@@ -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:

View File

@@ -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.

View File

@@ -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

View File

@@ -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.

View File

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

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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>
![Flexbox example](../_media/flexbox-example.png "Flexbox example")
### 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>

View 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
```

View 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"
```

View 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
```

View 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
```

View 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
```

View 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"
```

View 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
```

View File

@@ -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")
```

View File

@@ -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")
```

View 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
```

View 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
```

View 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
```

View File

@@ -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

View 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.

View 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
```

View File

@@ -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>

View File

@@ -1,9 +1,9 @@
## add&#60;Object&#62;
Adds a new object. Don't use add&#60;Object&#62; 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&#60;Object&#62; 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

View File

@@ -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:

View File

@@ -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)
```

View File

@@ -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:
| | |
|---|---|

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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)
```

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -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()

View File

@@ -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()

View File

@@ -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="&#62;" />
<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>

View File

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

View File

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

View File

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

View File

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