142 Commits

Author SHA1 Message Date
Robert Jelic
bb921c57cd v1.6.5 2023-01-07 02:31:11 +01:00
Robert Jelic
2b85ab9746 Small fix
Forgot to check if program is active or not
2023-01-01 22:46:34 +01:00
Robert Jelic
29ebd7d4d7 Update Program.lua 2023-01-01 22:24:03 +01:00
Robert Jelic
8ab7bc4bde Auto Resizing fix
Forgot to move code for term_resize events to customEventHandler..
2023-01-01 22:21:52 +01:00
Robert Jelic
1b8f62ce41 schedule filter
Added event filters for schedules, now they should work properly.
2022-12-31 01:42:12 +01:00
Robert Jelic
61e38d89e8 Update images.lua 2022-12-30 02:30:48 +01:00
Robert Jelic
a0db5ecb61 Fixed nfp
Forgot i didn't add nfp support >.<
2022-12-30 02:14:58 +01:00
Robert Jelic
3ef7aa91bf Frame Resize
Forgot to add basalt_resize event for base frames
2022-12-26 15:51:25 +01:00
Robert Jelic
09e8589938 Update install.lua 2022-12-26 12:12:31 +01:00
Robert Jelic
e9aba2498b Small XML Fix
-fixed dyn value for width, height, x and y.
- added bgSymbol and bgSymbolColor for xml
- added texture for xml
2022-12-25 19:12:34 +01:00
Robert Jelic
20ceb6b56f Small event fix for programs 2022-12-25 16:56:13 +01:00
Robert Jelic
6d2956f3bf Updated image docs 2022-12-24 11:48:35 +01:00
Robert Jelic
91e42e096c Update utils.lua 2022-12-24 00:28:07 +01:00
Robert Jelic
5f00dfe401 Update Button.lua 2022-12-19 20:32:35 +01:00
Robert Jelic
2c4c059a70 Fixed a fix
Forgot i have to split by words and not just split when width has reached.
2022-12-18 00:43:09 +01:00
Robert Jelic
923b570d48 CreateText & splitString improvements
Improved the createText and splitString functions.
2022-12-18 00:31:52 +01:00
Robert Jelic
5499057e7e Merge pull request #43 from Erb3/path-6
✏️ Fix small typo ("sotred" -> "stored")
2022-12-16 18:31:21 +01:00
Erlend
d6091b312c ✏️ Fix small typo ("sotred" -> "stored") 2022-12-16 15:28:11 +01:00
Robert Jelic
f19c0ebb49 Update Frame.lua 2022-12-14 20:34:17 +01:00
Robert Jelic
01b83822b1 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-12-14 20:33:05 +01:00
Robert Jelic
c81f24cca2 Made a small mistake.. 2022-12-14 20:31:01 +01:00
Robert Jelic
ed894cb390 Monitor mouse event fix
Fixed mouse event's on monitor frames not working
2022-12-14 20:25:49 +01:00
Robert Jelic
355db9a82c Merge pull request #42 from Erb3/patch-3
📝 Fix a small typo in How-To.md
2022-12-14 20:10:28 +01:00
Erlend
8112378c70 📝 Fix a small typo in How-To.md
Fixed typo where it said `mainFrame` instead of `main`.
Reported by Broso56#0465 in the Discord.
2022-12-14 15:10:36 +01:00
Robert Jelic
a181496052 Update Frame.lua
This is just a small workaround for an actual bug - i need to figure out where it comes from.
2022-12-09 12:38:20 +01:00
Robert Jelic
636ed0001f Update init.lua
Accidentally changed package.path to nil in certain cases. Oopsie #fixed
2022-12-09 07:18:00 +01:00
Robert Jelic
0e3da7eda5 Update install.lua 2022-11-27 00:47:16 +01:00
Robert Jelic
3cf5adaef1 Add files via upload 2022-11-23 17:52:04 +01:00
Robert Jelic
c0fab23cef Small update to 1.6.4
- added bimg support
- reworked graphic object
- added blit for drawsystem (makes drawing bit faster
- added bimg lib
- reworked image object
- fixed thread bug
2022-11-23 17:32:06 +01:00
Robert Jelic
7609708507 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-11-23 17:11:33 +01:00
Robert Jelic
e2f2a2871d Improved event system
Updated the event system to the current dev branch
2022-11-23 17:11:21 +01:00
Robert Jelic
37dde881ad Small bugfix for frames
Small bugfix for frames when using setZIndex after objects got added. Reason was because the frame didn't add the events to it's parent.
2022-11-22 18:28:03 +01:00
Robert Jelic
8f2e191fe3 Border Bugfix for Buttons
Small visual fix for buttons, when using borders
2022-11-21 06:23:13 +01:00
Robert Jelic
15d8cb3781 Update Object.lua
cancels other events - should never have been there
2022-11-14 06:13:23 +01:00
Robert Jelic
8acb673f74 small hotfix for source project 2022-11-04 21:18:32 +01:00
Robert Jelic
cfdca639db Docs update
some docs update for the new installer
2022-10-31 17:30:11 +01:00
Robert Jelic
b34cdd8383 Small install.lua fix
Small fix to the web version
2022-10-31 00:41:57 +01:00
Robert Jelic
a74b8a3d9f Some smaller changed
some changes for testing improved installer
2022-10-31 00:27:59 +01:00
Robert Jelic
ef480c3998 changed index.html
-added edit-on-github
-added copy code
-added image zoom
- changed search depth from 6 to 2
2022-10-26 00:24:22 +02:00
Robert Jelic
c3e97ae516 Docs -> frames
Updated the frame object in docs
2022-10-26 00:19:00 +02:00
Robert Jelic
d78bb4d141 Docs - panes
changed panes to make it more clear why they exist
2022-10-21 21:13:09 +02:00
Robert Jelic
ab72f244ed Updated some formatting
Updated formatting for object
2022-10-20 21:05:29 +02:00
Robert Jelic
4352d36831 Small docs update
- added searchbar
- added :remove method @Object
2022-10-20 20:20:25 +02:00
Robert Jelic
04ad97ccbe Small program fix 2022-10-20 06:22:14 +02:00
Robert Jelic
6b2433e0a1 Whoops 2022-10-13 20:59:49 +02:00
Robert Jelic
bf1b008084 Docs update
Some more stuff for docs
2022-10-09 14:00:35 +02:00
Robert Jelic
681d54b406 moving module 2022-10-09 12:16:38 +02:00
Robert Jelic
eab8794d38 ..forgot to add (1.6.3)
- Fixed focus system bug
- Fixed :getScrollAmount (frames)
- added :onHover
- added :onLeave
- Made drawing a bit faster
- Added a dragging throttle system
- Mouse events should send now relative coordinates
2022-10-09 12:14:20 +02:00
Robert Jelic
1d3e2018ef docs update
Updated some docs stuff
2022-10-09 12:05:30 +02:00
Robert Jelic
44402b1d26 Basalt 1.6.3 - some improvements
- added new animations (:setMode("animname")
- added :addMode("animname", f) to create custom easings
- Fixed a bug in input when using - or . nothing happens (inputmode number)
- Added a event for labels when using multiple line text and the window/frame gets resized)
- Changed some backend stuff for programs
- added a setEnviroment method for programs
- Added a program_done event and a program_error event for programs (:onError() and :onDone())
- Fixed a bug in textfields (when using editLine it doesn't update colors)
- seperated the char event from the key event (before both events executed :onKey events, now there is a :onChar() and :onKey() event
2022-10-09 10:50:02 +02:00
Robert Jelic
56d89ad6f0 added install/package script
Added install script
Added packager/minify script
2022-09-18 22:21:29 +02:00
Robert Jelic
4af3df72ab Merge pull request #28 from Erb3/master
Docs update, mostly Basalt, Sidebar and Footer.
2022-09-17 15:04:41 +02:00
Erb3
f404e0ad8f Small onEvent change 2022-09-17 14:59:46 +02:00
Erb3
45bb23476b Docs: Fix sidebar issue on all Basalt methods 2022-09-17 14:41:54 +02:00
Erb3
bd61da9593 Docs: basalt.update() 2022-09-17 14:33:10 +02:00
Erb3
9acf7d5345 Docs: Basalt.stopUpdate 2022-09-17 14:33:04 +02:00
Erb3
1efca45639 Docs: Basalt.setVariable.md 2022-09-17 14:28:53 +02:00
Erb3
2dfe69fe43 Docs: Basalt.setTheme 2022-09-17 14:28:44 +02:00
Erb3
40b24ccf46 Docs: Add basalt.setActiveFrame.md 2022-09-17 14:25:01 +02:00
Erb3
1ebeda0375 Docs: Clean up basalt.scheduel.md 2022-09-17 14:21:55 +02:00
Erb3
9a514e6f7c Docs: Add base onEvent.md 2022-09-17 14:21:43 +02:00
Erb3
4f1baee771 Docs: Update basalt.removeFrame.md 2022-09-15 15:34:59 +02:00
Erb3
6ed31dd44c Docs: Update log.md 2022-09-15 15:19:16 +02:00
Erb3
19bc07e350 Docs: Fix typo in basalt.getVariable.md 2022-09-15 15:06:26 +02:00
Erb3
27321380ae Docs: Finish Basalt.getTheme.md 2022-09-15 15:05:42 +02:00
Erb3
bf9f01aae7 Docs: basalt.isKeyDown 2022-09-12 21:07:31 +02:00
Erb3
651690d8ab Docs: basalt.getVariable & basalt.getVersion 2022-09-12 21:04:01 +02:00
Erb3
7bcbafe30b Docs: basalt.getTheme 2022-09-12 20:57:06 +02:00
Erb3
72f2c527b9 Docs: basalt.get(Active)Frame 2022-09-12 20:51:58 +02:00
Erb3
77eeb1ce81 Docs: basalt.debug 2022-09-12 20:47:37 +02:00
Erb3
04d5919a82 Docs: basalt.createFrame 2022-09-12 20:44:18 +02:00
Erb3
6fa519be86 Docs: basalt.autoUpdate() 2022-09-12 20:35:01 +02:00
Erb3
00fff1c2f0 Docs: Basalt.md update
Changes:
* Rewording
* Add forgotten methods
* Sort methods
2022-09-12 20:09:14 +02:00
Erlend
140f1b0014 Reword Quick-Start.md 2022-09-12 12:23:31 +02:00
Erlend
153f2b9146 docs: rephrase installer.md 2022-09-12 12:20:24 +02:00
Erlend
21467fe4f4 Merge pull request #1 from Pyroxenium/master
fetch latest
2022-09-12 11:49:10 +02:00
Robert Jelic
6f372fa070 docs update 2022-09-11 11:40:49 +02:00
Robert Jelic
3ca6ac5af0 small docs fix
someone is watching me
2022-09-10 21:02:56 +02:00
Robert Jelic
859303e7a1 documentated multi-monitor support 2022-09-08 20:36:36 +02:00
Erlend
ab767e16dd Fix _footer 2022-09-07 16:53:51 +02:00
Erb3
93a0c738fa Make the footer work 2022-09-07 16:51:32 +02:00
Erb3
04d85b633c Undo adding title to sidebar and navbar 2022-09-07 16:29:17 +02:00
Erb3
4d83697537 Update navbar to be consistant 2022-09-07 16:11:53 +02:00
Erb3
ff12c040df Fix formatting in _sidebar.md 2022-09-07 16:07:15 +02:00
Erb3
897b7018a1 [WIKI] Edit wiki home page
Changed made:
* Updated CC:T download link
* Fix <img> into markdown
* Change underscores into astrix
* Fix <a> into markdown
* Remove unnecessary <br>
2022-09-07 16:02:11 +02:00
Robert Jelic
51f6ebe7ce docs updates 2022-09-06 17:43:03 +02:00
Robert Jelic
4d227af9d9 fixed removeObject 2022-09-06 16:21:54 +02:00
Robert Jelic
cf4f15e659 added multimonitor support
- cursor fix @input
- now you are able to add bigger monitors - still in beta
Some features are still missing: checking if monitors are connected/disconnected,
resizing by destroying the blocks
2022-09-05 23:00:38 +02:00
Robert Jelic
a3291544ac small input fixed
Used the old way of receiving x position
2022-09-04 17:44:06 +02:00
Robert Jelic
0503aa1274 Update process.lua 2022-09-03 20:41:16 +02:00
Robert Jelic
299b23a6c2 Border fix
fixed the way borders are drawn
2022-09-02 19:38:38 +02:00
Robert Jelic
8b3b6f3490 Update Frame.lua
fixed small focus issue
2022-09-01 21:05:13 +02:00
Robert Jelic
d1792ac537 Merge pull request #27 from Erb3/patch-2
Fix typo in Animations - changeBackground.md
2022-09-01 19:43:53 +02:00
Erlend
709cf66ce8 Fix typo in Animations - changeBackground.md 2022-09-01 18:57:39 +02:00
Robert Jelic
ae14d85a6b Input fix
fixed a bug in input fields while drag event is happening - now the input object loses the focus when dragging outside of its position+size
2022-08-30 22:51:26 +02:00
Robert Jelic
896e8179a6 oops 2022-08-30 20:52:28 +02:00
Robert Jelic
2dd3bf648b Some docs updates 2022-08-30 20:49:25 +02:00
Robert Jelic
c977410a41 Small bugfix
Fixed a bug where frames incorrectly remove their own events in parent frames
2022-08-30 20:17:00 +02:00
Robert Jelic
23b94d076b Frame drag fix
Fixed a dragging bug on frames
2022-08-29 18:50:18 +02:00
Robert Jelic
b10ec1770c fixed wrong links for labels 2022-08-29 18:26:59 +02:00
Robert Jelic
001e8c4ef6 Small bugfix
Forgot to add a check - if it has a parent or not
2022-08-28 20:27:07 +02:00
Robert Jelic
18601d54f7 Some updates 2022-08-28 20:25:42 +02:00
Robert Jelic
4d614372a1 Updated docs
There is still stuff to do
2022-08-28 18:18:26 +02:00
Robert Jelic
53d7b9f70c smallest bugfix 2022-08-26 23:22:25 +02:00
Robert Jelic
92e91b7d6b Update Animation.lua 2022-08-26 21:18:02 +02:00
Robert Jelic
b6c5531290 example changes and cursor bugfix 2022-08-26 21:13:19 +02:00
Robert Jelic
b637e65983 Update Frame.lua 2022-08-26 19:34:23 +02:00
Robert Jelic
5d12e0db74 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-08-26 19:32:43 +02:00
Robert Jelic
41bbe19de1 small quick fix 2022-08-26 19:31:27 +02:00
Robert Jelic
537d37c21b Update Frame.lua
quick fix for removing events
2022-08-25 23:15:00 +02:00
Robert Jelic
de84dbf406 New example for resizeable frames 2022-08-25 22:38:04 +02:00
Robert Jelic
8ab06dbc17 1.6.0 Release
Release version of basalt 1.6.0
2022-08-25 22:22:47 +02:00
Robert Jelic
14643193b9 Update mouseEvents.md 2022-08-24 20:24:51 +02:00
Robert Jelic
9d7c7d8a85 Merge pull request #26 from Yarillo4/master
Fix nil dereferencing exception in Frames.lua
2022-08-16 20:24:22 +02:00
Yarillo4
6809f9991b Fix nil dereferencing exception 2022-08-16 15:06:36 +02:00
Robert Jelic
b64f3ef87c updated the example
people are still using :show() and supply a id but never use them, probably because the example was not up2date
2022-08-12 19:03:13 +02:00
Robert Jelic
fb227445df Update Frame.md 2022-08-10 19:59:20 +02:00
Robert Jelic
10c25e7615 Update Frame.md 2022-08-10 19:58:17 +02:00
Robert Jelic
dfed9a5512 Merge pull request #25 from toastonrye/master
Example - Controlling Redstone output with a slider
2022-08-09 03:10:08 +02:00
toastonrye
fac7e221b3 Update redstoneAnalogOutput.lua
Add comments
2022-08-08 19:44:24 -05:00
toastonrye
c775958254 Update redstoneAnalogOutput.lua
Uploaded from pastebin
2022-08-08 19:33:51 -05:00
toastonrye
1c76130086 Update redstoneAnalogOutput.lua 2022-08-08 17:09:35 -05:00
toastonrye
57b303f538 Update redstoneAnalogOutput.lua 2022-08-08 16:58:28 -05:00
toastonrye
74071cb4bd Create redstoneAnalogOutput.lua 2022-08-08 16:47:24 -05:00
toastonrye
0cbded634a Delete redstoneAnalogOutput.lua 2022-08-08 16:46:57 -05:00
toastonrye
6ae0242b00 Create redstoneAnalogOutput.lua 2022-08-08 16:45:39 -05:00
Robert Jelic
ad6bf96124 Merge pull request #24 from EmmaKnijn/master
Issues in the documentation that might've caused confusion
2022-08-08 17:27:52 +02:00
EmmaKnijn
039782ec0e Add clarification
IDs for all objects were recently changed to be optional, but this was not reflected in the example script
2022-08-08 17:12:18 +02:00
EmmaKnijn
878e45bf8c Fix require file names
The default install script offered in docs\home\installer.md would install to the file `basalt.lua` instead of `Basalt.lua`, directly following instructions would cause the example script to error because of this.
2022-08-08 17:10:13 +02:00
Robert Jelic
cf387cab5a Merge pull request #23 from Erb3/patch-1
Readme badges + readme demo
2022-08-08 17:02:03 +02:00
Erlend
bcbca630f8 Readme badges + readme demo resizing
I added some cool™ badges to the README, with the help of shields.io.
I also resized the demo so the readme works better on mobile.
2022-08-08 16:59:35 +02:00
Robert Jelic
cfa2f561e4 Merge pull request #22 from Erb3/master
Improved README + Changelog
2022-08-07 10:25:01 +02:00
Erlend
1bc6cb80d2 Improved README + Changelog 2022-08-07 10:21:38 +02:00
Robert Jelic
323b521ddc Update discordCC.lua 2022-08-06 17:26:40 +02:00
Robert Jelic
80e2ed1c33 Merge pull request #21 from toastonrye/patch-2
Patch 2
2022-08-06 17:23:36 +02:00
toastonrye
46bb1c53f2 Update basaltPreview2.lua
typo
2022-08-06 10:07:21 -05:00
toastonrye
e6717c8648 Update basaltPreview.lua
Copied from the Basalt wiki example
2022-08-06 10:04:22 -05:00
Robert Jelic
5b422905fe Fixed file handle bug
Now it should work on CraftOS PC without any errors
2022-07-29 23:56:55 +02:00
Robert Jelic
00e70c8b4e Update basaltPackager.lua 2022-07-29 23:08:16 +02:00
Robert Jelic
ca38c7d560 -fixed file handle is not closing
Never forget to close file handle guys.
2022-07-29 23:05:22 +02:00
Robert Jelic
a3c2e7a043 Delete oldVersions directory
Not necessary anymore, if you are looking for different versions go and look into the release section.
2022-07-29 14:32:52 +02:00
Robert Jelic
c36690da00 Update main.lua 2022-07-28 22:52:53 +02:00
353 changed files with 30713 additions and 20435 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,17 @@
local curDir = fs.getDir(table.pack(...)[2]) or ""
local defaultPath = package.path
local format = "%s;/%s/?.lua;/%s/?/init.lua"
package.path = string.format(format, package.path, curDir,curDir)..string.format(format, package.path, curDir.."/libraries",curDir.."/libraries")..string.format(format, package.path, curDir.."/objects",curDir.."/objects")
if not(packed)then
local format = "path;/path/?.lua;/path/?/init.lua;"
local main = format:gsub("path", curDir)
local objFolder = format:gsub("path", curDir.."/objects")
local libFolder = format:gsub("path", curDir.."/libraries")
package.path = main..objFolder..libFolder..defaultPath
end
local Basalt = require("main")
package.path = defaultPath
return Basalt
return Basalt

View File

@@ -28,6 +28,7 @@ return function(drawTerm)
createEmptyLines()
local function recreateWindowArray()
createEmptyLines()
local emptyText = emptySpaceLine
local emptyFG = emptyColorLines[colors.white]
local emptyBG = emptyColorLines[colors.black]
@@ -125,7 +126,58 @@ return function(drawTerm)
end
end
local function blit(x, y, t, fg, bg)
if(#t == #fg)or(#t == #bg)then
if (y >= 1) and (y <= height) then
if (x + t:len() > 0) and (x <= width) then
local oldCacheT = cacheT[y]
local oldCacheFG = cacheFG[y]
local oldCacheBG = cacheBG[y]
local newCacheT, newCacheFG, newCacheBG
local nEnd = x + #t - 1
if (x < 1) then
local startN = 1 - x + 1
local endN = width - x + 1
t = sub(t, startN, endN)
fg = sub(fg, startN, endN)
bg = sub(bg, startN, endN)
elseif (nEnd > width) then
local endN = width - x + 1
t = sub(t, 1, endN)
fg = sub(fg, 1, endN)
bg = sub(bg, 1, endN)
end
if (x > 1) then
local endN = x - 1
newCacheT = sub(oldCacheT, 1, endN) .. t
newCacheFG = sub(oldCacheFG, 1, endN) .. fg
newCacheBG = sub(oldCacheBG, 1, endN) .. bg
else
newCacheT = t
newCacheFG = fg
newCacheBG = bg
end
if nEnd < width then
newCacheT = newCacheT .. sub(oldCacheT, nEnd + 1, width)
newCacheFG = newCacheFG .. sub(oldCacheFG, nEnd + 1, width)
newCacheBG = newCacheBG .. sub(oldCacheBG, nEnd + 1, width)
end
cacheT[y] = newCacheT
cacheFG[y] = newCacheFG
cacheBG[y] = newCacheBG
end
end
end
end
local drawHelper = {
setSize = function(w, h)
width, height = w, h
recreateWindowArray()
end,
setMirror = function(mirror)
mirrorTerm = mirror
end,
@@ -141,6 +193,10 @@ return function(drawTerm)
setFG(x, y, colorStr)
end;
blit = function(x, y, t, fg, bg)
blit(x, y, t, fg, bg)
end,
drawBackgroundBox = function(x, y, width, height, bgCol)
for n = 1, height do
setBG(x, y + (n - 1), rep(tHex[bgCol], width))
@@ -157,11 +213,15 @@ return function(drawTerm)
end
end;
writeText = function(x, y, text, bgCol, fgCol)
bgCol = bgCol or terminal.getBackgroundColor()
fgCol = fgCol or terminal.getTextColor()
setText(x, y, text)
setBG(x, y, rep(tHex[bgCol], text:len()))
setFG(x, y, rep(tHex[fgCol], text:len()))
if(text~=nil)then
setText(x, y, text)
if(bgCol~=nil)and(bgCol~=false)then
setBG(x, y, rep(tHex[bgCol], text:len()))
end
if(fgCol~=nil)and(fgCol~=false)then
setFG(x, y, rep(tHex[fgCol], text:len()))
end
end
end;
update = function()
@@ -171,7 +231,7 @@ return function(drawTerm)
isBlinking = terminal.getCursorBlink()
end
terminal.setCursorBlink(false)
if(mirrorTerm~=nil)then terminal.setCursorBlink(false) end
if(mirrorTerm~=nil)then mirrorTerm.setCursorBlink(false) end
for n = 1, height do
terminal.setCursorPos(1, n)
terminal.blit(cacheT[n], cacheFG[n], cacheBG[n])

View File

@@ -0,0 +1,20 @@
local logDir = ""
local logFileName = "basaltLog.txt"
local defaultLogType = "Debug"
fs.delete(logDir~="" and logDir.."/"..logFileName or logFileName)
local mt = {
__call = function(_,text, typ)
if(text==nil)then return end
local dirStr = logDir~="" and logDir.."/"..logFileName or logFileName
local handle = fs.open(dirStr, fs.exists(dirStr) and "a" or "w")
handle.writeLine("[Basalt]["..(typ and typ or defaultLogType).."]: "..tostring(text))
handle.close()
end,
}
return setmetatable({}, mt)
--Work in progress

View File

@@ -0,0 +1,199 @@
-- Right now this doesn't support scroll(n)
-- Because this lbirary is mainly made for basalt - it doesn't need scroll support, maybe i will add it in the future
local tHex = {
[colors.white] = "0",
[colors.orange] = "1",
[colors.magenta] = "2",
[colors.lightBlue] = "3",
[colors.yellow] = "4",
[colors.lime] = "5",
[colors.pink] = "6",
[colors.gray] = "7",
[colors.lightGray] = "8",
[colors.cyan] = "9",
[colors.purple] = "a",
[colors.blue] = "b",
[colors.brown] = "c",
[colors.green] = "d",
[colors.red] = "e",
[colors.black] = "f",
}
local type,len,rep,sub = type,string.len,string.rep,string.sub
return function (monitorNames)
local monitors = {}
for k,v in pairs(monitorNames)do
monitors[k] = {}
for a,b in pairs(v)do
local mon = peripheral.wrap(b)
if(mon==nil)then
error("Unable to find monitor "..b)
end
monitors[k][a] = mon
monitors[k][a].name = b
end
end
local x,y,monX,monY,monW,monH,w,h = 1,1,1,1,0,0,0,0
local blink,scale = false,1
local fg,bg = colors.white,colors.black
local function calcSize()
local maxW,maxH = 0,0
for k,v in pairs(monitors)do
local _maxW,_maxH = 0,0
for a,b in pairs(v)do
local nw,nh = b.getSize()
_maxW = _maxW + nw
_maxH = nh > _maxH and nh or _maxH
end
maxW = maxW > _maxW and maxW or _maxW
maxH = maxH + _maxH
end
w,h = maxW,maxH
end
calcSize()
local function calcPosition()
local relY = 0
local mX,mY = 0,0
for k,v in pairs(monitors)do
local relX = 0
local _mh = 0
for a,b in pairs(v)do
local mw,mh = b.getSize()
if(x-relX>=1)and(x-relX<=mw)then
mX = a
end
b.setCursorPos(x-relX, y-relY)
relX = relX + mw
if(_mh<mh)then _mh = mh end
end
if(y-relY>=1)and(y-relY<=_mh)then
mY = k
end
relY = relY + _mh
end
monX,monY = mX,mY
end
calcPosition()
local function call(f, ...)
local t = {...}
return function()
for k,v in pairs(monitors)do
for a,b in pairs(v)do
b[f](table.unpack(t))
end
end
end
end
local function cursorBlink()
call("setCursorBlink", false)()
if not(blink)then return end
if(monitors[monY]==nil)then return end
local mon = monitors[monY][monX]
if(mon==nil)then return end
mon.setCursorBlink(blink)
end
local function blit(text, tCol, bCol)
if(monitors[monY]==nil)then return end
local mon = monitors[monY][monX]
if(mon==nil)then return end
mon.blit(text, tCol, bCol)
local mW, mH = mon.getSize()
if(len(text)+x>mW)then
local monRight = monitors[monY][monX+1]
if(monRight~=nil)then
monRight.blit(text, tCol, bCol)
monX = monX + 1
x = x + len(text)
end
end
calcPosition()
end
return {
clear = call("clear"),
setCursorBlink = function(_blink)
blink = _blink
cursorBlink()
end,
getCursorBlink = function()
return blink
end,
getCursorPos = function()
return x, y
end,
setCursorPos = function(newX,newY)
x, y = newX, newY
calcPosition()
cursorBlink()
end,
setTextScale = function(_scale)
call("setTextScale", _scale)()
calcSize()
calcPosition()
scale = _scale
end,
getTextScale = function()
return scale
end,
blit = function(text,fgCol,bgCol)
blit(text,fgCol,bgCol)
end,
write = function(text)
text = tostring(text)
local l = len(text)
blit(text, rep(tHex[fg], l), rep(tHex[bg], l))
end,
getSize = function()
return w,h
end,
setBackgroundColor = function(col)
call("setBackgroundColor", col)()
bg = col
end,
setTextColor = function(col)
call("setTextColor", col)()
fg = col
end,
calculateClick = function(name, xClick, yClick)
local relY = 0
for k,v in pairs(monitors)do
local relX = 0
local maxY = 0
for a,b in pairs(v)do
local wM,hM = b.getSize()
if(b.name==name)then
return xClick + relX, yClick + relY
end
relX = relX + wM
if(hM > maxY)then maxY = hM end
end
relY = relY + maxY
end
return xClick, yClick
end,
}
end

381
Basalt/libraries/bimg.lua Normal file
View File

@@ -0,0 +1,381 @@
local sub,rep = string.sub,string.rep
local function frame(base, manager)
local w, h = 0, 0
local t,fg,bg = {}, {}, {}
local x, y = 1,1
local data = {}
local function recalculateSize()
for y=1,h do
if(t[y]==nil)then
t[y] = rep(" ", w)
else
t[y] = t[y]..rep(" ", w-#t[y])
end
if(fg[y]==nil)then
fg[y] = rep("0", w)
else
fg[y] = fg[y]..rep("0", w-#fg[y])
end
if(bg[y]==nil)then
bg[y] = rep("f", w)
else
bg[y] = bg[y]..rep("f", w-#bg[y])
end
end
end
local addText = function(text, _x, _y)
x = _x or x
y = _y or y
if(t[y]==nil)then
t[y] = rep(" ", x-1)..text..rep(" ", w-(#text+x))
else
t[y] = sub(t[y], 1, x-1)..rep(" ", x-#t[y])..text..sub(t[y], x+#text, w)
end
if(#t[y]>w)then w = #t[y] end
if(y > h)then h = y end
manager.updateSize(w, h)
end
local addBg = function(b, _x, _y)
x = _x or x
y = _y or y
if(bg[y]==nil)then
bg[y] = rep("f", x-1)..b..rep("f", w-(#b+x))
else
bg[y] = sub(bg[y], 1, x-1)..rep("f", x-#bg[y])..b..sub(bg[y], x+#b, w)
end
if(#bg[y]>w)then w = #bg[y] end
if(y > h)then h = y end
manager.updateSize(w, h)
end
local addFg = function(f, _x, _y)
x = _x or x
y = _y or y
if(fg[y]==nil)then
fg[y] = rep("0", x-1)..f..rep("0", w-(#f+x))
else
fg[y] = sub(fg[y], 1, x-1)..rep("0", x-#fg[y])..f..sub(fg[y], x+#f, w)
end
if(#fg[y]>w)then w = #fg[y] end
if(y > h)then h = y end
manager.updateSize(w, h)
end
local function setFrame(frm)
data = {}
t, fg, bg = {}, {}, {}
for k,v in pairs(base)do
if(type(k)=="string")then
data[k] = v
else
t[k], fg[k], bg[k] = v[1], v[2], v[3]
end
end
manager.updateSize(w, h)
end
if(base~=nil)then
w = #base[1][1]
h = #base
setFrame(base)
end
return {
recalculateSize = recalculateSize,
setFrame = setFrame,
getFrame = function()
local f = {}
for k,v in pairs(t)do
table.insert(f, {v, fg[k], bg[k]})
end
for k,v in pairs(data)do
f[k] = v
end
return f, w, h
end,
getImage = function()
local i = {}
for k,v in pairs(t)do
table.insert(i, {v, fg[k], bg[k]})
end
return i
end,
setFrameData = function(key, value)
if(value~=nil)then
data[key] = value
else
if(type(key)=="table")then
data = key
end
end
end,
setFrameImage = function(imgData)
for k,v in pairs(imgData.t)do
t[k] = imgData.t[k]
fg[k] = imgData.fg[k]
bg[k] = imgData.bg[k]
end
end,
getFrameImage = function()
return {t = t, fg = fg, bg = bg}
end,
getFrameData = function(key)
return (key~= nil and data[key] or data)
end,
blit = function(text, fgCol, bgCol, x, y)
addText(text, x, y)
addFg(fgCol, x, y)
addBg(bgCol, x, y)
end,
text = addText,
fg = addFg,
bg = addBg,
getSize = function()
return w, h
end,
setSize = function(_w, _h)
local nt,nfg,nbg = {}, {}, {}
for _y=1,_h do
if(t[_y]~=nil)then
nt[_y] = sub(t[_y], 1, _w)..rep(" ", _w - w)
else
nt[_y] = rep(" ", _w)
end
if(fg[_y]~=nil)then
nfg[_y] = sub(fg[_y], 1, _w)..rep("0", _w - w)
else
nfg[_y] = rep("0", _w)
end
if(bg[_y]~=nil)then
nbg[_y] = sub(bg[_y], 1, _w)..rep("f", _w - w)
else
nbg[_y] = rep("f", _w)
end
end
t, fg, bg = nt, nfg, nbg
w, h = _w, _h
end,
}
end
return function(img)
local frames = {}
local metadata = {creator="Bimg Library by NyoriE", date=os.date("!%Y-%m-%dT%TZ")}
local width,height = 0, 0
local manager = {}
local function addFrame(id, data)
id = id or #frames+1
table.insert(frames, id, frame(data, manager))
if(data==nil)then
frames[id].setSize(width, height)
end
end
local function removeFrame(id)
table.remove(frames, id or #frames)
end
local function moveFrame(id, dir)
local f = frames[id]
if(f~=nil)then
local newId = id+dir
if(newId>=1)and(newId<=#frames)then
table.remove(frames, id)
table.insert(frames, newId, f)
end
end
end
manager = {
updateSize = function(w, h, force)
local changed = force==true and true or false
if(w > width)then changed = true width = w end
if(h > height)then changed = true height = h end
if(changed)then
for k,v in pairs(frames)do
v.setSize(width, height)
v.recalculateSize()
end
end
end,
text = function(frame, text, x, y)
local f = frames[frame]
if(f==nil)then
f = addFrame(frame)
end
f.text(text, x, y)
end,
fg = function(frame, fg, x, y)
local f = frames[frame]
if(f==nil)then
f = addFrame(frame)
end
f.fg(fg, x, y)
end,
bg = function(frame, bg, x, y)
local f = frames[frame]
if(f==nil)then
f = addFrame(frame)
end
f.bg(bg, x, y)
end,
blit = function(frame, text, fg, bg, x, y)
local f = frames[frame]
if(f==nil)then
f = addFrame(frame)
end
f.blit(text, fg, bg, x, y)
end,
setSize = function(w, h)
width = w
height = h
for k,v in pairs(frames)do
v.setSize(w, h)
end
end,
getFrame = function(id)
if(frames[id]~=nil)then
return frames[id].getFrame()
end
end,
getFrameObjects = function()
return frames
end,
getFrames = function()
local f = {}
for k,v in pairs(frames)do
local frame = v.getFrame()
table.insert(f, frame)
end
return f
end,
getFrameObject = function(id)
return frames[id]
end,
addFrame = function(id)
local f = frame()
if(#frames<=1)then
if(metadata.animated==nil)then
metadata.animated = true
end
if(metadata.secondsPerFrame==nil)then
metadata.secondsPerFrame = 0.2
end
end
addFrame(id)
return f
end,
removeFrame = function(id)
removeFrame(id)
if(#frames<=1)then
if(metadata.animated==nil)then
metadata.animated = true
end
if(metadata.secondsPerFrame==nil)then
metadata.secondsPerFrame = 0.2
end
end
end,
moveFrame = moveFrame,
setFrameData = function(id, key, value)
if(frames[id]~=nil)then
frames[id].setFrameData(key, value)
end
end,
getFrameData = function(id, key)
return frames[id]~=nil and frames[id].getFrameData(key)
end,
getSize = function()
return width, height
end,
setAnimation = function(anim)
metadata.animation = anim
end,
setMetadata = function(key, val)
if(val~=nil)then
metadata[key] = val
else
if(type(key)=="table")then
metadata = key
end
end
end,
getMetadata = function(key)
return key~=nil and metadata[key] or metadata
end,
createBimg = function()
local bimg = {}
for k,v in pairs(frames)do
local f = v.getFrame()
table.insert(bimg, f)
end
for k,v in pairs(metadata)do
bimg[k] = v
end
bimg.width = width
bimg.height = height
return bimg
end,
}
if(img~=nil)then
for k,v in pairs(img)do
if(type(k)=="string")then
metadata[k] = v
else
addFrame(k, v)
end
end
if(metadata.width==nil)or(metadata.height==nil)then
for k,v in pairs(frames)do
local w, h = v.getSize()
if(w>width)then w = width end
if(h>height)then h = height end
end
manager.updateSize(width, height, true)
end
else
addFrame(1)
end
return manager
end

View File

@@ -1,197 +0,0 @@
local function line(x1,y1,x2,y2)
local points = {}
if x1 == x2 and y1 == y2 then return {x=x1,y=x2} end
local minX = math.min(x1, x2)
local maxX, minY, maxY
if minX == x1 then minY,maxX,maxY = y1,x2,y2
else minY,maxX,maxY = y2,x1,y1 end
local xDiff,yDiff = maxX - minX,maxY - minY
if xDiff > math.abs(yDiff) then
local y = minY
local dy = yDiff / xDiff
for x = minX, maxX do
table.insert(points,{x=x,y=math.floor(y + 0.5)})
y = y + dy
end
else
local x,dx = minX,xDiff / yDiff
if maxY >= minY then
for y = minY, maxY do
table.insert(points,{x=math.floor(x + 0.5),y=y})
x = x + dx
end
else
for y = minY, maxY, -1 do
table.insert(points,{x=math.floor(x + 0.5),y=y})
x = x - dx
end
end
end
return points
end
local function filledCircle(xC, yC, r)
local points = {}
for x=-r, r+1 do
local dy = math.floor(math.sqrt(r*r - x*x))
for y=-dy, dy+1 do
table.insert(points, {x=xC+x, y=yC+y})
end
end
return points
end
local function ellipse(xC, yC, r1, r2, filled)
local rx,ry = math.ceil(math.floor(r1-0.5)/2),math.ceil(math.floor(r2-0.5)/2)
local x,y=0,ry
local d1 = ((ry * ry) - (rx * rx * ry) + (0.25 * rx * rx))
local dx = 2*ry^2*x
local dy = 2*rx^2*y
local points = {}
while dx < dy do
table.insert(points,{x=x+xC,y=y+yC})
table.insert(points,{x=-x+xC,y=y+yC})
table.insert(points,{x=x+xC,y=-y+yC})
table.insert(points,{x=-x+xC,y=-y+yC})
if filled then
for y=-y+yC+1,y+yC-1 do
table.insert(points,{x=x+xC,y=y})
table.insert(points,{x=-x+xC,y=y})
end
end
if d1 < 0 then
x = x + 1
dx = dx + 2*ry^2
d1 = d1 + dx + ry^2
else
x,y = x+1,y-1
dx = dx + 2*ry^2
dy = dy - 2*rx^2
d1 = d1 + dx - dy + ry^2
end
end
local d2 = (((ry * ry) * ((x + 0.5) * (x + 0.5))) + ((rx * rx) * ((y - 1) * (y - 1))) - (rx * rx * ry * ry))
while y >= 0 do
table.insert(points,{x=x+xC,y=y+yC})
table.insert(points,{x=-x+xC,y=y+yC})
table.insert(points,{x=x+xC,y=-y+yC})
table.insert(points,{x=-x+xC,y=-y+yC})
if filled then
for y=-y+yC,y+yC do
table.insert(points,{x=x+xC,y=y})
table.insert(points,{x=-x+xC,y=y})
end
end
if d2 > 0 then
y = y - 1
dy = dy - 2*rx^2
d2 = d2 + rx^2 - dy
else
y = y - 1
x = x + 1
dy = dy - 2*rx^2
dx = dx + 2*ry^2
d2 = d2 + dx - dy + rx^2
end
end
return points
end
local function circle(xC, yC, r, filled)
return ellipse(xC, yC, r, r, filled)
end
return {
circle = function(x, y, radius, filled)
return circle(x, y, radius, filled)
end,
rectangle = function(x1, y1, x2, y2, filled)
local points = {}
if(filled)then
for y=y1,y2 do
for x=x1,x2 do
table.insert(points, {x=x,y=y})
end
end
else
for y=y1,y2 do
for x=x1,x2 do
if(x==x1)or(x==x2)or(y==y1)or(y==y2)then
table.insert(points, {x=x,y=y})
end
end
end
end
return points
end,
triangle = function(x1, y1, x2, y2, x3, y3, filled)
local function drawFlatTopTriangle(points,x1,y1,x2,y2,x3,y3)
local m1 = (x3 - x1) / (y3 - y1)
local m2 = (x3 - x2) / (y3 - y2)
local yStart = math.ceil(y1 - 0.5)
local yEnd = math.ceil(y3 - 0.5)-1
for y = yStart, yEnd do
local px1 = m1 * (y + 0.5 - y1) + x1
local px2 = m2 * (y + 0.5 - y2) + x2
local xStart = math.ceil(px1 - 0.5)
local xEnd = math.ceil(px2 - 0.5)
for x=xStart,xEnd do
table.insert(points,{x=x,y=y})
end
end
end
local function drawFlatBottomTriangle(points,x1,y1,x2,y2,x3,y3)
local m1 = (x2 - x1) / (y2 - y1)
local m2 = (x3 - x1) / (y3 - y1)
local yStart = math.ceil(y1-0.5)
local yEnd = math.ceil(y3-0.5)-1
for y = yStart, yEnd do
local px1 = m1 * (y + 0.5 - y1) + x1
local px2 = m2 * (y + 0.5 - y1) + x1
local xStart = math.ceil(px1 - 0.5)
local xEnd = math.ceil(px2 - 0.5)
for x=xStart,xEnd do
table.insert(points,{x=x,y=y})
end
end
end
local points = {}
if(filled)then
if y2 < y1 then x1,y1,x2,y2 = x2,y2,x1,y1 end
if y3 < y2 then x2,y2,x3,y3 = x3,y3,x2,y2 end
if y2 < y2 then x1,y1,x2,y2 = x2,y2,x1,y1 end
if y1 == y2 then
if x2 < x1 then x1,y1,x2,y2 = x2,y2,x1,y1 end
drawFlatTopTriangle(points,x1,y1,x2,y2,x3,y3)
elseif y2 == y3 then
if x3 < x2 then x3,y3,x2,y2 = x2,y2,x3,y3 end
drawFlatBottomTriangle(points,x1,y1,x2,y2,x3,y3)
else
local alphaSplit = (y2-y1)/(y3-y1)
local x = x1 + ((x3 - x1) * alphaSplit)
local y = y1 + ((y3 - y1) * alphaSplit)
if x2 < x then
drawFlatBottomTriangle(points,x1,y1,x2,y2,x, y)
drawFlatTopTriangle(points,x2,y2,x,y,x3,y3)
else
drawFlatBottomTriangle(points,x1,y1,x,y,x1,y1)
drawFlatTopTriangle(points,x,y,x2,y2,x3,y3)
end
end
else
points = line(x1,y1,x2,y2)
for k,v in pairs(line(x2,y2,x3,y3))do table.insert(points, v) end
for k,v in pairs(line(x3,y3,x1,y1))do table.insert(points, v) end
end
return points
end,
line = line,
ellipse = function(xCenter, yCenter, radius1, radius2, filled)
return ellipse(xCenter, yCenter, radius1, radius2, filled)
end
}

View File

@@ -0,0 +1,97 @@
local sub,floor,rep = string.sub,math.floor,string.rep
local function loadNFPAsBimg(path)
local bimg = {{}}
local nfp = fs.open(path, "r")
if(nfp~=nil)then
for line in nfp.readLine do
table.insert(bimg[1], {rep(" ",#line), rep(" ",#line), line})
end
nfp.close()
return bimg
end
end
local function loadNFP(path)
return paintutils.loadImage(path), "nfp"
end
local function loadBIMG(path)
local f = fs.open(path, "rb")
local content = textutils.unserialize(f.readAll())
f.close()
if(content~=nil)then
return content, "bimg"
end
end
local function loadBBF(path)
end
local function loadBBFAsBimg(path)
end
local function loadImage(path, f)
if(f==nil)then
if(path:find(".bimg"))then
return loadBIMG(path)
elseif(path:find(".bbf"))then
return loadBBF(path)
else
return loadNFP(path)
end
end
-- ...
end
local function loadImageAsBimg(path, f)
if(f==nil)then
if(path:find(".bimg"))then
return loadBIMG(path)
elseif(path:find(".bbf"))then
return loadBBFAsBimg(path)
else
return loadNFPAsBimg(path)
end
end
end
local function resizeBIMG(source, w, h)
local oW, oH = source.width or #source[1][1][1], source.height or #source[1]
local newImg = {}
for k,v in pairs(source)do
if(type(k)=="number")then
local frame = {}
for y=1, h do
local xT,xFG,xBG = "","",""
local yR = floor(y / h * oH + 0.5)
if(v[yR]~=nil)then
for x=1, w do
local xR = floor(x / w * oW + 0.5)
xT = xT..sub(v[yR][1], xR,xR)
xFG = xFG..sub(v[yR][2], xR,xR)
xBG = xBG..sub(v[yR][3], xR,xR)
end
table.insert(frame, {xT, xFG, xBG})
end
end
table.insert(newImg, k, frame)
else
newImg[k] = v
end
end
newImg.width = w
newImg.height = h
return newImg
end
return {
loadNFP = loadNFP,
loadBIMG = loadBIMG,
loadImage = loadImage,
resizeBIMG = resizeBIMG,
loadImageAsBimg = loadImageAsBimg,
}

View File

@@ -0,0 +1,4 @@
return function(path)
local exists, content = pcall(require, path)
return exists and content or nil
end

View File

@@ -2,28 +2,61 @@ local processes = {}
local process = {}
local processId = 0
function process:new(path, window, ...)
local args = table.pack(...)
local newPackage = dofile("rom/modules/main/cc/require.lua").make
function process:new(path, window, newEnv, ...)
local args = {...}
local newP = setmetatable({ path = path }, { __index = self })
newP.window = window
window.current = term.current
window.redirect = term.redirect
newP.processId = processId
if(type(path)=="string")then
newP.coroutine = coroutine.create(function()
os.run({ }, path, table.unpack(args))
local pPath = shell.resolveProgram(path)
local env = setmetatable(newEnv, {__index=_ENV})
env.shell = shell
env.basaltProgram=true
env.arg = {[0]=path, table.unpack(args)}
env.require, env.package = newPackage(env, fs.getDir(pPath))
if(fs.exists(pPath))then
local file = fs.open(pPath, "r")
local content = file.readAll()
file.close()
local program = load(content, path, "bt", env)
if(program~=nil)then
return program()
end
end
end)
elseif(type(path)=="function")then
newP.coroutine = coroutine.create(function()
path(table.unpack(args))
end)
else
return
end
processes[processId] = newP
processId = processId + 1
return newP
end
function process:resume(event, ...)
local cur = term.current()
term.redirect(self.window)
if(self.filter~=nil)then
if(event~=self.filter)then return end
self.filter=nil
end
local ok, result = coroutine.resume(self.coroutine, event, ...)
self.window = term.current()
if ok then
self.filter = result
else
basalt.debug(result)
printError(result)
end
term.redirect(cur)
return ok, result
end
function process:isDead()

View File

@@ -1,17 +1,92 @@
local splitString = function(str, sep)
if sep == nil then
sep = "%s"
local sub,find,reverse = string.sub,string.find,string.reverse
local function splitString(str, delimiter)
local result = {}
if str == "" or delimiter == "" then
return result
end
local start = 1
local delim_start, delim_end = find(str, delimiter, start)
while delim_start do
table.insert(result, sub(str, start, delim_start - 1))
start = delim_end + 1
delim_start, delim_end = find(str, delimiter, start)
end
local t={}
for v in string.gmatch(str, "([^"..sep.."]+)") do
table.insert(t, v)
end
return t
table.insert(result, sub(str, start))
return result
end
local relations = {[0] = {8, 4, 3, 6, 5}, {4, 14, 8, 7}, {6, 10, 8, 7}, {9, 11, 8, 0}, {1, 14, 8, 0}, {13, 12, 8, 0}, {2, 10, 8, 0}, {15, 8, 10, 11, 12, 14},
{0, 7, 1, 9, 2, 13}, {3, 11, 8, 7}, {2, 6, 7, 15}, {9, 3, 7, 15}, {13, 5, 7, 15}, {5, 12, 8, 7}, {1, 4, 7, 15}, {7, 10, 11, 12, 14}}
local colourNum, exponents, colourChar = {}, {}, {}
for i = 0, 15 do exponents[2^i] = i end
do
local hex = "0123456789abcdef"
for i = 1, 16 do
colourNum[hex:sub(i, i)] = i - 1
colourNum[i - 1] = hex:sub(i, i)
colourChar[hex:sub(i, i)] = 2 ^ (i - 1)
colourChar[2 ^ (i - 1)] = hex:sub(i, i)
local thisRel = relations[i - 1]
for i = 1, #thisRel do thisRel[i] = 2 ^ thisRel[i] end
end
end
local function getBestColourMatch(usage)
local lastCol = relations[exponents[usage[#usage][1]]]
for j = 1, #lastCol do
local thisRelation = lastCol[j]
for i = 1, #usage - 1 do if usage[i][1] == thisRelation then return i end end
end
return 1
end
local function colsToChar(pattern, totals)
if not totals then
local newPattern = {}
totals = {}
for i = 1, 6 do
local thisVal = pattern[i]
local thisTot = totals[thisVal]
totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal
end
pattern = newPattern
end
local usage = {}
for key, value in pairs(totals) do usage[#usage + 1] = {key, value} end
if #usage > 1 then
-- Reduce the chunk to two colours:
while #usage > 2 do
table.sort(usage, function (a, b) return a[2] > b[2] end)
local matchToInd, usageLen = getBestColourMatch(usage), #usage
local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1]
for i = 1, 6 do if pattern[i] == matchFrom then
pattern[i] = matchTo
usage[matchToInd][2] = usage[matchToInd][2] + 1
end end
usage[usageLen] = nil
end
-- Convert to character. Adapted from oli414's function:
-- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/
local data = 128
for i = 1, #pattern - 1 do if pattern[i] ~= pattern[6] then data = data + 2^(i-1) end end
return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]]
else
-- Solid colour character:
return "\128", colourChar[pattern[1]], colourChar[pattern[1]]
end
end
return {
getTextHorizontalAlign = function(text, width, textAlign, replaceChar)
text = string.sub(text, 1, width)
text = sub(text, 1, width)
local offset = width - string.len(text)
if (textAlign == "right") then
text = string.rep(replaceChar or " ", offset) .. text
@@ -48,26 +123,39 @@ rpairs = function(t)
end, t, #t + 1
end,
tableCount = function(t)
local n = 0
if(t~=nil)then
for k,v in pairs(t)do
n = n + 1
end
end
return n
end,
splitString = splitString,
createText = function(str, width)
local uniqueLines = splitString(str, "\n")
local lines = {}
local result = {}
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
if(#v==0)then table.insert(result, "") end
while #v > width do
local last_space = find(reverse(sub(v, 1, width)), " ")
if not last_space then
last_space = width
else
table.insert(lines, line)
line = b:sub(1,width)
if(a==#words)then table.insert(lines, line) end
last_space = width - last_space + 1
end
local line = sub(v, 1, last_space)
table.insert(result, line)
v = sub(v, last_space + 1)
end
if #v > 0 then
table.insert(result, v)
end
end
return lines
return result
end,
getValueFromXML = function(name, tab)
@@ -107,4 +195,36 @@ uuid = function()
end
return uuid()
end,
array = function(arraysize, hashsize)
return load("return {" .. ("nil,"):rep(arraysize) .. ("[0]=nil,"):rep(hashsize) .. "}")()
end,
shrink = function(image, bgCol)
local results, width, height, bgCol = {{}, {}, {}}, 0, #image + #image % 3, bgCol or colours.black
for i = 1, #image do if #image[i] > width then width = #image[i] end end
for y = 0, height - 1, 3 do
local cRow, tRow, bRow, counter = {}, {}, {}, 1
for x = 0, width - 1, 2 do
-- Grab a 2x3 chunk:
local pattern, totals = {}, {}
for yy = 1, 3 do for xx = 1, 2 do
pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol
totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1
end end
cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals)
counter = counter + 1
end
results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow)
end
results.width, results.height = #results[1][1], #results[1]
return results
end,
}

View File

@@ -2,26 +2,79 @@ local basaltEvent = require("basaltEvent")()
local Frame = require("Frame")
local theme = require("theme")
local utils = require("utils")
local log = require("basaltLogs")
local uuid = utils.uuid
local createText = utils.createText
local count = utils.tableCount
local moveThrottle = 300
local dragThrottle = 50
local baseTerm = term.current()
local version = 5
local debugger = true
local version = "1.6.4"
local projectDirectory = fs.getDir(table.pack(...)[2] or "")
local activeKey, frames, monFrames, variables, schedules = {}, {}, {}, {}, {}
local activeKey, frames, monFrames, monGroups, variables, schedules = {}, {}, {}, {}, {}, {}
local mainFrame, activeFrame, focusedObject, updaterActive
local basalt = {}
if not term.isColor or not term.isColor() then
error('Basalt requires an advanced (golden) computer to run.', 0)
end
local defaultColors = {}
for k,v in pairs(colors)do
if(type(v)=="number")then
defaultColors[k] = {baseTerm.getPaletteColor(v)}
end
end
local function stop()
updaterActive = false
baseTerm.clear()
baseTerm.setCursorPos(1, 1)
for k,v in pairs(colors)do
if(type(v)=="number")then
baseTerm.setPaletteColor(v, colors.packRGB(table.unpack(defaultColors[k])))
end
end
end
local function basaltError(errMsg)
baseTerm.clear()
baseTerm.setBackgroundColor(colors.black)
baseTerm.setTextColor(colors.red)
local w,h = baseTerm.getSize()
if(basalt.logging)then
log(errMsg, "Error")
end
local text = createText("Basalt error: "..errMsg, w)
local yPos = 1
for k,v in pairs(text)do
baseTerm.setCursorPos(1,yPos)
baseTerm.write(v)
yPos = yPos + 1
end
baseTerm.setCursorPos(1,yPos+1)
updaterActive = false
end
local function schedule(f)
assert(f~="function", "Schedule needs a function in order to work!")
return function(...)
local co = coroutine.create(f)
local ok, result = coroutine.resume(co, ...)
if(ok)then
table.insert(schedules, {co, result})
else
basaltError(result)
end
end
end
local setVariable = function(name, var)
variables[name] = var
end
@@ -39,6 +92,10 @@ local getTheme = function(name)
end
local bInstance = {
getDynamicValueEventSetting = function()
return basalt.dynamicValueEvents
end,
getMainFrame = function()
return mainFrame
end,
@@ -68,17 +125,27 @@ local bInstance = {
end,
getMonitorFrame = function(name)
return monFrames[name]
return monFrames[name] or monGroups[name][1]
end,
setMonitorFrame = function(name, frame)
monFrames[name] = frame
setMonitorFrame = function(name, frame, isGroupedMon)
if(mainFrame == frame)then mainFrame = nil end
if(isGroupedMon)then
monGroups[name] = {frame, sides}
else
monFrames[name] = frame
end
if(frame==nil)then
monGroups[name] = nil
end
end,
getBaseTerm = function()
return baseTerm
end,
schedule = schedule,
stop = stop,
newFrame = Frame,
@@ -87,50 +154,26 @@ local bInstance = {
end
}
local basaltError = function(errMsg)
baseTerm.clear()
baseTerm.setBackgroundColor(colors.black)
baseTerm.setTextColor(colors.red)
local w,h = baseTerm.getSize()
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
return t
end
local words = splitString(errMsg, " ")
local line = "Basalt error: "
local yPos = 1
for n=1,#words do
baseTerm.setCursorPos(1,yPos)
if(#line+#words[n]<w)then
line = line.." "..words[n]
else
baseTerm.write(line)
line = words[n]
yPos = yPos + 1
end
if(n==#words)then
baseTerm.write(line)
end
end
baseTerm.setCursorPos(1,yPos+1)
end
local function handleSchedules(event, p1, p2, p3, p4)
local function handleSchedules(event, ...)
if(#schedules>0)then
local finished = {}
for n=1,#schedules do
if(schedules[n]~=nil)then
if (coroutine.status(schedules[n]) == "suspended")then
local ok, result = coroutine.resume(schedules[n], event, p1, p2, p3, p4)
if not(ok)then
basaltError(result)
if (coroutine.status(schedules[n][1]) == "suspended")then
if(schedules[n][2]~=nil)then
if(schedules[n][2]==event)then
local ok, result = coroutine.resume(schedules[n][1], event, ...)
schedules[n][2] = result
if not(ok)then
basaltError(result)
end
end
else
local ok, result = coroutine.resume(schedules[n][1], event, ...)
schedules[n][2] = result
if not(ok)then
basaltError(result)
end
end
else
table.insert(finished, n)
@@ -144,67 +187,130 @@ local function handleSchedules(event, p1, p2, p3, p4)
end
local function drawFrames()
if(updaterActive)then
if(mainFrame~=nil)then
mainFrame:draw()
mainFrame:drawUpdate()
end
for _,v in pairs(monFrames)do
v:draw()
v:drawUpdate()
if(updaterActive==false)then return end
if(mainFrame~=nil)then
mainFrame:draw()
mainFrame:updateTerm()
end
for _,v in pairs(monFrames)do
v:draw()
v:updateTerm()
end
for _,v in pairs(monGroups)do
v[1]:draw()
v[1]:updateTerm()
end
end
local stopped, moveX, moveY = nil, nil, nil
local moveTimer = nil
local function mouseMoveEvent(_, stp, x, y)
stopped, moveX, moveY = stp, x, y
if(moveTimer==nil)then
moveTimer = os.startTimer(moveThrottle/1000)
end
end
local function moveHandlerTimer()
moveTimer = nil
mainFrame:hoverHandler(moveX, moveY, stopped)
activeFrame = mainFrame
end
local btn, dragX, dragY = nil, nil, nil
local dragTimer = nil
local function dragHandlerTimer()
dragTimer = nil
mainFrame:dragHandler(btn, dragX, dragY)
activeFrame = mainFrame
end
local function mouseDragEvent(_, b, x, y)
btn, dragX, dragY = b, x, y
if(dragThrottle<50)then
dragHandlerTimer()
else
if(dragTimer==nil)then
dragTimer = os.startTimer(dragThrottle/1000)
end
end
end
local function basaltUpdateEvent(event, p1, p2, p3, p4)
if(basaltEvent:sendEvent("basaltEventCycle", event, p1, p2, p3, p4)==false)then return end
local function basaltUpdateEvent(event, ...)
local a = {...}
if(basaltEvent:sendEvent("basaltEventCycle", event, ...)==false)then return end
if(event=="terminate")then basalt.stop() end
if(mainFrame~=nil)then
if (event == "mouse_click") then
mainFrame:mouseHandler(event, p1, p2, p3, p4)
activeFrame = mainFrame
elseif (event == "mouse_drag") then
mainFrame:mouseHandler(event, p1, p2, p3, p4)
activeFrame = mainFrame
elseif (event == "mouse_up") then
mainFrame:mouseHandler(event, p1, p2, p3, p4)
activeFrame = mainFrame
elseif (event == "mouse_scroll") then
mainFrame:mouseHandler(event, p1, p2, p3, p4)
activeFrame = mainFrame
elseif (event == "monitor_touch") then
if(monFrames[p1]~=nil)then
monFrames[p1]:mouseHandler(event, p1, p2, p3, p4)
activeFrame = monFrames[p1]
local mouseEvents = {
mouse_click = mainFrame.mouseHandler,
mouse_up = mainFrame.mouseUpHandler,
mouse_scroll = mainFrame.scrollHandler,
mouse_drag = mouseDragEvent,
mouse_move = mouseMoveEvent,
}
local mouseEvent = mouseEvents[event]
if(mouseEvent~=nil)then
mouseEvent(mainFrame, ...)
handleSchedules(event, ...)
drawFrames()
return
end
end
if(event == "monitor_touch") then
if(monFrames[a[1]]~=nil)then
monFrames[a[1]]:mouseHandler(1, a[2], a[3], true)
activeFrame = monFrames[a[1]]
end
if(count(monGroups)>0)then
for k,v in pairs(monGroups)do
v[1]:mouseHandler(1, a[2], a[3], true, a[1])
end
end
handleSchedules(event, ...)
drawFrames()
return
end
if(event == "key") or (event == "char") then
if(activeFrame~=nil)then
activeFrame:keyHandler(event, p1)
activeFrame:backgroundKeyHandler(event, p1)
if(activeFrame~=nil)then
local keyEvents = {
char = activeFrame.charHandler,
key = activeFrame.keyHandler,
key_up = activeFrame.keyUpHandler,
}
local keyEvent = keyEvents[event]
if(keyEvent~=nil)then
if(event == "key")then
activeKey[a[1]] = true
elseif(event == "key_up")then
activeKey[a[1]] = false
end
keyEvent(activeFrame, ...)
handleSchedules(event, ...)
drawFrames()
return
end
end
if(event == "key")then
activeKey[p1] = true
if(event=="timer")and(a[1]==moveTimer)then
moveHandlerTimer()
elseif(event=="timer")and(a[1]==dragTimer)then
dragHandlerTimer()
else
for k, v in pairs(frames) do
v:eventHandler(event, ...)
end
end
if(event == "key_up")then
activeKey[p1] = false
end
for _, v in pairs(frames) do
v:eventHandler(event, p1, p2, p3, p4)
end
handleSchedules(event, p1, p2, p3, p4)
handleSchedules(event, ...)
drawFrames()
end
local basalt = {}
basalt = {
logging = false,
dynamicValueEvents = false,
setTheme = setTheme,
getTheme = getTheme,
drawFrames = drawFrames,
getVersion = function()
return version
end,
@@ -216,14 +322,51 @@ basalt = {
baseTerm = _baseTerm
end,
log = function(...)
log(...)
end,
setMouseMoveThrottle = function(amount)
if(_HOST:find("CraftOS%-PC"))then
if(config.get("mouse_move_throttle")~=10)then config.set("mouse_move_throttle", 10) end
if(amount<100)then
moveThrottle = 100
else
moveThrottle = amount
end
return true
end
return false
end,
setMouseDragThrottle = function(amount)
if(amount<=0)then
dragThrottle = 0
else
dragTimer = nil
dragThrottle = amount
end
end,
autoUpdate = function(isActive)
local pCall = pcall
updaterActive = isActive
if(isActive==nil)then updaterActive = true end
drawFrames()
while updaterActive do
local event, p1, p2, p3, p4 = os.pullEventRaw()
local ok, err = pCall(basaltUpdateEvent, event, p1, p2, p3, p4)
local function f()
drawFrames()
while updaterActive do
basaltUpdateEvent(os.pullEventRaw())
end
end
local ok, err = xpcall(f, debug.traceback)
if not(ok)then
basaltError(err)
return
end
end,
update = function(event, ...)
if (event ~= nil) then
local ok, err = xpcall(basaltUpdateEvent, debug.traceback, event, ...)
if not(ok)then
basaltError(err)
return
@@ -231,13 +374,8 @@ basalt = {
end
end,
update = function(event, p1, p2, p3, p4)
if (event ~= nil) then
basaltUpdateEvent(event, p1, p2, p3, p4)
end
end,
stop = stop,
stopUpdate = stop,
isKeyDown = function(key)
if(activeKey[key]==nil)then return false end
@@ -272,18 +410,7 @@ basalt = {
end
end,
schedule = function(f)
assert(f~="function", "Schedule needs a function in order to work!")
return function(...)
local co = coroutine.create(f)
local ok, result = coroutine.resume(co, ...)
if(ok)then
table.insert(schedules, co)
else
basaltError(result)
end
end
end,
schedule = schedule,
createFrame = function(name)
name = name or uuid()
@@ -293,6 +420,7 @@ basalt = {
end
end
local newFrame = Frame(name,nil,nil,bInstance)
newFrame:init()
table.insert(frames, newFrame)
if(mainFrame==nil)and(newFrame:getName()~="basaltDebuggingFrame")then
newFrame:show()
@@ -310,6 +438,7 @@ basalt = {
debug = function(...)
local args = { ... }
if(mainFrame==nil)then print(...) return end
if (mainFrame.name ~= "basaltDebuggingFrame") then
if (mainFrame ~= basalt.debugFrame) then
basalt.debugLabel:setParent(mainFrame)
@@ -336,7 +465,7 @@ basalt = {
basalt.debugFrame = basalt.createFrame("basaltDebuggingFrame"):showBar():setBackground(colors.lightGray):setBar("Debug", colors.black, colors.gray)
basalt.debugFrame:addButton("back"):setAnchor("topRight"):setSize(1, 1):setText("\22"):onClick(function() if(basalt.oldFrame~=nil)then basalt.oldFrame:show() end end):setBackground(colors.red):show()
basalt.debugList = basalt.debugFrame:addList("debugList"):setSize(basalt.debugFrame.width - 2, basalt.debugFrame.height - 3):setPosition(2, 3):setScrollable(true):show()
basalt.debugList = basalt.debugFrame:addList("debugList"):setSize("parent.w - 2", "parent.h - 3"):setPosition(2, 3):setScrollable(true):show()
basalt.debugLabel = basalt.debugFrame:addLabel("debugLabel"):onClick(function() basalt.oldFrame = mainFrame basalt.debugFrame:show() end):setBackground(colors.black):setForeground(colors.white):setAnchor("bottomLeft"):ignoreOffset():setZIndex(20):show()
return basalt

4
Basalt/module.lua Normal file
View File

@@ -0,0 +1,4 @@
return function(path)
local exists, content = pcall(require, path)
return exists and content or nil
end

View File

@@ -1,8 +1,9 @@
local xmlValue = require("utils").getValueFromXML
local basaltEvent = require("basaltEvent")
local floor = math.floor
local floor,sin,cos,pi,sqrt,pow = math.floor,math.sin,math.cos,math.pi,math.sqrt,math.pow
-- You can find the easing curves here https://easings.net
local lerp = function(s, e, pct)
return s + (e - s) * pct
@@ -12,8 +13,8 @@ local linear = function (t)
return t
end
local flip = function (x)
return 1 - x
local flip = function (t)
return 1 - t
end
local easeIn = function (t)
@@ -28,15 +29,199 @@ local easeInOut = function(t)
return lerp(easeIn(t), easeOut(t), t)
end
local easeOutSine = function(t)
return sin((t * pi) / 2);
end
local easeInSine = function(t)
return flip(cos((t * pi) / 2))
end
local easeInOutSine = function(t)
return -(cos(pi * x) - 1) / 2
end
local easeInBack = function(t)
local c1 = 1.70158;
local c3 = c1 + 1
return c3*t^3-c1*t^2
end
local easeInCubic = function(t)
return t^3
end
local easeInElastic = function(t)
local c4 = (2*pi)/3;
return t == 0 and 0 or (t == 1 and 1 or (
-2^(10*t-10)*sin((t*10-10.75)*c4)
))
end
local function easeInExpo(t)
return t == 0 and 0 or 2^(10*t-10)
end
local function easeInExpo(t)
return t == 0 and 0 or 2^(10*t-10)
end
local function easeInOutBack(t)
local c1 = 1.70158;
local c2 = c1 * 1.525;
return t < 0.5 and ((2*t)^2*((c2+1)*2*t-c2))/2 or ((2*t-2)^2*((c2+1)*(t*2-2)+c2)+2)/2
end
local function easeInOutCubic(t)
return t < 0.5 and 4 * t^3 or 1-(-2*t+2)^3 / 2
end
local function easeInOutElastic(t)
local c5 = (2*pi) / 4.5
return t==0 and 0 or (t == 1 and 1 or (t < 0.5 and -(2^(20*t-10) * sin((20*t - 11.125) * c5))/2 or (2^(-20*t+10) * sin((20*t - 11.125) * c5))/2 + 1))
end
local function easeInOutExpo(t)
return t == 0 and 0 or (t == 1 and 1 or (t < 0.5 and 2^(20*t-10)/2 or (2-2^(-20*t+10)) /2))
end
local function easeInOutQuad(t)
return t < 0.5 and 2*t^2 or 1-(-2*t+2)^2/2
end
local function easeInOutQuart(t)
return t < 0.5 and 8*t^4 or 1 - (-2*t+2)^4 / 2
end
local function easeInOutQuint(t)
return t < 0.5 and 16*t^5 or 1-(-2*t+2)^5 / 2
end
local function easeInQuad(t)
return t^2
end
local function easeInQuart(t)
return t^4
end
local function easeInQuint(t)
return t^5
end
local function easeOutBack(t)
local c1 = 1.70158;
local c3 = c1 + 1
return 1+c3*(t-1)^3+c1*(t-1)^2
end
local function easeOutCubic(t)
return 1 - (1-t)^3
end
local function easeOutElastic(t)
local c4 = (2*pi)/3;
return t == 0 and 0 or (t == 1 and 1 or (2^(-10*t)*sin((t*10-0.75)*c4)+1))
end
local function easeOutExpo(t)
return t == 1 and 1 or 1-2^(-10*t)
end
local function easeOutQuad(t)
return 1 - (1 - t) * (1 - t)
end
local function easeOutQuart(t)
return 1 - (1-t)^4
end
local function easeOutQuint(t)
return 1 - (1 - t)^5
end
local function easeInCirc(t)
return 1 - sqrt(1 - pow(t, 2))
end
local function easeOutCirc(t)
return sqrt(1 - pow(t - 1, 2))
end
local function easeInOutCirc(t)
return t < 0.5 and (1 - sqrt(1 - pow(2 * t, 2))) / 2 or (sqrt(1 - pow(-2 * t + 2, 2)) + 1) / 2;
end
local function easeOutBounce(t)
local n1 = 7.5625;
local d1 = 2.75;
if (t < 1 / d1)then
return n1 * t * t
elseif (t < 2 / d1)then
local a = t - 1.5 / d1
return n1 * a * a + 0.75;
elseif (t < 2.5 / d1)then
local a = t - 2.25 / d1
return n1 * a * a + 0.9375;
else
local a = t - 2.625 / d1
return n1 * a * a + 0.984375;
end
end
local function easeInBounce(t)
return 1 - easeOutBounce(1 - t)
end
local function easeInOutBounce(t)
return x < 0.5 and (1 - easeOutBounce(1 - 2 * t)) / 2 or (1 + easeOutBounce(2 * t - 1)) / 2;
end
local lerp = {
linear = linear,
lerp = lerp,
flip=flip,
easeIn=easeIn,
easeInSine = easeInSine,
easeInBack=easeInBack,
easeInCubic=easeInCubic,
easeInElastic=easeInElastic,
easeInExpo=easeInExpo,
easeInQuad=easeInQuad,
easeInQuart=easeInQuart,
easeInQuint=easeInQuint,
easeInCirc=easeInCirc,
easeInBounce=easeInBounce,
easeOut=easeOut,
easeOutSine = easeOutSine,
easeOutBack=easeOutBack,
easeOutCubic=easeOutCubic,
easeOutElastic=easeOutElastic,
easeOutExpo=easeOutExpo,
easeOutQuad=easeOutQuad,
easeOutQuart=easeOutQuart,
easeOutQuint=easeOutQuint,
easeOutCirc=easeOutCirc,
easeOutBounce=easeOutBounce,
easeInOut=easeInOut,
easeInOutSine = easeInOutSine,
easeInOutBack=easeInOutBack,
easeInOutCubic=easeInOutCubic,
easeInOutElastic=easeInOutElastic,
easeInOutExpo=easeInOutExpo,
easeInOutQuad=easeInOutQuad,
easeInOutQuart=easeInOutQuart,
easeInOutQuint=easeInOutQuint,
easeInOutCirc=easeInOutCirc,
easeInOutBounce=easeInOutBounce,
}
local activeAnimations = {}
return function(name)
local object = {}
local objectType = "Animation"
@@ -117,16 +302,36 @@ return function(name)
end
local function predefinedLerp(v1,v2,d,t,get,set)
local function predefinedLerp(v1,v2,d,t,get,set,typ,self)
local obj = _OBJ
local x,y
local name = ""
if(obj.parent~=nil)then name = obj.parent:getName() end
name = name..obj:getName()
addAnimationPart(t+0.05, function()
x,y = get(_OBJ)
if(typ~=nil)then
if(activeAnimations[typ]==nil)then activeAnimations[typ] = {} end
if(activeAnimations[typ][name]~=nil)then
if(activeAnimations[typ][name]~=self)then
activeAnimations[typ][name]:cancel()
end
end
activeAnimations[typ][name] = self
end
x,y = get(obj)
end)
for n=0.05,d,0.05 do
for n=0.05,d+0.01,0.05 do
addAnimationPart(t+n, function()
local _x = math.floor(lerp.lerp(x, v1, lerp[mode](n / d))+0.5)
local _y = math.floor(lerp.lerp(y, v2, lerp[mode](n / d))+0.5)
set(_OBJ, _x,_y)
set(obj, _x,_y)
if(typ~=nil)then
if(n>=d-0.01)then
if(activeAnimations[typ][name]==self)then
activeAnimations[typ][name] = nil
end
end
end
end)
end
end;
@@ -149,6 +354,11 @@ return function(name)
return self
end,
addMode = function(self, modeId, modeF)
lerp[modeId] = modeF
return self
end,
generateXMLEventFunction = function(self, func, val)
local createF = function(str)
if(str:sub(1,1)=="#")then
@@ -274,19 +484,19 @@ return function(name)
move = function(self, x, y, duration, timer, obj)
_OBJ = obj or _OBJ
predefinedLerp(x,y,duration,timer or 0,_OBJ.getPosition,_OBJ.setPosition)
predefinedLerp(x,y,duration,timer or 0,_OBJ.getPosition,_OBJ.setPosition, "position", self)
return self
end,
offset = function(self, x, y, duration, timer, obj)
_OBJ = obj or _OBJ
predefinedLerp(x,y,duration,timer or 0,_OBJ.getOffset,_OBJ.setOffset)
predefinedLerp(x,y,duration,timer or 0,_OBJ.getOffset,_OBJ.setOffset, "offset", self)
return self
end,
size = function(self, w, h, duration, timer, obj)
_OBJ = obj or _OBJ
predefinedLerp(w,h,duration,timer or 0,_OBJ.getSize,_OBJ.setSize)
predefinedLerp(w,h,duration,timer or 0,_OBJ.getSize,_OBJ.setSize, "size", self)
return self
end,
@@ -326,9 +536,9 @@ return function(name)
return self
end,
add = function(self, func, wait)
add = function(self, func, timer)
lastFunc = func
addAnimationPart((wait or nextWaitTimer) + (animations[#animations]~=nil and animations[#animations].t or 0), func)
addAnimationPart((timer or nextWaitTimer) + (animations[#animations]~=nil and animations[#animations].t or 0), func)
return self
end;
@@ -363,6 +573,7 @@ return function(name)
animationDoneHandler = function(self)
eventSystem:sendEvent("animation_done", self)
self.parent:removeEvent("other_event", self)
if(autoDestroy)then
self.parent:removeObject(self)
self = nil
@@ -393,11 +604,12 @@ return function(name)
if (animations[index].t > 0) then
timerObj = os.startTimer(animations[index].t)
else
onPlay()
onPlay(self)
end
else
self:animationDoneHandler()
end
self.parent:addEvent("other_event", self)
return self
end;
@@ -407,6 +619,7 @@ return function(name)
infinitePlay = false
end
animationActive = false
self.parent:removeEvent("other_event", self)
return self
end;

View File

@@ -1,6 +1,7 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
-- Button
@@ -16,22 +17,29 @@ return function(name)
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("ButtonBG")
self.fgColor = self.parent:getTheme("ButtonText")
if(base.init(self))then
self.bgColor = self.parent:getTheme("ButtonBG")
self.fgColor = self.parent:getTheme("ButtonText")
end
end,
getType = function(self)
return objectType
end;
setHorizontalAlign = function(self, pos)
textHorizontalAlign = pos
self:updateDraw()
return self
end;
setVerticalAlign = function(self, pos)
textVerticalAlign = pos
self:updateDraw()
return self
end;
setText = function(self, text)
base:setValue(text)
base:setValue(tostring(text))
self:updateDraw()
return self
end;
@@ -50,20 +58,16 @@ return function(name)
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
self.parent:drawTextBox(obx, oby, w, h, " ")
end
if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) end
for n = 1, h do
if (n == verticalAlign) then
self.parent:setText(obx, oby + (n - 1), utils.getTextHorizontalAlign(self:getValue(), w, textHorizontalAlign))
local val = self:getValue()
self.parent:setText(obx + (w/2-val:len()/2), oby + (n - 1), utils.getTextHorizontalAlign(val, val:len(), textHorizontalAlign))
self.parent:setFG(obx + (w/2-val:len()/2), oby + (n - 1), utils.getTextHorizontalAlign(tHex[self.fgColor]:rep(val:len()), val:len(), textHorizontalAlign))
end
end
end
self:setVisualChanged(false)
end
end;
end,
}
return setmetatable(object, base)

View File

@@ -12,31 +12,38 @@ return function(name)
base.width = 1
base.height = 1
local object = {
symbol = "\42",
local symbol = "\42"
init = function(self)
self.bgColor = self.parent:getTheme("CheckboxBG")
self.fgColor = self.parent:getTheme("CheckboxText")
end,
local object = {
getType = function(self)
return objectType
end;
mouseHandler = function(self, event, button, x, y)
if (base.mouseHandler(self, event, button, x, y)) then
if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then
setSymbol = function(self, sym)
symbol = sym
self:updateDraw()
return self
end,
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
if(button == 1)then
if (self:getValue() ~= true) and (self:getValue() ~= false) then
self:setValue(false)
else
self:setValue(not self:getValue())
end
end
self:updateDraw()
return true
end
end
return false
end;
end,
touchHandler = function(self, x, y)
return self:mouseHandler(1, x, y)
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
@@ -54,17 +61,24 @@ return function(name)
for n = 1, h do
if (n == verticalAlign) then
if (self:getValue() == true) then
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(self.symbol, w, "center"), self.bgColor, self.fgColor)
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(symbol, w, "center"), self.bgColor, self.fgColor)
else
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(" ", w, "center"), self.bgColor, self.fgColor)
end
end
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("CheckboxBG")
self.fgColor = self.parent:getTheme("CheckboxText")
end
end,
}
return setmetatable(object, base)

View File

@@ -26,12 +26,6 @@ return function(name)
getType = function(self)
return objectType
end;
init = function(self)
self.bgColor = self.parent:getTheme("DropdownBG")
self.fgColor = self.parent:getTheme("DropdownText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
@@ -51,6 +45,7 @@ return function(name)
setOffset = function(self, yOff)
yOffset = yOff
self:updateDraw()
return self
end;
@@ -60,6 +55,7 @@ return function(name)
addItem = function(self, text, bgCol, fgCol, ...)
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
@@ -69,6 +65,7 @@ return function(name)
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
@@ -87,7 +84,8 @@ return function(name)
clear = function(self)
list = {}
self:setValue({})
self:setValue({}, false)
self:updateDraw()
return self
end;
@@ -98,67 +96,108 @@ return function(name)
editItem = function(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {})
self:setValue(list[index] or {}, false)
self:updateDraw()
return self
end;
setSelectedItem = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self.bgColor
itemSelectedFG = fgCol or self.fgColor
selectionColorActive = active
selectionColorActive = active~=nil and active
self:updateDraw()
return self
end;
setDropdownSize = function(self, width, height)
dropdownW, dropdownH = width, height
self:updateDraw()
return self
end;
end,
mouseHandler = function(self, event, button, x, y)
getDropdownSize = function(self)
return dropdownW, dropdownH
end,
mouseHandler = function(self, button, x, y)
if (isOpened) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
if ((event == "mouse_click") and (button == 1)) or (event == "monitor_touch") then
if(button==1)then
if (#list > 0) then
for n = 1, dropdownH do
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
self:setValue(list[n + yOffset])
self:updateDraw()
local val = self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", dir, x, y)
if(val==false)then return val end
return true
end
end
end
end
end
end
if (base.mouseHandler(self, button, x, y)) then
isOpened = (not isOpened)
self:updateDraw()
return true
else
if(isOpened)then
self:updateDraw()
isOpened = false
end
return false
end
end,
if (event == "mouse_scroll") then
yOffset = yOffset + button
if (yOffset < 0) then
yOffset = 0
end
if (button == 1) then
if (#list > dropdownH) then
if (yOffset > #list - dropdownH) then
yOffset = #list - dropdownH
mouseUpHandler = function(self, button, x, y)
if (isOpened) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
if(button==1)then
if (#list > 0) then
for n = 1, dropdownH do
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + dropdownW > x) and (oby + n == y) then
isOpened = false
self:updateDraw()
local val = self:getEventSystem():sendEvent("mouse_up", self, "mouse_up", dir, x, y)
if(val==false)then return val end
return true
end
end
else
yOffset = math.min(#list - 1, 0)
end
end
return true
end
self:setVisualChanged()
end
if (base.mouseHandler(self, event, button, x, y)) then
isOpened = true
else
isOpened = false
end,
scrollHandler = function(self, dir, x, y)
if (isOpened)and(self:isFocused()) then
yOffset = yOffset + dir
if (yOffset < 0) then
yOffset = 0
end
if (dir == 1) then
if (#list > dropdownH) then
if (yOffset > #list - dropdownH) then
yOffset = #list - dropdownH
end
else
yOffset = math.min(#list - 1, 0)
end
end
local val = self:getEventSystem():sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y)
if(val==false)then return val end
self:updateDraw()
return true
end
end;
end,
draw = function(self)
if (base.draw(self)) then
@@ -186,9 +225,20 @@ return function(name)
end
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("DropdownBG")
self.fgColor = self.parent:getTheme("DropdownText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end
end,
}
return setmetatable(object, base)

View File

@@ -1,7 +1,8 @@
local Object = require("Object")
local geometric = require("geometricPoints")
local tHex = require("tHex")
local xmlValue = require("utils").getValueFromXML
local bimgLib = require("bimg")
local images = require("images")
local sub,len,max,min = string.sub,string.len,math.max,math.min
@@ -9,420 +10,181 @@ return function(name)
-- Graphic
local base = Object(name)
local objectType = "Graphic"
base:setZIndex(2)
local imgData = bimgLib()
local bimgFrame = imgData.getFrameObject(1)
local bimg
local selectedFrame = 1
base:setZIndex(5)
local graphicObjects = {}
local graphic = {}
local shrinkedGraphic = {}
local isGraphicShrinked = false
local xOffset, yOffset = 0, 0
local dragable = false
local xMouse,yMouse
local w, h = 40, 15
local canvasSizeChanged = false
local tColourLookup = {}
for n=1,16 do
tColourLookup[ string.byte( "0123456789abcdef",n,n ) ] = 2^(n-1)
end
local function stringToTable(str)
local t = {}
for i = 1, #str do
t[i] = str:sub(i, i)
end
return t
end
local function setBG(x, y, width, height, colorStr)
if (y >= 1) and (y <= height) then
if (x + len(colorStr) > 0) and (x <= width) then
local oldCache = graphic[y]
local newCache
local nEnd = x + #colorStr - 1
if (x < 1) then
colorStr = sub(colorStr, 1 - x + 1, width - x + 1)
elseif (nEnd > width) then
colorStr = sub(colorStr, 1, width - x + 1)
end
if (x > 1) then
newCache = sub(oldCache, 1, x - 1) .. colorStr
else
newCache = colorStr
end
if nEnd < width then
newCache = newCache .. sub(oldCache, nEnd + 1, width)
end
graphic[y] = newCache
end
end
end
local function redrawCanvasSize()
local w,h = w,h
if(isGraphicShrinked)then w = w*2 h = h*3 end
for y=1,h do
if(graphic[y]~=nil)then
if(w>graphic[y]:len())then
graphic[y] = graphic[y]..(tHex[base.bgColor]):rep(w-graphic[y]:len())
else
graphic[y] = graphic[y]:sub(1,w)
end
else
graphic[y] = (tHex[base.bgColor]):rep(w)
end
end
end
redrawCanvasSize()
local function shrink()
local function parseLine( tImageArg, sLine )
local tLine = {}
for x=1,sLine:len() do
tLine[x] = tColourLookup[ string.byte(sLine,x,x) ] or 0
end
table.insert( tImageArg, tLine )
end
function parseImage( sRawData )
if type( sRawData ) ~= "string" then
error( "bad argument #1 (expected string, got " .. type( sRawData ) .. ")" )
end
local tImage = {}
for sLine in ( sRawData .. "\n" ):gmatch( "(.-)\n" ) do
parseLine( tImage, sLine )
end
return tImage
end
local rawImg = ""
for y=1,#graphic do
if(y==#graphic)then
rawImg = rawImg..graphic[y]
else
rawImg = rawImg..graphic[y].."\n"
end
end
local img = parseImage(rawImg)
-- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 },
{ 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } }
local colourNum, exponents, colourChar = {}, {}, {}
for i = 0, 15 do
exponents[2 ^ i] = i
end
do
local hex = "0123456789abcdef"
for i = 1, 16 do
colourNum[hex:sub(i, i)] = i - 1
colourNum[i - 1] = hex:sub(i, i)
colourChar[hex:sub(i, i)] = 2 ^ (i - 1)
colourChar[2 ^ (i - 1)] = hex:sub(i, i)
local thisRel = relations[i - 1]
for i = 1, #thisRel do
thisRel[i] = 2 ^ thisRel[i]
end
end
end
local function getBestColourMatch(usage)
local lastCol = relations[exponents[usage[#usage][1]]]
for j = 1, #lastCol do
local thisRelation = lastCol[j]
for i = 1, #usage - 1 do
if usage[i][1] == thisRelation then
return i
end
end
end
return 1
end
local function colsToChar(pattern, totals)
if not totals then
local newPattern = {}
totals = {}
for i = 1, 6 do
local thisVal = pattern[i]
local thisTot = totals[thisVal]
totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal
end
pattern = newPattern
end
local usage = {}
for key, value in pairs(totals) do
usage[#usage + 1] = { key, value }
end
if #usage > 1 then
-- Reduce the chunk to two colours:
while #usage > 2 do
table.sort(usage, function(a, b)
return a[2] > b[2]
end)
local matchToInd, usageLen = getBestColourMatch(usage), #usage
local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1]
for i = 1, 6 do
if pattern[i] == matchFrom then
pattern[i] = matchTo
usage[matchToInd][2] = usage[matchToInd][2] + 1
end
end
usage[usageLen] = nil
end
-- Convert to character. Adapted from oli414's function:
-- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/
local data = 128
for i = 1, #pattern - 1 do
if pattern[i] ~= pattern[6] then
data = data + 2 ^ (i - 1)
end
end
return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]]
else
-- Solid colour character:
return "\128", colourChar[pattern[1]], colourChar[pattern[1]]
end
end
local results, width, height, bgCol = { {}, {}, {} }, 0, #img + #img % 3, base.bgColor or colors.black
for i = 1, #img do
if #img[i] > width then
width = #img[i]
end
end
for y = 0, height - 1, 3 do
local cRow, tRow, bRow, counter = {}, {}, {}, 1
for x = 0, width - 1, 2 do
-- Grab a 2x3 chunk:
local pattern, totals = {}, {}
for yy = 1, 3 do
for xx = 1, 2 do
pattern[#pattern + 1] = (img[y + yy] and img[y + yy][x + xx]) and (img[y + yy][x + xx] == 0 and bgCol or img[y + yy][x + xx]) or bgCol
totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1
end
end
cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals)
counter = counter + 1
end
results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow)
end
results.width, results.height = #results[1][1], #results[1]
shrinkedGraphic = results
end
local function redraw()
local w,h = w,h
if(isGraphicShrinked)then w = w*2 h = h*3 end
for k,v in pairs(graphicObjects)do
for a,b in pairs(v[1])do
setBG(b.x, b.y, w, h, v[2])
end
end
if(isGraphicShrinked)then
shrink()
end
end
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("GraphicBG")
end,
getType = function(self)
return objectType
end;
setSize = function(self, width, height, rel)
base.setSize(self, width, height, rel)
if not(canvasSizeChanged)then
w = width
h = height
redrawCanvasSize()
setOffset = function(self, _x, _y, rel)
if(rel)then
xOffset = xOffset + _x or 0
yOffset = yOffset + _y or 0
else
xOffset = _x or xOffset
yOffset = _y or yOffset
end
redraw()
self:updateDraw()
return self
end,
setOffset = function(self, x, y)
xOffset = x or xOffset
yOffset = y or yOffset
return self
end,
setCanvasSize = function(self, width, height)
w,h = width,height
canvasSizeChanged = true
redrawCanvasSize()
return self
end,
clearCanvas = function(self)
graphicObjects = {}
graphic = {}
redrawCanvasSize()
end,
getOffset = function(self)
return xOffset,yOffset
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end
if(xmlValue("xOffset", data)~=nil)then self:setOffset(xmlValue("xOffset", data), yOffset) end
if(xmlValue("yOffset", data)~=nil)then self:setOffset(xOffset, xmlValue("yOffset", data)) end
if(xmlValue("wCanvas", data)~=nil)then w = xmlValue("wCanvas", data) end
if(xmlValue("hCanvas", data)~=nil)then h = xmlValue("hCanvas", data) end
if(xmlValue("shrink", data)~=nil)then if(xmlValue("shrink", data))then self:shrink() end end
if(xmlValue("dragable", data)~=nil)then if(xmlValue("dragable", data))then dragable = true end end
if(data["ellipse"]~=nil)then
local tab = data["ellipse"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
local col = colors[xmlValue("color", v)]
local rad1 = xmlValue("radius", v)
local rad2 = xmlValue("radius2", v)
local x = xmlValue("x", v)
local y = xmlValue("y", v)
local filled = xmlValue("filled", v)
self:addEllipse(col, rad1, rad2, x, y, filled)
end
end
if(data["circle"]~=nil)then
local tab = data["circle"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
local col = colors[xmlValue("color", v)]
local rad = tonumber(xmlValue("radius", v))
local x = tonumber(xmlValue("x", v))
local y = tonumber(xmlValue("y", v))
local filled = xmlValue("filled", v)
self:addCircle(col, rad, x, y, filled)
end
end
if(data["line"]~=nil)then
local tab = data["line"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
local col = colors[xmlValue("color", v)]
local x = tonumber(xmlValue("x", v))
local x2 = tonumber(xmlValue("x2", v))
local y = tonumber(xmlValue("y", v))
local y2 = tonumber(xmlValue("y2", v))
self:addLine(col, x, y, x2, y2)
end
end
if(data["rectangle"]~=nil)then
local tab = data["rectangle"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
local col = colors[xmlValue("color", v)]
local x = tonumber(xmlValue("x", v))
local x2 = tonumber(xmlValue("x2", v))
local y = tonumber(xmlValue("y", v))
local y2 = tonumber(xmlValue("y2", v))
local filled = xmlValue("filled", v)=="true" and true or false
self:addRectangle(col, x, y, x2, y2, filled)
end
end
if(data["triangle"]~=nil)then
local tab = data["triangle"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
local col = colors[xmlValue("color", v)]
local x = tonumber(xmlValue("x", v))
local x2 = tonumber(xmlValue("x2", v))
local x3 = tonumber(xmlValue("x2", v))
local y = tonumber(xmlValue("y", v))
local y2 = tonumber(xmlValue("y2", v))
local y3 = tonumber(xmlValue("y3", v))
local filled = xmlValue("filled", v)
self:addTriangle(col, x, y, x2, y2, x3, y3, filled)
end
end
return self
end,
addCircle = function(self, color, rad, x, y, filled)
local col = tHex[color]
table.insert(graphicObjects, {geometric.circle(x or 1, y or 1, rad, filled), tHex[color]})
redraw()
return self
end;
addEllipse = function(self, color, rad, rad2, x, y, filled)
table.insert(graphicObjects, {geometric.ellipse(x or 1, y or 1, rad, rad2, filled), tHex[color]})
redraw()
return self
end;
addLine = function(self, color, x1, y1, x2, y2)
table.insert(graphicObjects, {geometric.line(x1 or 1, y1 or 1, x2 or 1, y2 or 1), tHex[color]})
redraw()
return self
end;
addTriangle = function(self, color, x1, y1, x2, y2, x3, y3, filled)
table.insert(graphicObjects, {geometric.triangle(x1 or 1, y1 or 1, x2 or 1, y2 or 1, x3 or 1, y3 or 1, filled), tHex[color]})
redraw()
return self
end;
addRectangle = function(self, color, x1, y1, x2, y2, filled)
table.insert(graphicObjects, {geometric.rectangle(x1 or 1, y1 or 1, x2 or 1, y2 or 1, filled), tHex[color]})
redraw()
return self
end;
shrink = function(self)
isGraphicShrinked = true
redrawCanvasSize()
shrink()
return self
end,
setDragable = function(self, drag)
dragable = drag == true and true or false
return self
end,
mouseHandler = function(self, event, button, x, y)
if(base.mouseHandler(self, event, button, x, y))then
if(dragable)then
if(event=="mouse_click")then
xMouse,yMouse = x,y
end
if(event=="mouse_drag")then
if(xMouse~=nil)and(yMouse~=nil)then
xOffset = max(min(xOffset+xMouse-x, w-self:getWidth()),0)
xMouse = x
yOffset = max(min(yOffset+yMouse-y, h-self:getHeight()),0)
yMouse = y
end
end
end
return true
selectFrame = function(self, id)
if(imgData.getFrameObject(id)==nil)then
imgData.addFrame(id)
end
return false
bimgFrame = imgData.getFrameObject(id)
bimg = bimgFrame.getImage(id)
selectedFrame = id
self:updateDraw()
end,
addFrame = function(self, id)
imgData.addFrame(id)
return self
end,
getFrameMetadata = function(self, id, key)
return imgData.getFrameData(id, key)
end,
setFrameMetadata = function(self, id, key, val)
imgData.setFrameData(id, key, val)
return self
end,
getMetadata = function(self, key)
return imgData.getMetadata(key)
end,
setMetadata = function(self, key, value)
return imgData.setMetadata(key, value)
end,
getFrame = function(self, id)
return imgData.getFrame(id)
end,
getFrameObject = function(self, id)
return imgData.getFrameObject(id)
end,
removeFrame = function(self, id)
imgData.removeFrame(id)
return self
end,
moveFrame = function(self, id, dir)
imgData.moveFrame(id, dir)
return self
end,
getFrames = function(self)
return imgData.getFrames()
end,
getFrameCount = function(self)
return #imgData.getFrames()
end,
getSelectedFrame = function(self)
return selectedFrame
end,
blit = function(self, text, fg, bg, _x, _y)
x = _x or x
y = _y or y
bimgFrame.blit(text, fg, bg, x, y)
bimg = bimgFrame.getImage()
self:updateDraw()
return self
end,
setText = function(self, text, _x, _y)
x = _x or x
y = _y or y
bimgFrame.text(text, x, y)
bimg = bimgFrame.getImage()
self:updateDraw()
return self
end,
setBg = function(self, bg, _x, _y)
x = _x or x
y = _y or y
bimgFrame.bg(bg, x, y)
bimg = bimgFrame.getImage()
self:updateDraw()
return self
end,
setFg = function(self, fg, _x, _y)
x = _x or x
y = _y or y
bimgFrame.fg(fg, x, y)
bimg = bimgFrame.getImage()
self:updateDraw()
return self
end,
getImageSize = function(self)
return imgData.getSize()
end,
setImageSize = function(self, w, h)
imgData.setSize(w, h)
bimg = bimgFrame.getImage()
self:updateDraw()
return self
end,
resizeImage = function(self, w, h)
local newBimg = images.resizeBIMG(imgData.createBimg(), w, h)
imgData = bimgLib(newBimg)
selectedFrame = 1
bimgFrame = imgData.getFrameObject(1)
bimg = bimgFrame.getImage()
self:updateDraw()
return self
end,
loadImage = function(self, path)
if(fs.exists(path))then
local newBimg = images.loadBIMG(path)
imgData = bimgLib(newBimg)
selectedFrame = 1
bimgFrame = imgData.getFrameObject(1)
bimg = bimgFrame.getImage()
self:updateDraw()
end
return self
end,
clear = function(self)
imgData = bimgLib()
bimg = nil
self:updateDraw()
return self
end,
getImage = function(self)
return imgData.createBimg()
end,
draw = function(self)
@@ -430,41 +192,22 @@ return function(name)
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
end
if (isGraphicShrinked) then
-- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
local t, tC, bC = shrinkedGraphic[1], shrinkedGraphic[2], shrinkedGraphic[3]
for i = 1, shrinkedGraphic.height do
local x, y = obx+xOffset, oby + i - 1 + yOffset
if(y>oby-1)and(y<=oby+h-1)and(x<=w+obx)then
local tI = t[i]
local xpos,substart,subend = max(x, obx), max(1 - x + 1, 1), min(w - (x-obx), w)
if type(tI) == "string" then
self.parent:setText(xpos, y, sub(tI, substart, subend))
self.parent:setFG(xpos, y, sub(tC[i], substart, subend))
self.parent:setBG(xpos, y, sub(bC[i], substart, subend))
elseif type(tI) == "table" then
self.parent:setText(xpos, y, sub(tI[2], substart, subend))
self.parent:setFG(xpos, y, sub(tC[i], substart, subend))
self.parent:setBG(xpos, y, sub(bC[i], substart, subend))
end
end
end
else
for i = 1, #graphic do
local x, y = obx+xOffset, oby + i - 1 + yOffset
if(y>oby-1)and(y<=oby+h-1)and(x<=w+obx)then
local xpos,substart,subend = max(x, obx), max(1 - x + 1, 1), min(w - (x-obx), w)
self.parent:setBG(xpos, y, sub(graphic[i],substart,subend))
if(bimg~=nil)then
for k,v in pairs(bimg)do
if(k<=h-yOffset)and(k+yOffset>=1)then
self.parent:blit(obx+xOffset, oby+k-1+yOffset, v[1], v[2], v[3])
end
end
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("GraphicBG")
end
end,
}
return setmetatable(object, base)

View File

@@ -1,200 +1,162 @@
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
local images = require("images")
local unpack,sub = table.unpack,string.sub
return function(name)
-- Image
local base = Object(name)
local objectType = "Image"
base:setZIndex(2)
local originalImage
local image
local shrinkedImage
local imageGotShrinked = false
local curFrame = 1
local infinitePlay = false
local animTimer
local usePalette = false
local function shrink()
-- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 },
{ 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } }
base.width = 24
base.height = 8
local colourNum, exponents, colourChar = {}, {}, {}
for i = 0, 15 do
exponents[2 ^ i] = i
end
do
local hex = "0123456789abcdef"
for i = 1, 16 do
colourNum[hex:sub(i, i)] = i - 1
colourNum[i - 1] = hex:sub(i, i)
colourChar[hex:sub(i, i)] = 2 ^ (i - 1)
colourChar[2 ^ (i - 1)] = hex:sub(i, i)
local thisRel = relations[i - 1]
for i = 1, #thisRel do
thisRel[i] = 2 ^ thisRel[i]
local function getPalette(id)
if(originalImage~=nil)then
local p = {}
for k,v in pairs(colors)do
if(type(v)=="number")then
p[k] = {term.nativePaletteColor(v)}
end
end
end
local function getBestColourMatch(usage)
local lastCol = relations[exponents[usage[#usage][1]]]
for j = 1, #lastCol do
local thisRelation = lastCol[j]
for i = 1, #usage - 1 do
if usage[i][1] == thisRelation then
return i
end
if(originalImage.palette~=nil)then
for k,v in pairs(originalImage.palette)do
p[k] = tonumber(v)
end
end
return 1
end
local function colsToChar(pattern, totals)
if not totals then
local newPattern = {}
totals = {}
for i = 1, 6 do
local thisVal = pattern[i]
local thisTot = totals[thisVal]
totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal
if(originalImage[id]~=nil)and(originalImage[id].palette~=nil)then
for k,v in pairs(originalImage[id].palette)do
p[k] = tonumber(v)
end
pattern = newPattern
end
local usage = {}
for key, value in pairs(totals) do
usage[#usage + 1] = { key, value }
end
if #usage > 1 then
-- Reduce the chunk to two colours:
while #usage > 2 do
table.sort(usage, function(a, b)
return a[2] > b[2]
end)
local matchToInd, usageLen = getBestColourMatch(usage), #usage
local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1]
for i = 1, 6 do
if pattern[i] == matchFrom then
pattern[i] = matchTo
usage[matchToInd][2] = usage[matchToInd][2] + 1
end
end
usage[usageLen] = nil
end
-- Convert to character. Adapted from oli414's function:
-- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/
local data = 128
for i = 1, #pattern - 1 do
if pattern[i] ~= pattern[6] then
data = data + 2 ^ (i - 1)
end
end
return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]]
else
-- Solid colour character:
return "\128", colourChar[pattern[1]], colourChar[pattern[1]]
end
return p
end
local results, width, height, bgCol = { {}, {}, {} }, 0, #image + #image % 3, base.bgColor or colors.black
for i = 1, #image do
if #image[i] > width then
width = #image[i]
end
end
for y = 0, height - 1, 3 do
local cRow, tRow, bRow, counter = {}, {}, {}, 1
for x = 0, width - 1, 2 do
-- Grab a 2x3 chunk:
local pattern, totals = {}, {}
for yy = 1, 3 do
for xx = 1, 2 do
pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol
totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1
end
end
cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals)
counter = counter + 1
end
results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow)
end
results.width, results.height = #results[1][1], #results[1]
shrinkedImage = results
end
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("ImageBG")
if(base.init(self))then
self.bgColor = self.parent:getTheme("ImageBG")
end
end,
getType = function(self)
return objectType
end;
loadImage = function(self, path)
image = paintutils.loadImage(path)
imageGotShrinked = false
loadImage = function(self, path, f)
if not(fs.exists(path))then error("No valid path: "..path) end
originalImage = images.loadImageAsBimg(path, f)
curFrame = 1
image = originalImage
if(animTimer~=nil)then
os.cancelTimer(animTimer)
end
self:updateDraw()
return self
end;
shrink = function(self)
shrink()
imageGotShrinked = true
setImage = function(self, data)
originalImage = data
image = originalImage
curFrame = 1
if(animTimer~=nil)then
os.cancelTimer(animTimer)
end
self:updateDraw()
return self
end;
end,
usePalette = function(self, use)
usePalette = use~=nil and use or true
return self
end,
play = function(self, inf)
if(originalImage.animated)then
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
self.parent:addEvent("other_event", self)
animTimer = os.startTimer(t)
infinitePlay = inf or false
end
return self
end,
selectFrame = function(self, fr)
if(originalImage[fr]~=nil)then
curFrame = fr
if(animTimer~=nil)then
os.cancelTimer(animTimer)
end
self:updateDraw()
end
end,
eventHandler = function(self, event, timerId, ...)
base.eventHandler(self, event, timerId, ...)
if(event=="timer")then
if(timerId==animTimer)then
if(originalImage[curFrame+1]~=nil)then
curFrame = curFrame + 1
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
animTimer = os.startTimer(t)
else
if(infinitePlay)then
curFrame = 1
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
animTimer = os.startTimer(t)
end
end
self:updateDraw()
end
end
end,
getMetadata = function(self, key)
return originalImage[key]
end,
getImageSize = function(self)
return originalImage.width, originalImage.height
end,
resizeImage = function(self, w, h)
image = images.resizeBIMG(originalImage, w, h)
self:updateDraw()
return self
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("shrink", data)~=nil)then if(xmlValue("shrink", data))then self:shrink() end end
if(xmlValue("path", data)~=nil)then self:loadImage(xmlValue("path", data)) end
return self
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
if (image ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (imageGotShrinked) then
-- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
local t, tC, bC = shrinkedImage[1], shrinkedImage[2], shrinkedImage[3]
for i = 1, shrinkedImage.height do
local tI = t[i]
if type(tI) == "string" then
self.parent:setText(obx, oby + i - 1, tI)
self.parent:setFG(obx, oby + i - 1, tC[i])
self.parent:setBG(obx, oby + i - 1, bC[i])
elseif type(tI) == "table" then
self.parent:setText(obx, oby + i - 1, tI[2])
self.parent:setFG(obx, oby + i - 1, tC[i])
self.parent:setBG(obx, oby + i - 1, bC[i])
end
end
else
for yPos = 1, math.min(#image, h) do
local line = image[yPos]
for xPos = 1, math.min(#line, w) do
if line[xPos] > 0 then
self.parent:drawBackgroundBox(obx + xPos - 1, oby + yPos - 1, 1, 1, line[xPos])
end
end
end
end
if (image ~= nil) then
if(usePalette)then
self:getBaseFrame():setThemeColor(getPalette(curFrame))
end
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
for y,v in ipairs(image[curFrame])do
local t, f, b = unpack(v)
t = sub(t, 1,w)
f = sub(f, 1,w)
b = sub(b, 1,w)
self.parent:blit(obx, oby+y-1, t, f, b)
if(y==h)then break end
end
end
self:setVisualChanged(false)
end
end;
end,
}
return setmetatable(object, base)

View File

@@ -1,5 +1,6 @@
local Object = require("Object")
local utils = require("utils")
local log = require("basaltLogs")
local xmlValue = utils.getValueFromXML
return function(name)
@@ -24,10 +25,6 @@ return function(name)
local internalValueChange = false
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("InputBG")
self.fgColor = self.parent:getTheme("InputFG")
end,
getType = function(self)
return objectType
end;
@@ -36,6 +33,7 @@ return function(name)
if (iType == "password") or (iType == "number") or (iType == "text") then
inputType = iType
end
self:updateDraw()
return self
end;
@@ -48,6 +46,7 @@ return function(name)
else
showingText = defaultText
end
self:updateDraw()
return self
end;
@@ -59,7 +58,13 @@ return function(name)
base.setValue(self, tostring(val))
if not (internalValueChange) then
textX = tostring(val):len() + 1
wIndex = math.max(1, textX-self:getWidth()+1)
if(self:isFocused())then
local obx, oby = self:getAnchorPosition()
self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor)
end
end
self:updateDraw()
return self
end;
@@ -70,6 +75,7 @@ return function(name)
setInputLimit = function(self, limit)
inputLimit = tonumber(limit) or inputLimit
self:updateDraw()
return self
end;
@@ -93,25 +99,28 @@ return function(name)
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
showingText = ""
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor)
if(defaultText~="")then
self:updateDraw()
end
self.parent:setCursor(true, obx + textX - wIndex, oby+math.max(math.ceil(self:getHeight()/2-1, 1)), self.fgColor)
end
end;
loseFocusHandler = function(self)
base.loseFocusHandler(self)
if (self.parent ~= nil) then
self.parent:setCursor(false)
showingText = defaultText
if(defaultText~="")then
self:updateDraw()
end
self.parent:setCursor(false)
end
end;
keyHandler = function(self, event, key)
if (base.keyHandler(self, event, key)) then
keyHandler = function(self, key)
if (base.keyHandler(self, key)) then
local w,h = self:getSize()
internalValueChange = true
if (event == "key") then
if (key == keys.backspace) then
-- on backspace
local text = tostring(base.getValue())
@@ -167,52 +176,140 @@ return function(name)
wIndex = 1
end
end
local obx, oby = self:getAnchorPosition()
local val = tostring(base.getValue())
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
local inpX = self:getX()
if (cursorX > inpX + w - 1) then
cursorX = inpX + w - 1
end
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
end
self:updateDraw()
internalValueChange = false
return true
end
return false
end,
if (event == "char") then
local text = base.getValue()
if (text:len() < inputLimit or inputLimit <= 0) then
if (inputType == "number") then
local cache = text
if (key == ".") or (tonumber(key) ~= nil) then
self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len()))
textX = textX + 1
end
if (tonumber(base.getValue()) == nil) then
self:setValue(cache)
end
else
self:setValue(text:sub(1, textX - 1) .. key .. text:sub(textX, text:len()))
charHandler = function(self, char)
if (base.charHandler(self, char)) then
internalValueChange = true
local w,h = self:getSize()
local text = base.getValue()
if (text:len() < inputLimit or inputLimit <= 0) then
if (inputType == "number") then
local cache = text
if (textX==1 and char == "-") or (char == ".") or (tonumber(char) ~= nil) then
self:setValue(text:sub(1, textX - 1) .. char .. text:sub(textX, text:len()))
textX = textX + 1
if(char==".")or(char=="-")and(#text>0)then
if (tonumber(base.getValue()) == nil) then
self:setValue(cache)
textX = textX - 1
end
end
end
if (textX >= w + wIndex) then
wIndex = wIndex + 1
end
else
self:setValue(text:sub(1, textX - 1) .. char .. text:sub(textX, text:len()))
textX = textX + 1
end
if (textX >= w + wIndex) then
wIndex = wIndex + 1
end
end
local obx, oby = self:getAnchorPosition()
local val = tostring(base.getValue())
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
if (cursorX > self.x + w - 1) then
cursorX = self.x + w - 1
local x = self:getX()
if (cursorX > x + w - 1) then
cursorX = x + w - 1
end
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + cursorX, oby+math.floor(h/2), self.fgColor)
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
end
internalValueChange = false
end
end;
mouseHandler = function(self, event, button, x, y)
if (base.mouseHandler(self, event, button, x, y)) then
if (event == "mouse_click") and (button == 1) then
end
self:updateDraw()
return true
end
return false
end;
end,
mouseHandler = function(self, button, x, y)
if(base.mouseHandler(self, button, x, y))then
local ax, ay = self:getAnchorPosition()
local obx, oby = self:getAbsolutePosition(ax, ay)
local w, h = self:getSize()
textX = x - obx + wIndex
local text = base.getValue()
if (textX > text:len()) then
textX = text:len() + 1
end
if (textX < wIndex) then
wIndex = textX - 1
if (wIndex < 1) then
wIndex = 1
end
end
self.parent:setCursor(true, ax + textX - wIndex, ay+math.max(math.ceil(h/2-1, 1)), self.fgColor)
return true
end
end,
dragHandler = function(self, btn, x, y, xOffset, yOffset)
if(self:isFocused())then
if(self:isCoordsInObject(x, y))then
if(base.dragHandler(self, btn, x, y, xOffset, yOffset))then
return true
end
end
self.parent:removeFocusedObject()
end
end,
eventHandler = function(self, event, paste, ...)
base.eventHandler(self, event, paste, ...)
if(event=="paste")then
if(self:isFocused())then
local text = base.getValue()
local w, h = self:getSize()
internalValueChange = true
if (inputType == "number") then
local cache = text
if (paste == ".") or (tonumber(paste) ~= nil) then
self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len()))
textX = textX + paste:len()
end
if (tonumber(base.getValue()) == nil) then
self:setValue(cache)
end
else
self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len()))
textX = textX + paste:len()
end
if (textX >= w + wIndex) then
wIndex = (textX+1)-w
end
local obx, oby = self:getAnchorPosition()
local val = tostring(base.getValue())
local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1)
local x = self:getX()
if (cursorX > x + w - 1) then
cursorX = x + w - 1
end
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
end
self:updateDraw()
internalValueChange = false
end
end
end,
draw = function(self)
if (base.draw(self)) then
@@ -246,14 +343,30 @@ return function(name)
if (inputType == "password") and (val ~= "") then
text = string.rep("*", text:len())
end
text = text .. string.rep(" ", space)
text = text .. string.rep(self.bgSymbol, space)
self.parent:writeText(obx, oby + (n - 1), text, bCol, fCol)
end
end
if(self:isFocused())then
self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor)
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
if(self.parent~=nil)then
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("key", self)
self.parent:addEvent("char", self)
self.parent:addEvent("other_event", self)
self.parent:addEvent("mouse_drag", self)
end
if(base.init(self))then
self.bgColor = self.parent:getTheme("InputBG")
self.fgColor = self.parent:getTheme("InputText")
end
end,
}
return setmetatable(object, base)

View File

@@ -31,29 +31,36 @@ return function(name)
text = tostring(text)
base:setValue(text)
if (autoSize) then
self.width = text:len()
local xOffset = self.parent:getOffset()
if(text:len()+self:getX()>self.parent:getWidth()+xOffset)then
local newW = self.parent:getWidth()+xOffset - self:getX()
base.setSize(self, newW, #createText(text, newW))
else
base.setSize(self, text:len(), 1)
end
end
if not(fgColChanged)then self.fgColor = self.parent:getForeground() or colors.white end
if not(bgColChanged)then self.bgColor = self.parent:getBackground() or colors.black end
self:updateDraw()
return self
end;
setBackground = function(self, col)
base.setBackground(self, col)
bgColChanged = true
self:updateDraw()
return self
end,
setForeground = function(self, col)
base.setForeground(self, col)
fgColChanged = true
self:updateDraw()
return self
end,
setTextAlign = function(self, hor, vert)
textHorizontalAlign = hor or textHorizontalAlign
textVerticalAlign = vert or textVerticalAlign
self:setVisualChanged()
self:updateDraw()
return self
end;
@@ -61,6 +68,7 @@ return function(name)
if(size>0)and(size<=4)then
fontsize = size-1 or 0
end
self:updateDraw()
return self
end;
@@ -77,60 +85,84 @@ return function(name)
return self
end,
setSize = function(self, width, height)
base.setSize(self, width, height)
setSize = function(self, width, height, rel)
base.setSize(self, width, height, rel)
autoSize = false
self:setVisualChanged()
self:updateDraw()
return self
end;
eventHandler = function(self, event)
if(event=="basalt_resize")then
if (autoSize) then
local text = self:getValue()
if(text:len()+self:getX()>self.parent:getWidth())then
local newW = self.parent:getWidth() - self:getX()
base.setSize(self, newW, #createText(text, newW))
else
base.setSize(self, text:len(), 1)
end
else
--self.parent:removeEvent("other_event", self)
end
end
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
self.parent:drawTextBox(obx, oby, w, h, " ") end
if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) end
if(fontsize==0)then
if not(autoSize)then
local text = createText(self:getValue(), self:getWidth())
for k,v in pairs(text)do
self.parent:setText(obx, oby+k-1, v)
if(k<=h)then
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
end
end
else
for n = 1, h do
if (n == verticalAlign) then
self.parent:setText(obx, oby + (n - 1), utils.getTextHorizontalAlign(self:getValue(), w, textHorizontalAlign))
if(#self:getValue()+obx>self.parent:getWidth())then
local text = createText(self:getValue(), self:getWidth())
for k,v in pairs(text)do
if(k<=h)then
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
end
end
else
self.parent:writeText(obx, oby, self:getValue(), self.bgColor, self.fgColor)
end
end
else
local tData = bigFont(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.black)
local tData = bigFont(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.lightGray)
if(autoSize)then
self:setSize(#tData[1][1], #tData[1]-1)
end
for n = 1, h do
if (n == verticalAlign) then
local oX, oY = self.parent:getSize()
local cX, cY = #tData[1][1], #tData[1]
obx = obx or math.floor((oX - cX) / 2) + 1
oby = oby or math.floor((oY - cY) / 2) + 1
for i = 1, cY do
self.parent:setFG(obx, oby + i + n - 2, utils.getTextHorizontalAlign(tData[2][i], w, textHorizontalAlign))
self.parent:setBG(obx, oby + i + n - 2, utils.getTextHorizontalAlign(tData[3][i], w, textHorizontalAlign, tHex[self.bgColor or colors.black]))
self.parent:setText(obx, oby + i + n - 2, utils.getTextHorizontalAlign(tData[1][i], w, textHorizontalAlign))
end
local oX, oY = self.parent:getSize()
local cX, cY = #tData[1][1], #tData[1]
obx = obx or math.floor((oX - cX) / 2) + 1
oby = oby or math.floor((oY - cY) / 2) + 1
for i = 1, cY do
self.parent:setFG(obx, oby + i - 1, tData[2][i])
self.parent:setBG(obx, oby + i - 1, tData[3][i])
self.parent:setText(obx, oby + i - 1, tData[1][i])
end
end
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("other_event", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("LabelBG")
self.fgColor = self.parent:getTheme("LabelText")
if(self.parent.bgColor==colors.black)and(self.fgColor==colors.black)then
self.fgColor = colors.lightGray
end
end
end
}

View File

@@ -18,26 +18,22 @@ return function(name)
local scrollable = true
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("ListBG")
self.fgColor = self.parent:getTheme("ListText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end,
getType = function(self)
return objectType
end;
addItem = function(self, text, bgCol, fgCol, ...)
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
if (#list == 1) then
self:setValue(list[1])
if (#list <= 1) then
self:setValue(list[1], false)
end
self:updateDraw()
return self
end;
setOffset = function(self, yOff)
yOffset = yOff
self:updateDraw()
return self
end;
@@ -47,6 +43,7 @@ return function(name)
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
@@ -69,7 +66,8 @@ return function(name)
clear = function(self)
list = {}
self:setValue({})
self:setValue({}, false)
self:updateDraw()
return self
end;
@@ -80,23 +78,28 @@ return function(name)
editItem = function(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {})
self:setValue(list[index] or {}, false)
self:updateDraw()
return self
end;
setSelectedItem = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self.bgColor
itemSelectedFG = fgCol or self.fgColor
selectionColorActive = active
selectionColorActive = active~=nil and active or true
self:updateDraw()
return self
end;
setScrollable = function(self, scroll)
scrollable = scroll
if(scroll==nil)then scrollable = true end
self:updateDraw()
return self
end;
@@ -116,29 +119,15 @@ return function(name)
return self
end,
mouseHandler = function(self, event, button, x, y)
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local w,h = self:getSize()
if (obx <= x) and (obx + w > x) and (oby <= y) and (oby + h > y) and (self:isVisible()) then
if (((event == "mouse_click") or (event == "mouse_drag"))and(button==1))or(event=="monitor_touch") then
if (#list > 0) then
for n = 1, h do
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + w > x) and (oby + n - 1 == y) then
self:setValue(list[n + yOffset])
self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", 0, x, y, list[n + yOffset])
end
end
end
end
end
if (event == "mouse_scroll") and (scrollable) then
yOffset = yOffset + button
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
if(scrollable)then
local w,h = self:getSize()
yOffset = yOffset + dir
if (yOffset < 0) then
yOffset = 0
end
if (button >= 1) then
if (dir >= 1) then
if (#list > h) then
if (yOffset > #list - h) then
yOffset = #list - h
@@ -150,11 +139,39 @@ return function(name)
yOffset = yOffset - 1
end
end
self:updateDraw()
end
self:setVisualChanged()
return true
end
end;
return false
end,
mouseHandler = function(self, button, x, y)
if(base.mouseHandler(self, button, x, y))then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local w,h = self:getSize()
if (#list > 0) then
for n = 1, h do
if (list[n + yOffset] ~= nil) then
if (obx <= x) and (obx + w > x) and (oby + n - 1 == y) then
self:setValue(list[n + yOffset])
self:updateDraw()
end
end
end
end
return true
end
return false
end,
dragHandler = function(self, button, x, y)
return self:mouseHandler(button, x, y)
end,
touchHandler = function(self, x, y)
return self:mouseHandler(1, x, y)
end,
draw = function(self)
if (base.draw(self)) then
@@ -178,9 +195,20 @@ return function(name)
end
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ListBG")
self.fgColor = self.parent:getTheme("ListText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end
end,
}
return setmetatable(object, base)

View File

@@ -40,13 +40,6 @@ return function(name)
end
object = {
init = function(self)
self.bgColor = self.parent:getTheme("MenubarBG")
self.fgColor = self.parent:getTheme("MenubarText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end,
getType = function(self)
return objectType
end;
@@ -56,6 +49,7 @@ return function(name)
if (#list == 1) then
self:setValue(list[1])
end
self:updateDraw()
return self
end;
@@ -74,12 +68,14 @@ return function(name)
clear = function(self)
list = {}
self:setValue({})
self:setValue({}, false)
self:updateDraw()
return self
end;
setSpace = function(self, _space)
space = _space or space
self:updateDraw()
return self
end;
@@ -93,6 +89,7 @@ return function(name)
if (itemOffset > mScroll) then
itemOffset = mScroll
end
self:updateDraw()
return self
end;
@@ -125,6 +122,7 @@ return function(name)
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
@@ -139,11 +137,13 @@ return function(name)
editItem = function(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {})
self:setValue(list[index] or {}, false)
self:updateDraw()
return self
end;
@@ -151,48 +151,49 @@ return function(name)
itemSelectedBG = bgCol or self.bgColor
itemSelectedFG = fgCol or self.fgColor
selectionColorActive = active
self:updateDraw()
return self
end;
mouseHandler = function(self, event, button, x, y)
if(base.mouseHandler(self, event, button, x, y))then
mouseHandler = function(self, button, x, y)
if(base.mouseHandler(self, button, x, y))then
local objX, objY = self:getAbsolutePosition(self:getAnchorPosition())
local w,h = self:getSize()
if (objX <= x) and (objX + w > x) and (objY <= y) and (objY + h > y) and (self:isVisible()) then
if (self.parent ~= nil) then
self.parent:setFocusedObject(self)
end
if (event == "mouse_click") or (event == "monitor_touch") then
local xPos = 0
for n = 1, #list do
if (list[n] ~= nil) then
if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then
self:setValue(list[n])
self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n])
end
xPos = xPos + list[n].text:len() + space * 2
local xPos = 0
for n = 1, #list do
if (list[n] ~= nil) then
if (objX + xPos <= x + itemOffset) and (objX + xPos + list[n].text:len() + (space*2) > x + itemOffset) and (objY == y) then
self:setValue(list[n])
self:getEventSystem():sendEvent(event, self, event, 0, x, y, list[n])
end
end
end
if (event == "mouse_scroll") and (scrollable) then
itemOffset = itemOffset + button
if (itemOffset < 0) then
itemOffset = 0
end
local mScroll = maxScroll()
if (itemOffset > mScroll) then
itemOffset = mScroll
xPos = xPos + list[n].text:len() + space * 2
end
end
self:setVisualChanged(true)
return true
end
self:updateDraw()
return true
end
return false
end;
end,
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
if(scrollable)then
itemOffset = itemOffset + dir
if (itemOffset < 0) then
itemOffset = 0
end
local mScroll = maxScroll()
if (itemOffset > mScroll) then
itemOffset = mScroll
end
self:updateDraw()
end
return true
end
return false
end,
draw = function(self)
if (base.draw(self)) then
@@ -221,9 +222,19 @@ return function(name)
self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, w+itemOffset))
self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, w+itemOffset))
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("MenubarBG")
self.fgColor = self.parent:getTheme("MenubarText")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
end
end,
}
return setmetatable(object, base)

View File

@@ -1,4 +1,5 @@
local Object = require("Object")
local log = require("basaltLogs")
return function(name)
-- Pane
@@ -6,26 +7,21 @@ return function(name)
local objectType = "Pane"
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("PaneBG")
self.fgColor = self.parent:getTheme("PaneBG")
end,
getType = function(self)
return objectType
end;
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor)
end
self:setVisualChanged(false)
end
end;
setBackground = function(self, col, sym, symC)
base.setBackground(self, col, sym, symC)
return self
end,
init = function(self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("PaneBG")
self.fgColor = self.parent:getTheme("PaneBG")
end
end,
}
return setmetatable(object, base)

View File

@@ -11,8 +11,9 @@ return function(name, parent)
base:setZIndex(5)
local object
local cachedPath
local enviroment = {}
local function createBasaltWindow(x, y, width, height)
local function createBasaltWindow(x, y, width, height, self)
local xCursor, yCursor = 1, 1
local bgColor, fgColor = colors.black, colors.white
local cursorBlink = false
@@ -51,6 +52,7 @@ return function(name, parent)
cacheFG[n] = sub(cacheFG[n] == nil and emptyFG or cacheFG[n] .. emptyFG:sub(1, width - cacheFG[n]:len()), 1, width)
cacheBG[n] = sub(cacheBG[n] == nil and emptyBG or cacheBG[n] .. emptyBG:sub(1, width - cacheBG[n]:len()), 1, width)
end
base.updateDraw(base)
end
recreateWindowArray()
@@ -118,6 +120,7 @@ return function(name, parent)
cacheFG[yCursor] = sNewTextColor
cacheBG[yCursor] = sNewBackgroundColor
end
object:updateDraw()
end
xCursor = nEnd + 1
if (visible) then
@@ -133,6 +136,7 @@ return function(name, parent)
cacheT[_y] = sub(gText:sub(1, _x - 1) .. text .. gText:sub(_x + (text:len()), width), 1, width)
end
end
object:updateDraw()
end
local function setBG(_x, _y, colorStr)
@@ -142,6 +146,7 @@ return function(name, parent)
cacheBG[_y] = sub(gBG:sub(1, _x - 1) .. colorStr .. gBG:sub(_x + (colorStr:len()), width), 1, width)
end
end
object:updateDraw()
end
local function setFG(_x, _y, colorStr)
@@ -151,6 +156,7 @@ return function(name, parent)
cacheFG[_y] = sub(gFG:sub(1, _x - 1) .. colorStr .. gFG:sub(_x + (colorStr:len()), width), 1, width)
end
end
object:updateDraw()
end
local setTextColor = function(color)
@@ -417,10 +423,57 @@ return function(name, parent)
local paused = false
local queuedEvent = {}
local function updateCursor(self)
local xCur, yCur = pWindow.getCursorPos()
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
local function resumeProcess(self, event, ...)
local ok, result = curProcess:resume(event, ...)
if (ok==false)and(result~=nil)and(result~="Terminated")then
local val = self:sendEvent("program_error", result)
if(val~=false)then
error("Basalt Program - "..result)
end
end
if(curProcess:getStatus()=="dead")then
self:sendEvent("program_done")
end
end
local function mouseEvent(self, event, p1, x, y)
if (curProcess == nil) then
return false
end
if not (curProcess:isDead()) then
if not (paused) then
local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true))
resumeProcess(self, event, p1, x-absX+1, y-absY+1)
updateCursor(self)
end
end
end
local function keyEvent(self, event, key, isHolding)
if (curProcess == nil) then
return false
end
if not (curProcess:isDead()) then
if not (paused) then
if (self.draw) then
resumeProcess(self, event, key, isHolding)
updateCursor(self)
end
end
end
end
object = {
init = function(self)
self.bgColor = self.parent:getTheme("ProgramBG")
end,
getType = function(self)
return objectType
end;
@@ -461,7 +514,7 @@ return function(name, parent)
setSize = function(self, width, height, rel)
base.setSize(self, width, height, rel)
pWindow.basalt_resize(self:getSize())
pWindow.basalt_resize(self:getWidth(), self:getHeight())
return self
end;
@@ -472,9 +525,14 @@ return function(name, parent)
return "inactive"
end;
setEnviroment = function(self, env)
enviroment = env or {}
return self
end,
execute = function(self, path, ...)
cachedPath = path or cachedPath
curProcess = process:new(cachedPath, pWindow, ...)
curProcess = process:new(cachedPath, pWindow, enviroment, ...)
pWindow.setBackgroundColor(colors.black)
pWindow.setTextColor(colors.white)
pWindow.clear()
@@ -482,15 +540,26 @@ return function(name, parent)
pWindow.setBackgroundColor(self.bgColor)
pWindow.setTextColor(self.fgColor)
pWindow.basalt_setVisible(true)
curProcess:resume()
resumeProcess(self)
paused = false
if(self.parent~=nil)then
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
self.parent:addEvent("key", self)
self.parent:addEvent("key_up", self)
self.parent:addEvent("char", self)
self.parent:addEvent("other_event", self)
end
return self
end;
stop = function(self)
if (curProcess ~= nil) then
if not (curProcess:isDead()) then
curProcess:resume("terminate")
resumeProcess(self, "terminate")
if (curProcess:isDead()) then
if (self.parent ~= nil) then
self.parent:setCursor(false)
@@ -498,6 +567,7 @@ return function(name, parent)
end
end
end
self.parent:removeEvents(self)
return self
end;
@@ -522,7 +592,7 @@ return function(name, parent)
if (curProcess ~= nil) then
if not (curProcess:isDead()) then
if (paused == false) or (ign) then
curProcess:resume(event, p1, p2, p3, p4)
resumeProcess(self, event, p1, p2, p3, p4)
else
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
end
@@ -544,43 +614,68 @@ return function(name, parent)
if (curProcess ~= nil) then
if not (curProcess:isDead()) then
for _, value in pairs(events) do
curProcess:resume(value.event, table.unpack(value.args))
resumeProcess(self, value.event, table.unpack(value.args))
end
end
end
return self
end;
mouseHandler = function(self, event, button, x, y)
if (base.mouseHandler(self, event, button, x, y)) then
if (curProcess == nil) then
return false
end
if not (curProcess:isDead()) then
if not (paused) then
local absX, absY = self:getAbsolutePosition(self:getAnchorPosition(nil, nil, true))
curProcess:resume(event, button, x-absX+1, y-absY+1)
end
end
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
mouseEvent(self, "mouse_click", button, x, y)
return true
end
end;
return false
end,
keyHandler = function(self, event, key)
base.keyHandler(self, event, key)
if (self:isFocused()) then
if (curProcess == nil) then
return false
end
if not (curProcess:isDead()) then
if not (paused) then
if (self.draw) then
curProcess:resume(event, key)
end
end
end
mouseUpHandler = function(self, button, x, y)
if (base.mouseUpHandler(self, button, x, y)) then
mouseEvent(self, "mouse_up", button, x, y)
return true
end
end;
return false
end,
scrollHandler = function(self, dir, x, y)
if (base.scrollHandler(self, dir, x, y)) then
mouseEvent(self, "mouse_scroll", dir, x, y)
return true
end
return false
end,
dragHandler = function(self, button, x, y)
if (base.dragHandler(self, button, x, y)) then
mouseEvent(self, "mouse_drag", button, x, y)
return true
end
return false
end,
keyHandler = function(self, key, isHolding)
if(base.keyHandler(self, key, isHolding))then
keyEvent(self, "key", key, isHolding)
return true
end
return false
end,
keyUpHandler = function(self, key)
if(base.keyUpHandler(self, key))then
keyEvent(self, "key_up", key)
return true
end
return false
end,
charHandler = function(self, char)
if(base.charHandler(self, char))then
keyEvent(self, "char", char)
return true
end
return false
end,
getFocusHandler = function(self)
base.getFocusHandler(self)
@@ -590,17 +685,15 @@ return function(name, parent)
if (self.parent ~= nil) then
local xCur, yCur = pWindow.getCursorPos()
local obx, oby = self:getAnchorPosition()
if (self.parent ~= nil) then
local w,h = self:getSize()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
local w,h = self:getSize()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
end
end
end
end;
end,
loseFocusHandler = function(self)
base.loseFocusHandler(self)
@@ -611,16 +704,36 @@ return function(name, parent)
end
end
end
end;
end,
customEventHandler = function(self, event, ...)
base.customEventHandler(self, event, ...)
if (curProcess == nil) then
return
end
if(event=="basalt_resize")then
local w, h = pWindow.getSize()
local pW, pH = self:getSize()
if(w~=pW)or(h~=pH)then
pWindow.basalt_resize(pW, pH)
if not (curProcess:isDead()) then
resumeProcess(self, "term_resize")
end
end
pWindow.basalt_reposition(self:getAnchorPosition())
end
end,
eventHandler = function(self, event, p1, p2, p3, p4)
base.eventHandler(self, event, p1, p2, p3, p4)
if (curProcess == nil) then
return
end
if not (curProcess:isDead()) then
if not (paused) then
if (event ~= "mouse_click") and (event ~= "monitor_touch") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then
curProcess:resume(event, p1, p2, p3, p4)
if(event ~= "terminate") then
resumeProcess(self, event, p1, p2, p3, p4)
end
if (self:isFocused()) then
local obx, oby = self:getAnchorPosition()
@@ -632,34 +745,64 @@ return function(name, parent)
end
end
if (event == "terminate") and (self:isFocused()) then
self:stop()
if (event == "terminate") then
resumeProcess(self, event)
self.parent:setCursor(false)
return true
end
end
else
if (event ~= "mouse_click") and (event ~= "monitor_touch") and (event ~= "mouse_up") and (event ~= "mouse_scroll") and (event ~= "mouse_drag") and (event ~= "key_up") and (event ~= "key") and (event ~= "char") and (event ~= "terminate") then
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
end
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
end
end
end;
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local xCur, yCur = pWindow.getCursorPos()
local w,h = self:getSize()
pWindow.basalt_reposition(obx, oby)
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
end
pWindow.basalt_update()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
self:setVisualChanged(false)
end
end;
end,
onError = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("program_error", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("other_event", self)
end
return self
end,
onDone = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("program_done", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("other_event", self)
end
return self
end,
init = function(self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ProgramBG")
end
end,
}
return setmetatable(object, base)
end
end

View File

@@ -21,9 +21,11 @@ return function(name)
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("ProgressbarBG")
self.fgColor = self.parent:getTheme("ProgressbarText")
activeBarColor = self.parent:getTheme("ProgressbarActiveBG")
if(base.init(self))then
self.bgColor = self.parent:getTheme("ProgressbarBG")
self.fgColor = self.parent:getTheme("ProgressbarText")
activeBarColor = self.parent:getTheme("ProgressbarActiveBG")
end
end,
getType = function(self)
return objectType
@@ -42,6 +44,7 @@ return function(name)
setDirection = function(self, dir)
direction = dir
self:updateDraw()
return self
end;
@@ -49,11 +52,13 @@ return function(name)
activeBarColor = color or activeBarColor
activeBarSymbol = symbol or activeBarSymbol
activeBarSymbolCol = symbolcolor or activeBarSymbolCol
self:updateDraw()
return self
end;
setBackgroundSymbol = function(self, symbol)
bgBarSymbol = symbol:sub(1, 1)
self:updateDraw()
return self
end;
@@ -65,6 +70,7 @@ return function(name)
self:progressDoneHandler()
end
end
self:updateDraw()
return self
end;
@@ -107,9 +113,8 @@ return function(name)
self.parent:drawTextBox(obx, oby, w / 100 * progress, h, activeBarSymbol)
end
end
self:setVisualChanged(false)
end
end;
end,
}

View File

@@ -20,16 +20,6 @@ return function(name)
local align = "left"
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("MenubarBG")
self.fgColor = self.parent:getTheme("MenubarFG")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
boxSelectedBG = self.parent:getTheme("MenubarBG")
boxSelectedFG = self.parent:getTheme("MenubarText")
end,
getType = function(self)
return objectType
end;
@@ -58,6 +48,7 @@ return function(name)
if (#list == 1) then
self:setValue(list[1])
end
self:updateDraw()
return self
end;
@@ -67,6 +58,7 @@ return function(name)
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
@@ -85,7 +77,8 @@ return function(name)
clear = function(self)
list = {}
self:setValue({})
self:setValue({}, false)
self:updateDraw()
return self
end;
@@ -96,16 +89,19 @@ return function(name)
editItem = function(self, index, text, x, y, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {})
self:setValue(list[index] or {}, false)
self:updateDraw()
return self
end;
setActiveSymbol = function(self, sym)
symbol = sym:sub(1,1)
self:updateDraw()
return self
end,
@@ -115,23 +111,23 @@ return function(name)
boxSelectedBG = boxBG or boxSelectedBG
boxSelectedFG = boxFG or boxSelectedFG
selectionColorActive = active~=nil and active or true
self:updateDraw()
return self
end;
mouseHandler = function(self, event, button, x, y)
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
if ((event == "mouse_click")and(button==1))or(event=="monitor_touch") then
if (#list > 0) then
for _, value in pairs(list) do
if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 2 >= x) and (oby + value.y - 1 == y) then
self:setValue(value)
if (self.parent ~= nil) then
self.parent:setFocusedObject(self)
end
self:getEventSystem():sendEvent(event, self, event, button, x, y)
self:setVisualChanged()
return true
mouseHandler = function(self, button, x, y)
if (#list > 0) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
for _, value in pairs(list) do
if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 1 >= x) and (oby + value.y - 1 == y) then
self:setValue(value)
local val = self:getEventSystem():sendEvent("mouse_click", self, "mouse_click", button, x, y)
if(val==false)then return val end
if(self.parent~=nil)then
self.parent:setFocusedObject(self)
end
self:updateDraw()
return true
end
end
end
@@ -139,24 +135,34 @@ return function(name)
end;
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
for _, value in pairs(list) do
if (value == self:getValue()) then
if (align == "left") then
self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG)
self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG)
end
else
self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, boxNotSelectedBG or self.bgColor)
self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol)
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
for _, value in pairs(list) do
if (value == self:getValue()) then
if (align == "left") then
self.parent:writeText(value.x + obx - 1, value.y + oby - 1, symbol, boxSelectedBG, boxSelectedFG)
self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, itemSelectedBG, itemSelectedFG)
end
else
self.parent:drawBackgroundBox(value.x + obx - 1, value.y + oby - 1, 1, 1, boxNotSelectedBG or self.bgColor)
self.parent:writeText(value.x + 2 + obx - 1, value.y + oby - 1, value.text, value.bgCol, value.fgCol)
end
end
self:setVisualChanged(false)
return true
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("MenubarBG")
self.fgColor = self.parent:getTheme("MenubarFG")
itemSelectedBG = self.parent:getTheme("SelectionBG")
itemSelectedFG = self.parent:getTheme("SelectionText")
boxSelectedBG = self.parent:getTheme("MenubarBG")
boxSelectedFG = self.parent:getTheme("MenubarText")
end
end,
}
return setmetatable(object, base)

View File

@@ -18,19 +18,37 @@ return function(name)
local index = 1
local symbolSize = 1
local function mouseEvent(self, button, x, y)
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local w,h = self:getSize()
if (barType == "horizontal") then
for _index = 0, w do
if (obx + _index == x) and (oby <= y) and (oby + h > y) then
index = math.min(_index + 1, w - (symbolSize - 1))
self:setValue(maxValue / w * (index))
self:updateDraw()
end
end
end
if (barType == "vertical") then
for _index = 0, h do
if (oby + _index == y) and (obx <= x) and (obx + w > x) then
index = math.min(_index + 1, h - (symbolSize - 1))
self:setValue(maxValue / h * (index))
self:updateDraw()
end
end
end
end
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("ScrollbarBG")
self.fgColor = self.parent:getTheme("ScrollbarText")
symbolColor = self.parent:getTheme("ScrollbarSymbolColor")
end,
getType = function(self)
return objectType
end;
setSymbol = function(self, _symbol)
symbol = _symbol:sub(1, 1)
self:setVisualChanged()
self:updateDraw()
return self
end;
@@ -53,6 +71,7 @@ return function(name)
local w,h = self:getSize()
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
self:updateDraw()
return self
end,
@@ -68,67 +87,62 @@ return function(name)
elseif (barType == "horizontal") then
self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1))))
end
self:setVisualChanged()
self:updateDraw()
return self
end;
setMaxValue = function(self, val)
maxValue = val
self:updateDraw()
return self
end;
setBackgroundSymbol = function(self, _bgSymbol)
bgSymbol = string.sub(_bgSymbol, 1, 1)
self:setVisualChanged()
self:updateDraw()
return self
end;
setSymbolColor = function(self, col)
symbolColor = col
self:setVisualChanged()
self:updateDraw()
return self
end;
setBarType = function(self, _typ)
barType = _typ:lower()
self:updateDraw()
return self
end;
mouseHandler = function(self, event, button, x, y)
if (base.mouseHandler(self, event, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local w,h = self:getSize()
if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then
if (barType == "horizontal") then
for _index = 0, w do
if (obx + _index == x) and (oby <= y) and (oby + h > y) then
index = math.min(_index + 1, w - (symbolSize - 1))
self:setValue(maxValue / w * (index))
self:setVisualChanged()
end
end
end
if (barType == "vertical") then
for _index = 0, h do
if (oby + _index == y) and (obx <= x) and (obx + w > x) then
index = math.min(_index + 1, h - (symbolSize - 1))
self:setValue(maxValue / h * (index))
self:setVisualChanged()
end
end
end
end
if (event == "mouse_scroll") then
index = index + button
if (index < 1) then
index = 1
end
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
end
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
mouseEvent(self, button, x, y)
return true
end
end;
return false
end,
dragHandler = function(self, button, x, y)
if (base.dragHandler(self, button, x, y)) then
mouseEvent(self, button, x, y)
return true
end
return false
end,
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
local w,h = self:getSize()
index = index + dir
if (index < 1) then
index = 1
end
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
self:updateDraw()
end
end,
draw = function(self)
if (base.draw(self)) then
@@ -155,9 +169,19 @@ return function(name)
end
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("ScrollbarBG")
self.fgColor = self.parent:getTheme("ScrollbarText")
symbolColor = self.parent:getTheme("ScrollbarSymbolColor")
end
end,
}
return setmetatable(object, base)

View File

@@ -1,4 +1,5 @@
local Object = require("Object")
local log = require("basaltLogs")
local xmlValue = require("utils").getValueFromXML
return function(name)
@@ -17,19 +18,37 @@ return function(name)
local index = 1
local symbolSize = 1
local function mouseEvent(self, button, x, y)
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local w,h = self:getSize()
if (barType == "horizontal") then
for _index = 0, w do
if (obx + _index == x) and (oby <= y) and (oby + h > y) then
index = math.min(_index + 1, w - (symbolSize - 1))
self:setValue(maxValue / w * (index))
self:updateDraw()
end
end
end
if (barType == "vertical") then
for _index = 0, h do
if (oby + _index == y) and (obx <= x) and (obx + w > x) then
index = math.min(_index + 1, h - (symbolSize - 1))
self:setValue(maxValue / h * (index))
self:updateDraw()
end
end
end
end
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("SliderBG")
self.fgColor = self.parent:getTheme("SliderText")
symbolColor = self.parent:getTheme("SliderSymbolColor")
end,
getType = function(self)
return objectType
end;
setSymbol = function(self, _symbol)
symbol = _symbol:sub(1, 1)
self:setVisualChanged()
self:updateDraw()
return self
end;
@@ -52,6 +71,7 @@ return function(name)
local w,h = self:getSize()
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
self:updateDraw()
return self
end,
@@ -66,7 +86,7 @@ return function(name)
elseif (barType == "horizontal") then
self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1))))
end
self:setVisualChanged()
self:updateDraw()
return self
end;
@@ -77,56 +97,52 @@ return function(name)
setBackgroundSymbol = function(self, _bgSymbol)
bgSymbol = string.sub(_bgSymbol, 1, 1)
self:setVisualChanged()
self:updateDraw()
return self
end;
setSymbolColor = function(self, col)
symbolColor = col
self:setVisualChanged()
self:updateDraw()
return self
end;
setBarType = function(self, _typ)
barType = _typ:lower()
self:updateDraw()
return self
end;
mouseHandler = function(self, event, button, x, y)
if (base.mouseHandler(self, event, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local w,h = self:getSize()
if (((event == "mouse_click") or (event == "mouse_drag")) and (button == 1))or(event=="monitor_touch") then
if (barType == "horizontal") then
for _index = 0, w do
if (obx + _index == x) and (oby <= y) and (oby + h > y) then
index = math.min(_index + 1, w - (symbolSize - 1))
self:setValue(maxValue / w * (index))
self:setVisualChanged()
end
end
end
if (barType == "vertical") then
for _index = 0, h do
if (oby + _index == y) and (obx <= x) and (obx + w > x) then
index = math.min(_index + 1, h - (symbolSize - 1))
self:setValue(maxValue / h * (index))
self:setVisualChanged()
end
end
end
end
if (event == "mouse_scroll") then
index = index + button
if (index < 1) then
index = 1
end
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
end
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
mouseEvent(self, button, x, y)
return true
end
end;
return false
end,
dragHandler = function(self, button, x, y)
if (base.dragHandler(self, button, x, y)) then
mouseEvent(self, button, x, y)
return true
end
return false
end,
scrollHandler = function(self, dir, x, y)
if(base.scrollHandler(self, dir, x, y))then
local w,h = self:getSize()
index = index + dir
if (index < 1) then
index = 1
end
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
self:updateDraw()
return true
end
return false
end,
draw = function(self)
if (base.draw(self)) then
@@ -141,7 +157,6 @@ return function(name)
if (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor)
@@ -154,9 +169,19 @@ return function(name)
end
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("SliderBG")
self.fgColor = self.parent:getTheme("SliderText")
symbolColor = self.parent:getTheme("SliderSymbolColor")
end
end,
}
return setmetatable(object, base)

View File

@@ -17,32 +17,25 @@ return function(name)
local activeBG = colors.green
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("SwitchBG")
self.fgColor = self.parent:getTheme("SwitchText")
bgSymbol = self.parent:getTheme("SwitchBGSymbol")
inactiveBG = self.parent:getTheme("SwitchInactive")
activeBG = self.parent:getTheme("SwitchActive")
end,
getType = function(self)
return objectType
end;
setSymbolColor = function(self, symbolColor)
bgSymbol = symbolColor
self:setVisualChanged()
self:updateDraw()
return self
end;
setActiveBackground = function(self, bgcol)
activeBG = bgcol
self:setVisualChanged()
self:updateDraw()
return self
end;
setInactiveBackground = function(self, bgcol)
inactiveBG = bgcol
self:setVisualChanged()
self:updateDraw()
return self
end;
@@ -54,12 +47,11 @@ return function(name)
end,
mouseHandler = function(self, event, button, x, y)
if (base.mouseHandler(self, event, button, x, y)) then
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
if ((event == "mouse_click") and (button == 1))or(event=="monitor_touch") then
self:setValue(not self:getValue())
end
self:setValue(not self:getValue())
self:updateDraw()
return true
end
end;
@@ -78,9 +70,19 @@ return function(name)
self.parent:drawBackgroundBox(obx+1, oby, 1, h, inactiveBG)
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("SwitchBG")
self.fgColor = self.parent:getTheme("SwitchText")
bgSymbol = self.parent:getTheme("SwitchBGSymbol")
inactiveBG = self.parent:getTheme("SwitchInactive")
activeBG = self.parent:getTheme("SwitchActive")
end
end,
}
return setmetatable(object, base)

View File

@@ -1,32 +1,101 @@
local Object = require("Object")
local tHex = require("tHex")
local xmlValue = require("utils").getValueFromXML
local log = require("basaltLogs")
local rep,find,gmatch,sub,len = string.rep,string.find,string.gmatch,string.sub,string.len
return function(name)
local base = Object(name)
local objectType = "Textfield"
local hIndex, wIndex, textX, textY = 1, 1, 1, 1
local lines = { "" }
local lines = { " " }
local bgLines = { "" }
local fgLines = { "" }
local keyWords = { }
local rules = { }
local startSelX,endSelX,startSelY,endSelY
local selectionBG,selectionFG = colors.lightBlue,colors.black
base.width = 30
base.height = 12
base:setZIndex(5)
local function isSelected()
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
return true
end
return false
end
local function getSelectionCoordinates()
local sx,ex,sy,ey
if(isSelected())then
if(startSelX>endSelX)then
sx,ex = endSelX,startSelX
else
sx,ex = startSelX,endSelX
end
if(startSelY>endSelY)then
sy,ey = endSelY,startSelY
else
sy,ey = startSelY,endSelY
end
end
return sx,ex,sy,ey
end
local function getSelection()
end
local function removeSelection(self)
local sx,ex,sy,ey = getSelectionCoordinates(self)
for n=ey,sy,-1 do
if(n==sy)or(n==ey)then
local l = lines[n]
local b = bgLines[n]
local f = fgLines[n]
if(n==sy)and(n==ey)then
l = l:sub(1,sx-1)..l:sub(ex+1,l:len())
b = b:sub(1,sx-1)..b:sub(ex+1,b:len())
f = f:sub(1,sx-1)..f:sub(ex+1,f:len())
elseif(n==sx)then
l = l:sub(1, sx)
b = b:sub(1, sx)
f = f:sub(1, sx)
elseif(n==sy)then
l = l:sub(ex, l:len())
b = b:sub(ex, b:len())
f = f:sub(ex, f:len())
end
lines[n] = l
bgLines[n] = b
fgLines[n] = f
else
table.remove(lines, n)
table.remove(bgLines, n)
table.remove(fgLines, n)
end
end
textX,textY = startSelX,startSelY
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
return self
end
local function stringGetPositions(str, word)
local pos = {}
if(str:len()>0)then
for w in string.gmatch(str, word)do
local s, e = string.find(str, w)
for w in gmatch(str, word)do
local s, e = find(str, w)
if(s~=nil)and(e~=nil)then
table.insert(pos,s)
table.insert(pos,e)
local startL = string.sub(str, 1, (s-1))
local endL = string.sub(str, e+1, str:len())
local startL = sub(str, 1, (s-1))
local endL = sub(str, e+1, str:len())
str = startL..(":"):rep(w:len())..endL
end
end
@@ -65,6 +134,7 @@ return function(name)
end
fgLines[l] = fgLine
bgLines[l] = bgLine
self:updateDraw()
end
local function updateAllColors(self)
@@ -74,10 +144,6 @@ return function(name)
end
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("TextfieldBG")
self.fgColor = self.parent:getTheme("TextfieldText")
end,
getType = function(self)
return objectType
end;
@@ -144,14 +210,18 @@ return function(name)
editLine = function(self, index, text)
lines[index] = text or lines[index]
updateColors(self, index)
self:updateDraw()
return self
end;
clear = function(self)
lines = {""}
lines = {" "}
bgLines = {""}
fgLines = {""}
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
hIndex, wIndex, textX, textY = 1, 1, 1, 1
self:updateDraw()
return self
end,
@@ -161,18 +231,21 @@ return function(name)
lines[1] = text
bgLines[1] = tHex[self.bgColor]:rep(text:len())
fgLines[1] = tHex[self.fgColor]:rep(text:len())
updateColors(self, 1)
return self
end
if (index ~= nil) then
table.insert(lines, index, text)
table.insert(bgLines, index, tHex[self.bgColor]:rep(text:len()))
table.insert(fgLines, tHex[self.fgColor]:rep(text:len()))
table.insert(fgLines, index, tHex[self.fgColor]:rep(text:len()))
else
table.insert(lines, text)
table.insert(bgLines, tHex[self.bgColor]:rep(text:len()))
table.insert(fgLines, tHex[self.fgColor]:rep(text:len()))
end
end
updateColors(self, index or #lines)
self:updateDraw()
return self
end;
@@ -183,11 +256,13 @@ return function(name)
for k,v in pairs(tab)do
table.insert(keyWords[color], v)
end
self:updateDraw()
return self
end;
addRule = function(self, rule, fg, bg)
table.insert(rules, {rule, fg, bg})
self:updateDraw()
return self
end;
@@ -198,6 +273,7 @@ return function(name)
rules[k][3] = bg
end
end
self:updateDraw()
return self
end;
@@ -207,19 +283,27 @@ return function(name)
table.remove(rules, k)
end
end
self:updateDraw()
return self
end;
setKeywords = function(self, color, tab)
keyWords[color] = tab
self:updateDraw()
return self
end;
removeLine = function(self, index)
table.remove(lines, index or #lines)
if (#lines <= 0) then
table.insert(lines, "")
if(#lines>1)then
table.remove(lines, index or #lines)
table.remove(bgLines, index or #bgLines)
table.remove(fgLines, index or #fgLines)
else
lines = {" "}
bgLines = {""}
fgLines = {""}
end
self:updateDraw()
return self
end;
@@ -244,11 +328,10 @@ return function(name)
end
end;
keyHandler = function(self, event, key)
keyHandler = function(self, key)
if (base.keyHandler(self, event, key)) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (event == "key") then
if (key == keys.backspace) then
-- on backspace
if (lines[textY] == "") then
@@ -300,17 +383,21 @@ return function(name)
if (key == keys.delete) then
-- on delete
if (textX > lines[textY]:len()) then
if (lines[textY + 1] ~= nil) then
lines[textY] = lines[textY] .. lines[textY + 1]
table.remove(lines, textY + 1)
table.remove(bgLines, textY + 1)
table.remove(fgLines, textY + 1)
end
if(isSelected())then
removeSelection(self)
else
lines[textY] = lines[textY]:sub(1, textX - 1) .. lines[textY]:sub(textX + 1, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. fgLines[textY]:sub(textX + 1, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. bgLines[textY]:sub(textX + 1, bgLines[textY]:len())
if (textX > lines[textY]:len()) then
if (lines[textY + 1] ~= nil) then
lines[textY] = lines[textY] .. lines[textY + 1]
table.remove(lines, textY + 1)
table.remove(bgLines, textY + 1)
table.remove(fgLines, textY + 1)
end
else
lines[textY] = lines[textY]:sub(1, textX - 1) .. lines[textY]:sub(textX + 1, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. fgLines[textY]:sub(textX + 1, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. bgLines[textY]:sub(textX + 1, bgLines[textY]:len())
end
end
updateColors(self)
end
@@ -361,7 +448,14 @@ return function(name)
if (textX > lines[textY]:len() + 1) then
textX = lines[textY]:len() + 1
end
if (wIndex > 1) then
if (textX < wIndex) then
wIndex = textX - w + 1
if (wIndex < 1) then
wIndex = 1
end
end
end
if (textY >= hIndex + h) then
hIndex = hIndex + 1
end
@@ -411,109 +505,192 @@ return function(name)
wIndex = 1
end
end
end
if (event == "char") then
lines[textY] = lines[textY]:sub(1, textX - 1) .. key .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self.fgColor] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
textX = textX + 1
if (textX >= w + wIndex) then
wIndex = wIndex + 1
end
updateColors(self)
self:setValue("")
if not((obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h)) then
wIndex = math.max(1, lines[textY]:len()-w+1)
hIndex = math.max(1, textY - h + 1)
end
local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1)
if (cursorX > self.x + w - 1) then
cursorX = self.x + w - 1
if (cursorX > self:getX() + w - 1) then
cursorX = self:getX() + w - 1
end
local cursorY = (textY - hIndex < h and textY - hIndex or textY - hIndex - 1)
if (cursorX < 1) then
cursorX = 0
end
self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor)
self:updateDraw()
return true
end
end;
end,
mouseHandler = function(self, event, button, x, y)
if (base.mouseHandler(self, event, button, x, y)) then
charHandler = function(self, char)
if(base.charHandler(self, char))then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
lines[textY] = lines[textY]:sub(1, textX - 1) .. char .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self.fgColor] .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor] .. bgLines[textY]:sub(textX, bgLines[textY]:len())
textX = textX + 1
if (textX >= w + wIndex) then
wIndex = wIndex + 1
end
updateColors(self)
self:setValue("")
if not((obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h)) then
wIndex = math.max(1, lines[textY]:len()-w+1)
hIndex = math.max(1, textY - h + 1)
end
local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1)
if (cursorX > self:getX() + w - 1) then
cursorX = self:getX() + w - 1
end
local cursorY = (textY - hIndex < h and textY - hIndex or textY - hIndex - 1)
if (cursorX < 1) then
cursorX = 0
end
if(isSelected())then
removeSelection(self)
end
self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor)
self:updateDraw()
return true
end
end,
dragHandler = function(self, button, x, y)
if (base.dragHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local anchx, anchy = self:getAnchorPosition()
local w,h = self:getSize()
if (event == "mouse_click")or(event=="monitor_touch") then
if (lines[y - oby + hIndex] ~= nil) then
if (lines[y - oby + hIndex] ~= nil) then
if(anchx+w > anchx + x - (obx+1)+ wIndex)and(anchx < anchx + x - obx+ wIndex)then
textX = x - obx + wIndex
textY = y - oby + hIndex
endSelX = textX
endSelY = textY
if (textX > lines[textY]:len()) then
textX = lines[textY]:len() + 1
endSelX = textX
end
if (textX < wIndex) then
wIndex = textX - 1
if (wIndex < 1) then
wIndex = 1
end
end
if (self.parent ~= nil) then
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
end
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
self:updateDraw()
end
end
if (event == "mouse_drag") then
if (lines[y - oby + hIndex] ~= nil) then
textX = x - obx + wIndex
textY = y - oby + hIndex
if (textX > lines[textY]:len()) then
textX = lines[textY]:len() + 1
end
if (textX < wIndex) then
wIndex = textX - 1
if (wIndex < 1) then
wIndex = 1
end
end
if (self.parent ~= nil) then
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
end
end
end
if (event == "mouse_scroll") then
hIndex = hIndex + button
if (hIndex > #lines - (h - 1)) then
hIndex = #lines - (h - 1)
end
if (hIndex < 1) then
hIndex = 1
end
if (self.parent ~= nil) then
if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h) then
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
else
self.parent:setCursor(false)
end
end
end
self:setVisualChanged()
return true
end
end;
end,
scrollHandler = function(self, dir, x, y)
if (base.scrollHandler(self, dir, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local anchx, anchy = self:getAnchorPosition()
local w,h = self:getSize()
hIndex = hIndex + dir
if (hIndex > #lines - (h - 1)) then
hIndex = #lines - (h - 1)
end
if (hIndex < 1) then
hIndex = 1
end
if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (anchy + textY - hIndex >= anchy and anchy + textY - hIndex < anchy + h) then
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
else
self.parent:setCursor(false)
end
self:updateDraw()
return true
end
end,
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local anchx, anchy = self:getAnchorPosition()
if (lines[y - oby + hIndex] ~= nil) then
textX = x - obx + wIndex
textY = y - oby + hIndex
endSelX = nil
endSelY = nil
startSelX = textX
startSelY = textY
if (textX > lines[textY]:len()) then
textX = lines[textY]:len() + 1
startSelX = textX
end
if (textX < wIndex) then
wIndex = textX - 1
if (wIndex < 1) then
wIndex = 1
end
end
self:updateDraw()
end
if (self.parent ~= nil) then
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
end
return true
end
end,
mouseUpHandler = function(self, button, x, y)
if (base.mouseUpHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
local anchx, anchy = self:getAnchorPosition()
if (lines[y - oby + hIndex] ~= nil) then
endSelX = x - obx + wIndex
endSelY = y - oby + hIndex
if (endSelX > lines[endSelY]:len()) then
endSelX = lines[endSelY]:len() + 1
end
if(startSelX==endSelX)and(startSelY==endSelY)then
startSelX, endSelX, startSelY, endSelY = nil, nil, nil, nil
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 w, h = self:getSize()
lines[textY] = lines[textY]:sub(1, textX - 1) .. paste .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. tHex[self.fgColor]:rep(paste:len()) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. tHex[self.bgColor]:rep(paste:len()) .. bgLines[textY]:sub(textX, bgLines[textY]:len())
textX = textX + paste:len()
if (textX >= w + wIndex) then
wIndex = (textX+1)-w
end
local anchx, anchy = self:getAnchorPosition()
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
updateColors(self)
self:updateDraw()
end
end
end
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
end
if(self.fgColor~=false)then
self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor)
end
for n = 1, h do
local text = ""
local bg = ""
@@ -530,17 +707,52 @@ return function(name)
if (space < 0) then
space = 0
end
text = text .. string.rep(" ", space)
bg = bg .. string.rep(tHex[self.bgColor], space)
fg = fg .. string.rep(tHex[self.fgColor], space)
text = text .. rep(self.bgSymbol, space)
bg = bg .. rep(tHex[self.bgColor], space)
fg = fg .. rep(tHex[self.fgColor], space)
self.parent:setText(obx, oby + n - 1, text)
self.parent:setBG(obx, oby + n - 1, bg)
self.parent:setFG(obx, oby + n - 1, fg)
end
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
local sx,ex,sy,ey = getSelectionCoordinates(self)
for n=sy,ey do
local line = lines[n]:len()
local xOffset = 0
if(n==sy)and(n==ey)then
xOffset = sx-1
line = line - (sx-1) - (line - ex)
elseif(n==ey)then
line = line - (line - ex)
elseif(n==sy)then
line = line-(sx-1)
xOffset = sx-1
end
self.parent:setBG(obx + xOffset, oby + n - 1, rep(tHex[selectionBG], line))
self.parent:setFG(obx + xOffset, oby + n - 1, rep(tHex[selectionFG], line))
end
end
if(self:isFocused())then
local anchx, anchy = self:getAnchorPosition()
--self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_scroll", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("key", self)
self.parent:addEvent("char", self)
self.parent:addEvent("other_event", self)
if(base.init(self))then
self.bgColor = self.parent:getTheme("TextfieldBG")
self.fgColor = self.parent:getTheme("TextfieldText")
end
end,
}
return setmetatable(object, base)

View File

@@ -7,6 +7,7 @@ return function(name)
local func
local cRoutine
local isActive = false
local filter
local generateXMLEventFunction = function(self, str)
if(str:sub(1,1)=="#")then
@@ -53,12 +54,22 @@ return function(name)
func = f
cRoutine = coroutine.create(func)
isActive = true
filter=nil
local ok, result = coroutine.resume(cRoutine)
filter = result
if not (ok) then
if (result ~= "Terminated") then
error("Thread Error Occurred - " .. result)
end
end
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_scroll", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("key", self)
self.parent:addEvent("key_up", self)
self.parent:addEvent("char", self)
self.parent:addEvent("other_event", self)
return self
end;
@@ -71,20 +82,58 @@ return function(name)
stop = function(self, f)
isActive = false
self.parent:removeEvent("mouse_click", self)
self.parent:removeEvent("mouse_up", self)
self.parent:removeEvent("mouse_scroll", self)
self.parent:removeEvent("mouse_drag", self)
self.parent:removeEvent("key", self)
self.parent:removeEvent("key_up", self)
self.parent:removeEvent("char", self)
self.parent:removeEvent("other_event", self)
return self
end;
eventHandler = function(self, event, p1, p2, p3)
mouseHandler = function(self, ...)
self:eventHandler("mouse_click", ...)
end,
mouseUpHandler = function(self, ...)
self:eventHandler("mouse_up", ...)
end,
mouseScrollHandler = function(self, ...)
self:eventHandler("mouse_scroll", ...)
end,
mouseDragHandler = function(self, ...)
self:eventHandler("mouse_drag", ...)
end,
mouseMoveHandler = function(self, ...)
self:eventHandler("mouse_move", ...)
end,
keyHandler = function(self, ...)
self:eventHandler("key", ...)
end,
keyUpHandler = function(self, ...)
self:eventHandler("key_up", ...)
end,
charHandler = function(self, ...)
self:eventHandler("char", ...)
end,
eventHandler = function(self, event, ...)
if (isActive) then
if (coroutine.status(cRoutine) ~= "dead") then
local ok, result = coroutine.resume(cRoutine, event, p1, p2, p3)
if (coroutine.status(cRoutine) == "suspended") then
if(filter~=nil)then
if(event~=filter)then return end
filter=nil
end
local ok, result = coroutine.resume(cRoutine, event, ...)
filter = result
if not (ok) then
if (result ~= "Terminated") then
error("Thread Error Occurred - " .. result)
end
end
else
isActive = false
self:stop()
end
end
end;

View File

@@ -74,6 +74,7 @@ return function(name)
repeats = savedRepeats
timerObj = os.startTimer(timer)
timerIsActive = true
self.parent:addEvent("other_event", self)
return self
end;
@@ -86,6 +87,7 @@ return function(name)
os.cancelTimer(timerObj)
end
timerIsActive = false
self.parent:removeEvent("other_event", self)
return self
end;

View File

@@ -31,7 +31,7 @@ return { -- The default main theme for basalt!
ScrollbarBG = colors.lightGray,
ScrollbarText = colors.gray,
ScrollbarSymbolColor = colors.black,
SliderBG = colors.lightGray,
SliderBG = false,
SliderText = colors.gray,
SliderSymbolColor = colors.black,
SwitchBG = colors.lightGray,
@@ -39,5 +39,9 @@ return { -- The default main theme for basalt!
SwitchBGSymbol = colors.black,
SwitchInactive = colors.red,
SwitchActive = colors.green,
LabelBG = false,
LabelText = colors.black,
GraphBG = colors.gray,
GraphText = colors.black
}

23
CHANGELOG.md Normal file
View File

@@ -0,0 +1,23 @@
# Changelog
#### v. 1.5:
- You can now mirror a frame to a monitor by using :setMirror(side)
- with dynamic values you are able to use percentage values and even functions which get called everytime we need the size of that object
- XML got added to make design and logic seperate (you don't have to) - you are now able to use xml to create your UI design.
- Animations are now more advanced and provide many features to do cool stuff. They are also very easy to use now!
- Also some smaller bugfixes
- new bugs to explore
- fixed monitor support
- added :setIndex() for scrollbars
- added dynamic value system (not fully done)
- reworked the filesystem, now we use require instead of loadfile
- from now on the single file will be complied on the end users computer
- prepared everything for an advanced installer
#### v. 1:
- created Basalt
- added many objects (buttons, checkbox, labels, programs, switch, radio, lists, dropdowns, input, textfields, images, menubar, animations, threads, timers, progressbar, scrollbar, slider, pane)
- added bigfont
- added blittle
- added coroutine management
- added advanced event system

View File

@@ -1,39 +1,15 @@
# Basalt - A UI Framework for CC:Tweaked
![GitHub Repo stars](https://img.shields.io/github/stars/Pyroxenium/Basalt?style=for-the-badge)
![GitHub commit activity](https://img.shields.io/github/commit-activity/y/Pyroxenium/Basalt?style=for-the-badge)
![GitHub Repo stars](https://img.shields.io/badge/Made%20for-CC%3AT-orange?style=for-the-badge)
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/Pyroxenium/Basalt?style=for-the-badge)
[![Discord](https://img.shields.io/discord/976905222251233320?label=Discord&style=for-the-badge)](https://discord.gg/yNNnmBVBpE)
Basalt is still under developement and you may find bugs!
Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (Also know as "ComputerCraft: Tweaked") - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's [wiki](https://tweaked.cc/) or [download](https://www.curseforge.com/minecraft/mc-mods/cc-tweaked).<br>
**Note:** Basalt is still under developement and you may find bugs!
## Information
Check out the [wiki](https://basalt.madefor.cc/) for information<br>
If you have questions, feel free to join the discord server: [https://discord.gg/yM7kndJdJJ](https://discord.gg/yM7kndJdJJ)
## Changelogs
From now on we will add changes:
#### Version 4:
- You can now mirror a frame to a monitor by using :setMirror(side)
- with dynamic values you are able to use percentage values and even functions which get called everytime we need the size of that object
- XML got added to make design and logic seperate (you don't have to) - you are now able to use xml to create your UI design.
- Animations are now more advanced and provide many features to do cool stuff. They are also very easy to use now!
- Also some smaller bugfixes
- new bugs to explore
#### Version 3:
- fixed monitor support
- added :setIndex() for scrollbars
- added dynamic value system (not fully done)
#### Version 2:
Note: You won't get any changes for now, so don't redownload the project! (:
- reworked the filesystem, now we use require instead of loadfile
- from now on the single file will be complied on the end users computer
- prepared everything for an advanced installer
#### Version 1:
- created Basalt
- added many objects (buttons, checkbox, labels, programs, switch, radio, lists, dropdowns, input, textfields, images, menubar, animations, threads, timers, progressbar, scrollbar, slider, pane)
- added bigfont
- added blittle
- added coroutine management
- added advanced event system
Check out the [wiki](https://basalt.madefor.cc/) for more information.<br>
If you have questions, feel free to join the discord server: [https://discord.gg/yNNnmBVBpE](https://discord.gg/yNNnmBVBpE).
## Demo
<img src="https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/basaltPreview2.gif" width="300">

View File

@@ -464,7 +464,8 @@ outputFile:write("project['default'] = {}")
local function writeNewPackage(subdir, name, path)
if not(fs.isDir(path))then
outputFile:write("project['"..subdir.."']['"..name.."'] = ".."function(...)")
local fileData = io.open(path, "r"):read("*all")
local file = io.open(path, "r")
local fileData = file:read("*all")
if(minifyProject)then
local success, data = minify(fileData)
if(success)then
@@ -475,6 +476,7 @@ local function writeNewPackage(subdir, name, path)
else
outputFile:write(fileData:gsub("]]", "] ]"):gsub("]]", "] ]").."\n")
end
file:close()
outputFile:write("end; \n")
end
end
@@ -489,16 +491,17 @@ for _,v in pairs(projectFiles)do
end
end
local main = io.open(fs.combine(projectPath, mainFile), "r"):read("*all")
local main = io.open(fs.combine(projectPath, mainFile), "r")
local mainData = main:read("*all")
if(minifyProject)then
local success,data = minify(main)
local success,data = minify(mainData)
if(success)then
outputFile:write(data)
else
print("Error: Can't minify "..fs.combine(projectPath, mainFile))
print("Error: Can't minify "..fs.combine(projectPath, mainFile).." "..data)
end
else
outputFile:write(main)
outputFile:write(mainData)
end
outputFile:close()
main:close()
outputFile:close()

View File

@@ -1,24 +1,19 @@
# Welcome to The Basalt Wiki!
# Welcome to The Basalt Wiki
*Note: The Basalt Wiki is a work in progress. Please treat Wiki errors the same as bugs and report them accordingly.*
*Note: The Basalt Wiki is a work in progress. Please treat wiki errors the same as bugs and report them accordingly.*
Here you can find information about how to use Basalt as well as examples of functional Basalt code. The aim of Basalt is to improve user interaction through visual display.
## About Basalt
Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (Also know as "ComputerCraft: Tweaked") - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's [wiki](https://tweaked.cc/) or [download](https://www.curseforge.com/minecraft/mc-mods/cc-tweaked).
Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (Also known as "ComputerCraft: Tweaked") - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's [wiki](https://tweaked.cc/) or [download](https://modrinth.com/mod/cc-tweaked).
## Quick Demo
<img src="https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/basaltPreview2.gif" width="600">
![Basalt Demo GIF](https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/basaltPreview2.gif)
## Questions & Bugs
Obviously NyoriE has implemented some easter eggs, *some people* call them "bugs". If you happen to discover one of these just make a new <a href="https://github.com/Pyroxenium/Basalt/issues">issue</a>.
Obviously NyoriE has implemented some easter eggs, *some people* call them "bugs". If you happen to discover one of these just make a new [Github Issue](https://github.com/Pyroxenium/Basalt/issues)
Additionally, if you have questions about Basalt or how to make use of it, feel free to create a new discussion on <a href="https://github.com/Pyroxenium/Basalt/discussions">Basalt's Discussion Board</a>, or ask in our [discord](https://discord.gg/yNNnmBVBpE).
---
Feel free to join our [discord](https://discord.gg/yNNnmBVBpE)!
<br><br>
Additionally, if you have questions about Basalt or how to make use of it, feel free to create a new discussion on [Basalt's Discussion Board (Github)](https://github.com/Pyroxenium/Basalt/discussions), or ask in our [discord](https://discord.gg/yNNnmBVBpE).

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +1,4 @@
- Getting Started
- [Home](Home.md)
- [Quick Start](home/Quick-Start.md)
- [Installer](home/installer)
- [Home](Home)
- [How To](home/How-To)
- [Download](home/download)

View File

@@ -1,35 +1,32 @@
- About
- [Home](Home.md)
- [Quick Start](home/Quick-Start.md)
- [Installer](home/installer)
- [Home](home)
- [How To](home/How-To)
- [Download](home/download)
- Objects
- [Basalt](objects/Basalt)
- [Object](objects/Object)
- [Button](objects/Button)
- [Checkbox](objects/Checkbox)
- [Dropdown](objects/Dropdown)
- [Frame](objects/Frame)
- [Image](objects/Image)
- [Input](objects/Input)
- [Label](objects/Label)
- [List](objects/List)
- [Menubar](objects/Menubar)
- [Pane](objects/Pane)
- [Program](objects/Program)
- [Progressbar](objects/Progressbar)
- [Radio](objects/Radio)
- [Scrollbar](objects/Scrollbar)
- [Slider](objects/Slider)
- [Textfield](objects/Textfield)
- [Animation](objects/Animation.md)
- [Thread](objects/Thread)
- [Timer](objects/Timer)
- Events
- [Mouse Events](events/mouseEvents.md)
- [Keyboard Events](events/keyEvents.md)
- [Other Events](events/otherEvents.md)
- [Basalt](objects/Basalt.md)
- [Object](objects/Object.md)
- [Button](objects/Button.md)
- [Checkbox](objects/Checkbox.md)
- [Dropdown](objects/Dropdown.md)
- [Frame](objects/Frame.md)
- [Image](objects/Image.md)
- [Input](objects/Input.md)
- [Label](objects/Label.md)
- [List](objects/List.md)
- [Menubar](objects/Menubar.md)
- [Pane](objects/Pane.md)
- [Program](objects/Program.md)
- [Progressbar](objects/Progressbar.md)
- [Radio](objects/Radio.md)
- [Scrollbar](objects/Scrollbar.md)
- [Slider](objects/Slider.md)
- [Textfield](objects/Textfield.md)
- [Animation](objects/Animation.md)
- [Thread](objects/Thread.md)
- [Timer](objects/Timer.md)
- Tips & Tricks
- [Component Logic](tips/logic)
- [Changing Button Color](tips/buttons)
- [Advanced usage of Events](tips/events.md)
- [Example Designs](tips/design.md)
- [Your Logic](tips/logic.md)
- [Button coloring](tips/buttonColoring.md)
- [Designing/Animating](tips/design.md)
- [Dynamic Values](tips/dynamicvalues.md)
- [XML](tips/xml.md)

View File

@@ -1,39 +0,0 @@
Here we will talk about keyboard events and how you can manipulate them. There are 2 possible key events you can add to almost every visual object.
# onKey
`onKey(self, event, key)`<br>
The computercraft event which triggers this method is `key`.
Any visual object can register onKey events.
Here is a example on how to add a onKey event to your frame:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myMainFrame"):show()
local subFrame = mainFrame:addFrame("subFrame"):setPosition(3,3):setSize(18,6):setBar("Sub Frame",colors.black):showBar():show()
function openSubFrame()
subFrame:show()
end
mainFrame:onKey(openSubFrame)
```
# onKeyUp
`onKeyUp(self, event, key)`<br>
The computercraft event which triggers this method is `key_up`.
Any visual object can register onKeyUp events.
Here is a example on how to add a onKeyUp event to your frame:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myMainFrame"):show()
local subFrame = mainFrame:addFrame("subFrame"):setPosition(3,3):setSize(18,6):setBar("Sub Frame",colors.black):showBar():show()
function openSubFrame()
subFrame:show()
end
mainFrame:onKeyUp(openSubFrame)
```

View File

@@ -1,82 +0,0 @@
Here we will talk about mouse events and how you can use them. You can register custom mouse events to all visual objects
# onClick
`onClick(self, event, button, x, y)`<br>
The computercraft event which triggers this method is `mouse_click` and `monitor_touch`.
Any visual object can register onClick events.
Here is a example on how to add a onClick event to your button:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myMainFrame"):show()
local button = mainFrame:addButton("myButton"):setPosition(3,3):setSize(12,3):setText("Click"):show()
function buttonOnClick()
basalt.debug("Button got clicked!")
end
button:onClick(buttonOnClick())
```
# onClickUp
`onClickUp(self, event, button, x, y)`<br>
The computercraft event which triggers this method is `mouse_up`.
Any visual object can register onClickUp events.
Here is a example on how to add a onClickUp event to your button:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myMainFrame"):show()
local button = mainFrame:addButton("myButton"):setPosition(3,3):setSize(12,3):setText("Click"):show()
function buttonOnClick(self, button, x, y)
basalt.debug("Button got clicked!")
end
button:onClick(buttonOnClick)
function buttonOnRelease(self, button, x, y)
basalt.debug("Button got released!")
end
button:onClickUp(buttonOnRelease)
```
# onScroll
`onScroll(self, event, direction, x, y)`<br>
The computercraft event which triggers this method is `mouse_scroll`.
Any visual object can register onScroll events.
Here is a example on how to add a onScroll event to your button:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myMainFrame"):show()
local button = mainFrame:addButton("myButton"):setPosition(3,3):setSize(12,3):setText("Click"):show()
function buttonOnScroll(self, direction, x, y)
basalt.debug("Someone scrolls on me!")
end
button:onScroll(buttonOnScroll)
```
# onDrag
`onDrag(self, event, button, x, y)`<br>
The computercraft event which triggers this method is `mouse_drag`.
Any visual object can register onDrag events.
Here is a example on how to add a onDrag event to your button:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myMainFrame"):show()
local button = mainFrame:addButton("myButton"):setPosition(3,3):setSize(12,3):setText("Click"):show()
function buttonOnDrag(self, button, x, y)
basalt.debug("Someone drags me (i know i wont reposition myself)!")
end
button:onDrag(buttonOnDrag)
```

View File

@@ -1,79 +0,0 @@
There are also other useful events you can listen to:
# onChange
`onChange(self)`<br>
This is a custom event which gets triggered as soon as the function :setValue() is called. This function is also called by basalt, for example if you change the input, textfield or checkbox (or all the different types of lists) objects.
Here is a example on how to add a onChange event to your input, and also another example for your checkbox:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myMainFrame"):show()
local aInput = mainFrame:addInput("specialInput"):setPosition(3,3):show()
local aCheckbox = mainFrame:addCheckbox("specialCheckbox"):setPosition(3,5):show()
local function checkInput(input)
if(string.lower(input:getValue())=="hello")then
basalt.debug("Hello back!")
end
end
local function checkCheckbox(checkbox)
if(checkbox:getValue()==true)then -- or if(checkbox:getValue())then
basalt.debug("Checkbox is active, let us do something!")
end
end
aInput:onChange(checkInput)
aCheckbox:onChange(checkCheckbox)
```
# onResize
`onResize(self)`<br>
This is a custom event which gets triggered as soon as the parent frame gets resized.
Here is a example on how to add a onResize event to your button:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myMainFrame"):show()
local aButton = mainFrame:addButton("myButton"):setPosition(3,3):show()
local function onButtonResize(button)
local width = mainFrame:getWidth()
button:setSize()
end
aButton:onResize(onButtonResize)
```
# onLoseFocus
`onLoseFocus(self)`<br>
This event gets triggered as soon as the object loses its focus.
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aButton = mainFrame:addButton("exampleButton"):setPosition(3,3):onLoseFocus(
function(self)
basalt.debug("Please come back... :(")
end
):show()
```
# onGetFocus
`onGetFocus(self)`<br>
This event gets triggered as soon as the object is the currently focused object.
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aButton = mainFrame:addButton("exampleButton"):setPosition(3,3):onGetFocus(
function(self)
basalt.debug("Welcome back!")
end
):show()
```

61
docs/home/How-To.md Normal file
View File

@@ -0,0 +1,61 @@
# How-To
After downloading the project you can finally start creating your own program and use basalt. The first thing you want to use in your program is always:
```lua
local basalt = require("basalt")
```
It doesn't matter if you're using the source folder or the minified/packed version of basalt. Both can be found by using require("basalt") without .lua.
Also to really run basalt you should use
```lua
basalt.autoUpdate()
```
somewhere on the bottom of your program. basalt.autoUpdate() starts the event listener and the draw handler.
## Example
Here is a fully working example of how a program could look like:
```lua
local basalt = require("basalt") --> Load the basalt framework into the variable called "basalt"
--> Now we want to create a base frame, we call the variable "main" - by default everything you create is visible. (you don't need to use :show())
local main = basalt.createFrame()
local button = main:addButton() --> Here we add our first button
button:setPosition(4, 4) -- of course we want to change the default position of our button
button:setSize(16, 3) -- and the default size.
button:setText("Click me!") --> This method displays what the text of our button should look like
local function buttonClick() --> Let us create a function we want to call when the button gets clicked
basalt.debug("I got clicked!")
end
-- Now we just need to register the function to the buttons onClick event handlers, this is how we can achieve that:
button:onClick(buttonClick)
basalt.autoUpdate() -- As soon as we call basalt.autoUpdate, the event and draw handlers will listen to any incomming events (and draw if necessary)
```
If you're like us and strive for succinct and beautiful code, here is a cleaner implementation of the code above:
```lua
local basalt = require("basalt")
local main = basalt.createFrame()
local button = main --> Basalt returns an instance of the object on most methods, to make use of "call-chaining"
:addButton() --> This is an example of call chaining
:setPosition(4,4)
:setText("Click me!")
:onClick(
function()
basalt.debug("I got clicked!")
end)
basalt.autoUpdate()
```

View File

@@ -1,93 +0,0 @@
## HowTo Use
To load the framework into your project, make use of the following code on top of your code.
```lua
local basalt = require("Basalt")
```
It does not matter if you have installed the single file version or the full folder project. <br>
Both versions can be loaded by using `require("Basalt")`, you dont need to add `.lua`.
## Download
### Download the folder version
This version is for people who'd like to work with Basalt, change something in Basalt or checkout the project.<br>
But you are also able to just use it to create your own UI.<br>
To install the full project to your CC:Tweaked Computer, use the following command on your CC:Tweaked shell:
`pastebin run ESs1mg7P`
This will download the project as a folder called "Basalt". You are immediatly after the download is done able to use it in your projects.
### Download the single file version
This is the version you should use if you're done with programming. It is a little bit faster and it is also minified, which makes the project smaller.
To install the single filed project to your CC:Tweaked Computer, use the following command on your CC:Tweaked shell:
`pastebin run ESs1mg7P packed`
This will download the project as a single file called "basalt.lua". You are immediatly after the download is done able to use it in your projects.
### Basalt Package Manager
The Basalt Package Manager is still in alpha!<br><br>
The Basalt Package Manager is a visual installer, you are able to change some settings, also to choose which objects are necessary for your projects and which are not.
To install the BPM (Basalt Package Manager) use the following command on your CC:Tweaked shell:
`pastebin run ESs1mg7P bpm true`
The true keyword in the end is optional and would simply start BPM immediately.
## Example
Here is a fully functioning example of Basalt code
```lua
local basalt = require("Basalt") --> Load the Basalt framework
--> Create the first frame. Please note that Basalt needs at least one active "non-parent" frame to properly supply events
--> When Basalt#createFrame makes use of unique identifiers (commonly referred to as UIDs), meaning that the supplied value must be UNIQUE
--> If the supplied UID is ambiguous, Basalt#createFrame returns a nil value
local mainFrame = basalt.createFrame("mainFrame")
--> Show the frame to the user
mainFrame:show()
local button = mainFrame:addButton("clickableButton") --> Add a button to the mainFrame (With a unique identifier)
--> Set the position of the button, Button#setPosition follows an x, y pattern.
--> The x value is how far right the object should be from its anchor (negative values from an anchor will travel left)
--> The y value is how far down the object should be from its anchor (negative values from an anchor will travel up)
button:setPosition(4, 4)
button:setText("Click me!") --> Set the text of our button
local function buttonClick() --> This function serves as our click logic
basalt.debug("I got clicked!")
end
--> Remember! You cannot supply buttonClick(), that will only supply the result of the function
--> Make sure the button knows which function to call when it's clicked
button:onClick(buttonClick)
button:show() --> Make the button visible, so the user can click it
basalt.autoUpdate() --> Basalt#autoUpdate starts the event listener to detect user input
```
If you're like us and strive for succinct and beautiful code, here is a cleaner implementation of the code above:
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame("mainFrame"):show()
local button = mainFrame --> Basalt returns an instance of the object on most methods, to make use of "call-chaining"
:addButton("clickableButton") --> This is an example of call chaining
:setPosition(4,4)
:setText("Click me!")
:onClick(
function()
basalt.debug("I got clicked!")
end)
:show()
basalt.autoUpdate()
```

36
docs/home/download.md Normal file
View File

@@ -0,0 +1,36 @@
Basalt provides multiple unique versions. A source version, a minified version and a web version.
## Source
This version is, like the name already says, the source code of basalt. If you want to dig into the code, add additional content or just prefer to use the source, then you should aim for the source-version.
The following command allows you to download the source-version on your computer:
`wget run https://basalt.madefor.cc/install.lua source [foldername] [branch]`
The first optional argument is the folder name you wish that basalt should be installed into, by default the folder is called basalt.
The second optional argument is the branch you want to use. If you don't know what this means please ignore it (the 2 options are master and dev)
## Minified / Packed
This version is the minified version, i also call it the packed version. There are 2 changes, the first one is that the code will be shown minified which makes the size much smaller, the second change is that you will recieve a file instead of a folder.
The following command allows you to download the packed-version on your computer:
`wget run https://basalt.madefor.cc/install.lua packed [filename] [branch]`
The first optional argument is the file name you wish that the installer should use, by default the file is called basalt.lua.
The second optional argument is the branch you want to use. If you don't know what this means please ignore it (the 2 options are master and dev)
## Web
The web version is a special version, used if your goal is to keep your project's size as small as possible. I suggest you to use the web version only if you don't restart your program over and over again. For example if you designed your program to reboot after the user made a bad choice (leads into a error or something like that) it is better to use the minified/source version.
The following command allows you to download the web-version on your computer:
`wget run https://basalt.madefor.cc/install.lua web [version] [filename]`
By default the first argument is the latest version of basalt's releases. [Here](https://github.com/Pyroxenium/Basalt/tree/master/docs/versions) you can see which versions are available to use.
For example: wget run https://basalt.madefor.cc/install.lua web basalt-1.6.3.lua - the second argument is just the file name, default is basaltWeb.lua.
Remember to rename `local basalt = require("basalt")` into `local basalt = require("basaltWeb")` if you want to use the web-version

View File

@@ -1,74 +0,0 @@
# Installer
This is just a script which helps you to setup your program to automatically install the Basalt UI Framework, if it doesn't exists. Means, you create your program (which requires basalt) and add this on the top of your program. Now, everytime you execute your program it checks if basalt.lua (or your custom filepath) exists or not, if not it installs it, or if you are using the advanced installer, it asks the user if the program is allowed to install basalt for you.
## Basic Installer
Here is a very basic one which just installs basalt.lua if don't exist:
```lua
--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", "")) -- here you can change the variablename in any variablename you want default: basalt
```
## Advanced Installer
This is a visual version, it asks the user if he wants to install basalt.lua (if not found)<br>
![](https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/installer.png)
```lua
--Basalt configurated installer
local filePath = "basalt.lua" --here you can change the file path default: basalt
if not(fs.exists(filePath))then
local w,h = term.getSize()
term.clear()
local _installerWindow = window.create(term.current(),w/2-8,h/2-3,18,6)
_installerWindow.setBackgroundColor(colors.gray)
_installerWindow.setTextColor(colors.black)
_installerWindow.write(" Basalt Installer ")
_installerWindow.setBackgroundColor(colors.lightGray)
for line=2,6,1 do
_installerWindow.setCursorPos(1,line)
if(line==3)then
_installerWindow.write(" No Basalt found! ")
elseif(line==4)then
_installerWindow.write(" Install it? ")
elseif(line==6)then
_installerWindow.setTextColor(colors.black)
_installerWindow.setBackgroundColor(colors.gray)
_installerWindow.write("Install")
_installerWindow.setBackgroundColor(colors.lightGray)
_installerWindow.write(string.rep(" ",5))
_installerWindow.setBackgroundColor(colors.red)
_installerWindow.write("Cancel")
else
_installerWindow.write(string.rep(" ",18))
end
end
_installerWindow.setVisible(true)
_installerWindow.redraw()
while(not(fs.exists(filePath))) do
local event, p1,p2,p3,p4 = os.pullEvent()
if(event=="mouse_click")then
if(p3==math.floor(h/2+2))and(p2>=w/2-8)and(p2<=w/2-2)then
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", ""))
_installerWindow.setVisible(false)
term.clear()
break
end
if(p3==math.floor(h/2+2))and(p2<=w/2+9)and(p2>=w/2+4)then
_installerWindow.clear()
_installerWindow.setVisible(false)
term.setCursorPos(1,1)
term.clear()
return
end
end
end
term.setCursorPos(1,1)
term.clear()
end
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
------------------------------
```

View File

@@ -33,22 +33,40 @@
</head>
<body>
<div id="app">Did you know: Basalt is a Pyroxene?></div>
<script src="//cdn.jsdelivr.net/npm/docsify-edit-on-github"></script>
<script>
window.$docsify = {
logo: '/_media/logo.png',
loadNavbar: true,
loadSidebar: true,
loadFooter: '_footer.md',
autoHeader: true,
subMaxLevel: 2,
subMaxLevel: 3,
homepage: 'Home.md',
name: 'Basalt',
repo: 'https://github.com/Pyroxenium/Basalt',
auto2top: true
auto2top: true,
search: {
maxAge: 86400000, // Expiration time, the default one day
paths: 'auto',
placeholder: 'Type to search',
noData: 'No Results!',
// Headline depth, 1 - 6
depth: 2,
hideOtherSidebarContent: false, // whether or not to hide other sidebar content
},
plugins: [
EditOnGithubPlugin.create("https://github.com/Pyroxenium/Basalt/blob/master/docs/", null, "Edit on Github")
]
}
</script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/js/docsify-themeable.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1.28.0/components/prism-lua.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/@alertbox/docsify-footer/dist/docsify-footer.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script>
</body>
</html>

375
docs/install.lua Normal file
View File

@@ -0,0 +1,375 @@
-- this file can download the project or other tools from github
local args = table.pack(...)
local installer = {printStatus=true}
installer.githubPath = "https://raw.githubusercontent.com/Pyroxenium/Basalt/"
local function printStatus(...)
if(installer.printStatus)then
print(...)
elseif(type(installer.printStatus)=="function")then
installer.printStatus(...)
end
end
function installer.get(url)
local httpReq = http.get(url, _G._GIT_API_KEY and {Authorization = "token ".._G._GIT_API_KEY})
printStatus("Downloading "..url)
if(httpReq~=nil)then
local content = httpReq.readAll()
if not content then
error("Could not connect to website")
end
return content
end
end
local basaltDataCache
function installer.getBasaltData()
if(basaltDataCache~=nil)then return basaltDataCache end
local content
printStatus("Downloading basalt data...")
if(fs.exists("basaltdata.json"))then
content = fs.open("basaltdata.json", "r")
else
content = installer.get("https://basalt.madefor.cc/basaltdata.json")
end
if(content~=nil)then
content = content.readAll()
basaltDataCache = textutils.unserializeJSON(content)
printStatus("Successfully downloaded basalt data!")
return basaltDataCache
end
end
-- Creates a filetree based on my github project, ofc you can use this in your projects if you'd like to
function installer.createTree(page, branch, dirName)
dirName = dirName or ""
printStatus("Receiving file tree for "..(dirName~="" and "Basalt/"..dirName or "Basalt"))
local tree = {}
local request = http.get(page, _G._GIT_API_KEY and {Authorization = "token ".._G._GIT_API_KEY})
if not(page)then return end
if(request==nil)then error("API rate limit exceeded. It will be available again in one hour.") end
for _,v in pairs(textutils.unserialiseJSON(request.readAll()).tree)do
if(v.type=="blob")then
table.insert(tree, {name = v.path, path=fs.combine(dirName, v.path), url=installer.githubPath..branch.."/Basalt/"..fs.combine(dirName, v.path), size=v.size})
elseif(v.type=="tree")then
tree[v.path] = installer.createTree(v.url, branch, fs.combine(dirName, v.path))
end
end
return tree
end
function installer.createTreeByBasaltData(page, branch, dirName)
dirName = dirName or ""
printStatus("Receiving file tree for "..(dirName~="" and "Basalt/"..dirName or "Basalt"))
local bData = installer.getBasaltData()
if(bData~=nil)then
local tree = {}
for k,v in pairs(bData.structure)do
if(k=="base")then
for a,b in pairs(v)do
table.insert(tree, b)
end
else
tree[k] = v
end
end
return tree
end
end
local function splitString(str, sep)
if sep == nil then
sep = "%s"
end
local t={}
for v in string.gmatch(str, "([^"..sep.."]+)") do
table.insert(t, v)
end
return t
end
function installer.createIgnoreList(str)
local files = splitString(str, ":")
local ignList = {}
for k,v in pairs(files)do
local a = splitString(v, "/")
if(#a>1)then
if(ignList[a[1]]==nil)then ignList[a[1]] = {} end
table.insert(ignList[a[1]], a[2])
else
table.insert(ignList, v)
end
end
end
function installer.download(url, file)
local content = installer.get(url)
if(content~=nil)then
local f = fs.open(file, "w")
f.write(content)
f.close()
end
end
function installer.getRelease(version)
local v = installer.getBasaltData().versions[version]
if(v~=nil)then
printStatus("Downloading basalt "..version)
local content = http.get("https://basalt.madefor.cc/versions/"..v, {Authorization = _G._GIT_API_KEY and "token ".._G._GIT_API_KEY})
if(content~=nil)then
return content.readAll()
end
end
end
function installer.downloadRelease(version, file)
local content = installer.getRelease(version)
if(content~=nil)then
local f = fs.open(file or "basalt.lua", "w")
f.write(content)
f.close()
return true
end
return false
end
function installer.getPackedProject(branch, ignoreList)
if (ignoreList==nil)then
ignoreList = {"init.lua"}
else
table.insert(ignoreList, "init.lua")
end
local projTree = installer.createTree("https://api.github.com/repos/Pyroxenium/Basalt/git/trees/"..branch..":Basalt", branch, "")
local filteredList = {}
local project = {}
local function isInIgnoreList(file, ign)
if(ign~=nil)then
for k,v in pairs(ign)do
if(v==file.name)then
return true
end
end
end
return false
end
for k,v in pairs(projTree)do
if(type(k)=="string")then
for a,b in pairs(v)do
if not(isInIgnoreList(b, ignoreList~=nil and ignoreList[k] or nil))then
if(filteredList[k]==nil)then filteredList[k] = {} end
table.insert(filteredList[k], b)
end
end
else
if not(isInIgnoreList(v, ignoreList))then
table.insert(filteredList, v)
end
end
end
local fList = {}
local delay = 0
for k,v in pairs(filteredList)do
if(type(k)=="string")then
for a,b in pairs(v)do
table.insert(fList, function() sleep(delay)
if(project[k]==nil)then project[k] = {} end
table.insert(project[k], {content=installer.get(b.url), name=b.name, path=b.path, size = b.size, url = b.url})
delay = delay + 0.05
end)
end
else
table.insert(fList, function() sleep(delay) table.insert(project, {content=installer.get(v.url), name=v.name, path=v.path, size = v.size, url = v.url}) delay = delay + 0.05 end)
end
end
parallel.waitForAll(table.unpack(fList))
local projectContent =
[[
local project = {}
local packaged = true
local baseRequire = require
local require = function(path)
for k,v in pairs(project)do
if(type(v)=="table")then
for name,b in pairs(v)do
if(name==path)then
return b()
end
end
else
if(k==path)then
return v()
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(project)do
if(type(k)=="string")then
local newSubDir = 'project["'..k..'"] = {}\n'
projectContent = projectContent.."\n"..newSubDir
for a,b in pairs(v)do
local newFile = 'project["'..k..'"]["'..b.name:gsub(".lua", "")..'"] = function(...)\n'..b.content..'\nend'
projectContent = projectContent.."\n"..newFile
end
else
local newFile = 'project["'..v.name:gsub(".lua", "")..'"] = function(...)\n'..v.content..'\nend'
projectContent = projectContent.."\n"..newFile
end
end
projectContent = projectContent..'\n return project["main"]()'
return projectContent
end
function installer.generateWebVersion(file, version)
if(fs.exists(file))then error("A file called "..file.." already exists!") end
version = version or "latest.lua"
local request = http.get("https://basalt.madefor.cc/versions/"..version, _G._GIT_API_KEY and {Authorization = "token ".._G._GIT_API_KEY})
if(request~=nil)then
if(fs.exists(file))then
fs.delete(file)
end
local f = fs.open(file, "w")
local link = "https://basalt.madefor.cc/versions/"..version
local content = 'local request = http.get("'..link..'", _G._GIT_API_KEY and {Authorization = "token ".._G._GIT_API_KEY})\n'
content = content..
[[
if(request~=nil)then
return load(request.readAll())()
else
error("Unable to connect to ]]..link..[[")
end
]]
f.write(content)
f.close()
printStatus("Web version successfully downloaded!")
else
error("Version doesn't exist!")
end
end
function installer.getProjectFiles(branch, ignoreList)
local projTree = installer.createTree("https://api.github.com/repos/Pyroxenium/Basalt/git/trees/"..branch..":Basalt", branch, "")
local filteredList = {}
local project = {}
local function isInIgnoreList(file)
if(ignoreList~=nil)then
for k,v in pairs(ignoreList)do
if(v==file)then
return true
end
end
end
return false
end
for k,v in pairs(projTree)do
if not(isInIgnoreList(v.name))then
if(type(k)=="string")then
local sub = {}
for a,b in pairs(v)do
if not(isInIgnoreList(b.name))then
table.insert(sub, b)
end
end
filteredList[k] = sub
else
table.insert(filteredList, v)
end
end
end
local function downloadFile(url, path)
project[path] = installer.get(url)
end
local fList = {}
local delay = 0
for k,v in pairs(filteredList)do
if(type(k)=="string")then
for a,b in pairs(v)do
table.insert(fList, function() sleep(delay) downloadFile(b.url, b.path) end)
delay = delay + 0.05
end
else
table.insert(fList, function() sleep(delay) downloadFile(v.url, v.path) end)
delay = delay + 0.05
end
end
parallel.waitForAll(table.unpack(fList))
return project
end
function installer.downloadPacked(filename, branch, ignoreList, minify)
if(fs.exists(filename))then error("A file called "..filename.." already exists!") end
local projectContent = installer.getPackedProject(branch, ignoreList)
if(minify)then
local min
if(fs.exists("packager.lua"))then
min = require("packager")
else
min = load(installer.get("https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/packager.lua"))()
end
if(min~=nil)then
success, data = min(projectContent)
if(success)then
projectContent = data
else
error(data)
end
end
end
local f = fs.open(filename, "w")
f.write(projectContent)
f.close()
printStatus("Packed version successfully downloaded!")
end
function installer.downloadProject(projectDir, branch, ignoreList)
if(fs.exists(projectDir))then error("A folder called "..projectDir.." already exists!") end
projectDir = projectDir or "basalt"
branch = branch or "master"
local projectFiles = installer.getProjectFiles(branch, ignoreList)
fs.makeDir(projectDir)
for k,v in pairs(projectFiles)do
local f = fs.open(fs.combine(projectDir, k), "w")
f.write(v)
f.close()
end
printStatus("Source version successfully downloaded!")
end
if(#args>0)then
if(string.lower(args[1])=="bpm")or(string.lower(args[1])=="basaltpackagemanager")or(string.lower(args[1])=="gui")then
installer.download("https://raw.githubusercontent.com/Pyroxenium/Basalt/master/basaltPackageManager.lua", "basaltPackageManager.lua")
if(args[2]=="true")then shell.run("basaltPackageManager.lua") fs.delete("basaltPackageManager.lua") end
elseif(string.lower(args[1])=="packed")then
installer.downloadPacked(args[2] or "basalt.lua", args[3] or "master", args[4]~=nil and installer.createIgnoreList(args[4]) or nil, args[5] == "false" and false or true)
elseif(string.lower(args[1])=="source")then
installer.downloadProject(args[2] or "basalt", args[3] or "master", args[4]~=nil and installer.createIgnoreList(args[4]) or nil)
elseif(string.lower(args[1])=="web")then
installer.generateWebVersion(args[3] or "basaltWeb.lua", args[2] or "latest.lua")
elseif(string.lower(args[1])=="file")or(string.lower(args[1])=="release")then
installer.download("https://basalt.madefor.cc/versions/"..args[2] or "latest.lua", args[3] or "basalt.lua")
end
end
return installer

View File

@@ -1,303 +1,32 @@
With animations, you can create a beautiful experience for users while interacting with objects.<br>
For now the animation class is very basic, it will be expanded in the future, but we have to say you can already do almost everything you can imagine!
With animations, you can create a beautiful experience for users while interacting with your program.
There are 2 types of animations, predefined animations and custom animations. By using add and wait you can create custom
animations (calls). Pre-defined methods are for example move, offset, size, changeText,...
Right now animation is a class which makes use of the timer event.<br>
You can find more information below:
:setObject always sets the object on what pre-defined methods should apply on.
`The animation object is still a WIP and the way you use it right now could change in the future!`
## add
Adds a new function to an animation
#### Parameters:
1. `function` The function containing animation logic
#### Returns:
1. `animation` Animation in use
When calling a pre-defined animation it will check what is safed as object (:setObject) and will calculate the animation methods based on that which means you won't
be able to change the object on the fly - you will always have to recreate the animation itself
#### Usage:
* This will set the button position to 3,3, waits 1 second, then sets position to 4,4, waits 2 seconds, and then sets the position to 5,5
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():add(function() testButton:setPosition(3,3) end):wait(1):add(function() testButton:setPosition(1,1,"r") end):wait(2):add(function() testButton:setPosition(1,1,"r") end)
aAnimation:play()
```
## wait
Sets a wait timer for the next function after the previous function got executed, no wait timer calls the next function immediately
#### Parameters:
1. `number` The length of delay between the functions _(in seconds)_
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():add(function() testButton:setPosition(3,3) end):wait(1):add(function() testButton:setPosition(1,1,"r") end):wait(2):add(function() testButton:setPosition(1,1,"r") end)
aAnimation:play()
```
## play
Plays the animation
#### Parameters:
1. `boolean` Whether it will loop forever, will most likely be replaced with a count in the future
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():add(function() testButton:setBackground(colors.black) end):wait(1):add(function() testButton:setBackground(colors.gray) end):wait(1):add(function() testButton:setBackground(colors.lightGray) end)
aAnimation:play() -- changes the background color of that button from black to gray and then to lightGray
```
## cancel
Cancels the animation
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():add(function() testButton:setBackground(colors.black) end):wait(1):add(function() aAnimation:cancel() end):wait(1):add(function() testButton:setBackground(colors.lightGray) end)
aAnimation:play()
```
## setObject
Sets the object which the animation should reposition/resize
#### Parameters:
1. `table` object
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():setObject(testButton)
```
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
```
```xml
<animation object="buttonToAnimate" />
```
## move
Moves the object which got defined by setObject
#### Parameters:
1. `number` x coordinate
2. `number` y coordinate
3. `number` duration in seconds
4. `number` time - time when this part should begin (offset to when the animation starts - default 0)
5. `table` object - optional, you could also define the object here
#### Returns:
1. `animation` Animation in use
#### Usage:
* Takes 2 seconds to move the object from its current position to x15 y3
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):move(15,3,2):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<move><x>15</x><y>6</y><duration>2</duration></move>
</animation>
```
## offset
Changes the offset on the object which got defined by setObject
#### Parameters:
1. `number` x offset
2. `number` y offset
3. `number` duration in seconds
4. `number` time - time when this part should begin (offset to when the animation starts - default 0)
5. `table` object - optional, you could also define the object here
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local subFrame = mainFrame:addFrame("frameToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(subFrame):offset(1,12,1):play()
```
```xml
<animation object="frameToAnimate" play="true">
<offset><x>1</x><y>12</y><duration>1</duration></offset>
</animation>
```
## size
Changes the size on the object which got defined by setObject
#### Parameters:
1. `number` width
2. `number` height
3. `number` duration in seconds
4. `number` time - time when this part should begin (offset to when the animation starts - default 0)
5. `table` object - optional, you could also define the object here
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):size(15,3,1):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<offset><w>15</w><h>3</h><duration>1</duration></offset>
</animation>
```
## changeText
Changes the text while animation is running
#### Parameters:
1. `table` multiple text strings - example: {"i", "am", "groot"}
2. `number` duration in seconds
3. `number` time - time when this part should begin (offset to when the animation starts - default 0)
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeText({"i", "am", "groot"}, 2):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<text>
<text>i</text>
<text>am</text>
<text>groot</text>
<duration>2</duration>
</text>
</animation>
```
## changeTextColor
Changes the text color while the animation is running
#### Parameters:
1. `table` multiple color numbers - example: {colors.red, colors.yellow, colors.green}
2. `number` duration in seconds
3. `number` time - time when this part should begin (offset to when the animation starts - default 0)
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor({colors.red, colors.yellow, colors.green}, 2):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<textColor>
<color>red</color>
<color>yellow</color>
<color>green</color>
<duration>2</duration>
</textColor>
</animation>
```
## changeBackground
Changes the background color while the animation is running
#### Parameters:
1. `table` multiple color numbers - example: {colors.red, colors.yellow, colors.green}
2. `number` duration in seconds
3. `number` time - time when this part should begin (offset to when the animation starts - default 0)
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor({colors.red, colors.yellow, colors.green}, 2):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<background>
<color>red</color>
<color>yellow</color>
<color>green</color>
<duration>2</duration>
</background>
</animation>
```
| | |
|---|---|
|[add](objects/Animation/add.md)|Adds a new custom function to call at the current time
|[wait](objects/Animation/wait.md)|Adds a amount to the animation time
|[play](objects/Animation/play.md)|Plays the animation
|[cancel](objects/Animation/cancel.md)|Cancels the animation
|[addMode](objects/Animation/addMode.md)|Adds custom easings
|[setMode](objects/Animation/setMode.md)|Changes the current easing-calculation
|[setObject](objects/Animation/setObject.md)|Sets an object on which predefined animations should work on
|[move](objects/Animation/move.md)|Predefined animation: moves the object to a new position
|[offset](objects/Animation/offset.md)|Predefined animation: Changes the offset of that object
|[size](objects/Animation/size.md)|Predefined animation: Changes the size on a object
|[changeText](objects/Animation/changeText.md)|Predefined animation: Changes the text (object needs a setText method)
|[changeTextColor](objects/Animation/changeTextColor.md)|Predefined animation: changes the foreground/textcolor on a object
|[changeBackground](objects/Animation/changeBackground.md)|Predefined animation: changes the background on a object
# Events
## onDone
`onDone(self)`<br>
This is a event which gets fired as soon as the animation has finished.
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor({colors.red, colors.yellow, colors.green}, 2):play()
aAnimation:onDone(function()
basalt.debug("The animation is done")
end)
```
In XML you are also able to queue multiple animations, like this:
```xml
<animation id="anim2" object="buttonToAnimate">
<textColor>
<color>red</color>
<color>yellow</color>
<color>green</color>
<duration>2</duration>
</textColor>
</animation>
<animation onDone="#anim2" object="buttonToAnimate" play="true">
<background>
<color>red</color>
<color>yellow</color>
<color>green</color>
<duration>2</duration>
</background>
</animation>
```
| | |
|---|---|
|[onStart](objects/Animation/onStart.md)|Gets called as soon as the animation is started
|[onDone](objects/Animation/onDone.md)|Gets called as soon as the animation has finished

View File

@@ -0,0 +1,17 @@
## add
Adds a new function to an animation
#### Parameters:
1. `function` The function containing animation logic
#### Returns:
1. `animation` Animation in use
#### Usage:
* This will set the button position to 3,3, waits 1 second, then sets position to 4,4, waits 2 seconds, and then sets the position to 5,5
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():add(function() testButton:setPosition(3,3) end):wait(1):add(function() testButton:setPosition(1,1,"r") end):wait(2):add(function() testButton:setPosition(1,1,"r") end)
aAnimation:play()
```

View File

@@ -0,0 +1,30 @@
## addMode
Adds a new easing curve into the available easing list. Checkout the animation object if you want to know how this works.
#### Parameters:
1. `string` - The name of the curve you want to use.
2. `functon` - The function to call
#### Returns:
1. `animation` Animation in use
#### Usage:
* Creates a new curve
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton)
local function easeInBack(t) -- t is the time from 0 to 1
local c1 = 1.70158;
local c3 = c1 + 1
return c3*t^3-c1*t^2
end
aAnimation:addMode("coolEaseInBack", easeInBack)
aAnimation:setMode("coolEaseInBack"):move(15,3,2):play()
```

View File

@@ -0,0 +1,15 @@
## cancel
Cancels the animation
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():add(function() testButton:setBackground(colors.black) end):wait(1):add(function() aAnimation:cancel() end):wait(1):add(function() testButton:setBackground(colors.lightGray) end)
aAnimation:play()
```

View File

@@ -0,0 +1,28 @@
## changeBackground
Changes the background color while the animation is running
#### Parameters:
1. `number` duration in seconds
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
3. `...` multiple color numbers - example: colors.red, colors.yellow, colors.green
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor(2, 0, colors.red, colors.yellow, colors.green):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<background>
<color>red</color>
<color>yellow</color>
<color>green</color>
<duration>2</duration>
</background>
</animation>
```

View File

@@ -0,0 +1,30 @@
## changeText
Changes the text while animation is running
#### Parameters:
1. `table` multiple text strings - example: {"i", "am", "groot"}
1. `number` duration in seconds
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
3. `...` multiple text strings - example: "i", "am", "groot"
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeText(2, 0, "i", "am", "groot"):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<text>
<text>i</text>
<text>am</text>
<text>groot</text>
<duration>2</duration>
</text>
</animation>
```

View File

@@ -0,0 +1,28 @@
## changeTextColor
Changes the text color while the animation is running
#### Parameters:
1. `number` duration in seconds
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
1. `...` multiple color numbers - example: colors.red, colors.yellow, colors.green
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor(2, 0, colors.red, colors.yellow, colors.green):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<textColor>
<color>red</color>
<color>yellow</color>
<color>green</color>
<duration>2</duration>
</textColor>
</animation>
```

View File

@@ -0,0 +1,25 @@
## move
Moves the object which got defined by setObject
#### Parameters:
1. `number` x coordinate
2. `number` y coordinate
3. `number` duration in seconds
4. `number` time - time when this part should begin (offset to when the animation starts - default 0)
5. `table` object - optional, you could also define the object here
#### Returns:
1. `animation` Animation in use
#### Usage:
* Takes 2 seconds to move the object from its current position to x15 y3
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):move(15,3,2):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<move><x>15</x><y>6</y><duration>2</duration></move>
</animation>
```

View File

@@ -0,0 +1,25 @@
## offset
Changes the offset on the object which got defined by setObject
#### Parameters:
1. `number` x offset
2. `number` y offset
3. `number` duration in seconds
4. `number` time - time when this part should begin (offset to when the animation starts - default 0)
5. `table` object - optional, you could also define the object here
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local subFrame = mainFrame:addFrame("frameToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(subFrame):offset(1,12,1):play()
```
```xml
<animation object="frameToAnimate" play="true">
<offset><x>1</x><y>12</y><duration>1</duration></offset>
</animation>
```

View File

@@ -0,0 +1,35 @@
## onDone
`onDone(self)`<br>
This is a event which gets fired as soon as the animation has finished.
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor({colors.red, colors.yellow, colors.green}, 2):play()
aAnimation:onDone(function()
basalt.debug("The animation is done")
end)
```
In XML you are also able to queue multiple animations, like this:
```xml
<animation id="anim2" object="buttonToAnimate">
<textColor>
<color>red</color>
<color>yellow</color>
<color>green</color>
<duration>2</duration>
</textColor>
</animation>
<animation onDone="#anim2" object="buttonToAnimate" play="true">
<background>
<color>red</color>
<color>yellow</color>
<color>green</color>
<duration>2</duration>
</background>
</animation>
```

View File

@@ -0,0 +1,16 @@
## onStart
`onStart(self)`<br>
This is a event which gets fired as soon as the animation is started.
```lua
local basalt = require("Basalt")
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor({colors.red, colors.yellow, colors.green}, 2)
aAnimation:onStart(function()
basalt.debug("The animation is started")
end)
aAnimation:play()
```

View File

@@ -0,0 +1,16 @@
## play
Plays the animation
#### Parameters:
1. `boolean` Whether it will loop forever, will most likely be replaced with a count in the future
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():add(function() testButton:setBackground(colors.black) end):wait(1):add(function() testButton:setBackground(colors.gray) end):wait(1):add(function() testButton:setBackground(colors.lightGray) end)
aAnimation:play() -- changes the background color of that button from black to gray and then to lightGray
```

View File

@@ -0,0 +1,36 @@
## setMode
Changes the easing curve. If you want to test them, here is a interesting website: https://easings.co
#### Parameters:
1. `string` - The name of the curve you want to use.
#### Returns:
1. `animation` Animation in use
#### Usage:
* Takes 2 seconds to move the object from its current position to x15 y3
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):setMode("easeInBounce"):move(15,3,2):play()
```
## Easing Curve List
Here is a list of all available easing curves:
| | | |
|---|---|---|
|linear||
|easIn|easeOut|easeInOut
|easeInSine|easeOutSine|easeInOutSine
|easeInBack|easeOutBack|easeInOutBack
|easeInCubic|easeOutCubic|easeInOutCubic
|easeInElastic|easeOutElastic|easeInOutElastic
|easeInExpo|easeOutExpo|easeInOutExpo
|easeInBack|easeOutBack|easeInOutBack
|easeInQuad|easeOutQuad|easeInOutQuad
|easeInQuint|easeOutQuint|easeInOutQuint
|easeInQuart|easeOutQuart|easeInOutQuart
|easeInCirc|easeOutCirc|easeInOutCirc
|easeInBounce|easeOutBounce|easeInOutBounce

View File

@@ -0,0 +1,24 @@
## setObject
Sets the object which the animation should reposition/resize
#### Parameters:
1. `table` object
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():setObject(testButton)
```
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
```
```xml
<animation object="buttonToAnimate" />
```

View File

@@ -0,0 +1,24 @@
## size
Changes the size on the object which got defined by setObject
#### Parameters:
1. `number` width
2. `number` height
3. `number` duration in seconds
4. `number` time - time when this part should begin (offset to when the animation starts - default 0)
5. `table` object - optional, you could also define the object here
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton("buttonToAnimate")
local aAnimation = mainFrame:addAnimation():setObject(testButton):size(15,3,1):play()
```
```xml
<animation object="buttonToAnimate" play="true">
<offset><w>15</w><h>3</h><duration>1</duration></offset>
</animation>
```

View File

@@ -0,0 +1,16 @@
## wait
Sets a wait timer for the next function after the previous function got executed, no wait timer calls the next function immediately
#### Parameters:
1. `number` The length of delay between the functions _(in seconds)_
#### Returns:
1. `animation` Animation in use
#### Usage:
```lua
local mainFrame = basalt.createFrame()
local testButton = mainFrame:addButton()
local aAnimation = mainFrame:addAnimation():add(function() testButton:setPosition(3,3) end):wait(1):add(function() testButton:setPosition(1,1,"r") end):wait(2):add(function() testButton:setPosition(1,1,"r") end)
aAnimation:play()
```

View File

@@ -1,201 +1,48 @@
# Basalt
This is the UI Manager and the first thing you want to access.
Before you can access Basalt, you need to add the following code on top of your file:
`local basalt = require("Basalt")`
Now you are able to access the following methods:
## basalt.createFrame
Create a base-frame (main frame)
#### Parameters:
1. `string` name
#### Returns:
1. `frame` object
#### Usage:
* Create and show a frame with id "myFirstFrame"
```lua
local mainFrame = basalt.createFrame("myFirstFrame")
local basalt = require("basalt")
```
## basalt.removeFrame
Removes a base frame
What this code does is it loads basalt into the basalt variable.
You are now able to access the following list of methods:
#### Parameters:
1. `string` name
| | |
|---|---|
|[autoUpdate](objects/Basalt/autoUpdate.md)|Starts the event and draw listener
|[createFrame](objects/Basalt/createFrame.md)|Creates a new base frame
|[debug](objects/Basalt/debug.md)|Writes something into the debug console
|[getFrame](objects/Basalt/getFrame.md)|Returns a frame object by it's id
|[getActiveFrame](objects/Basalt/getActiveFrame.md)|Returns the currently active base frame
|[getTheme](objects/Basalt/getTheme.md)|Returns the currently active theme
|[getVariable](objects/Basalt/getVariable.md)|Returns a variable defined with setVariable
|[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
|[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
|[setActiveFrame](objects/Basalt/setActiveFrame.md)|Sets the active frame
|[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
|[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
## Examples
Here is a lua example on how to create a empty base frame and start basalt's listener.
#### Usage:
* Removes the previously created frame with id "myFirstFrame"
```lua
local mainFrame = basalt.createFrame("myFirstFrame")
basalt.removeFrame("myFirstFrame")
```
## basalt.getFrame
Returns a base frame with the given name
#### Parameters:
1. `string` name
#### Returns:
1. `frame` object
#### Usage:
* Creates, fetches and shows the "myFirstFrame" object
```lua
basalt.createFrame("myFirstFrame"):hide()
basalt.getFrame("myFirstFrame"):show()
```
## basalt.getActiveFrame
Returns the currently active base frame
#### Returns:
1. `frame` The current frame
#### Usage:
* Displays the active frame name in the debug console
```lua
basalt.createFrame()
basalt.debug(basalt.getActiveFrame():getName()) -- returns the uuid
```
## basalt.autoUpdate
Starts the draw and event handler until basalt.stopUpdate() is called
#### Usage:
* Enable the basalt updates, otherwise the screen will not continue to update
```lua
local mainFrame = basalt.createFrame()
basalt.autoUpdate()
```
## basalt.update
Calls the draw and event handler once - this gives more flexibility about which events basalt should process. For example you could filter the terminate event.
#### Parameters:
1. `string` The event to be received
2. `...` Additional event variables to capture
#### Usage:
* Creates and starts a custom update cycle
```lua
local mainFrame = basalt.createFrame()
local aButton = mainFrame:addButton():setPosition(2,2)
while true do
basalt.update(os.pullEventRaw())
end
```
## basalt.stopUpdate
Stops the automatic draw and event handler which got started by basalt.autoUpdate()
#### Usage:
* When the quit button is clicked, the button stops basalt auto updates
```lua
local mainFrame = basalt.createFrame()
local aButton = mainFrame:addButton():setPosition(2,2):setText("Stop Basalt!")
aButton:onClick(function()
basalt.stopUpdate()
end)
basalt.autoUpdate()
```
## basalt.isKeyDown
Checks if the user is currently holding a key
#### Parameters:
1. `number` key code (use the keys table for that)
#### Returns:
1. `boolean` true or false
#### Usage:
* Shows a debug message with true or false if the left ctrl key is down, as soon as you click on the button.
```lua
local mainFrame = basalt.createFrame()
local aButton = mainFrame:addButton():setPosition(2,2):setText("Check Ctrl")
aButton:onClick(function()
basalt.debug(basalt.isKeyDown(keys.leftCtrl))
end)
basalt.autoUpdate()
```
## basalt.debug
creates a label with some information on the main frame on the bottom left, if you click on that label it will open a log view for you. See it as the new print for debugging
You can also edit the default debug Label (change position, change color or whatever you want) by accessing the variable basalt.debugLabel
which returns the debug Label.
Also basalt.debugFrame and basalt.debugList are available.
#### Parameters:
1. `...` (multiple parameters are possible, like print does)
#### Usage:
* Prints "Hello! ^-^" to the debug console
```lua
basalt.debug("Hello! ", "^-^")
```
## basalt.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)
#### Parameters:
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for a example
#### Usage:
* Sets the default theme of basalt.
```lua
basalt.setTheme({
ButtonBG = colors.yellow,
ButtonText = colors.red,
...,
})
```
## basalt.setVariable
This stores a variable which you're able to access via xml. You are also able to add a function, which then gets called by object events created in XML.
#### Parameters:
1. `string` a key name
1. `any` any variable
#### Usage:
* Adds a function to basalt.
```lua
basalt.setVariable("clickMe", function()
basalt.debug("I got clicked")
end)
```
```xml
<button onClick="clickMe" text="Click me" />
```
## basalt.schedule
Schedules a function which gets called in a coroutine. After the coroutine is finished it will get destroyed immediatly. It's something like threads, but with some limits.
#### Parameters:
1. `function` a function which should get executed
#### Returns:
1. `function` it returns the function which you have to execute in order to start the coroutine
#### Usage:
* Creates a schedule which switches the color between red and gray
```lua
local mainFrame = basalt.createFrame()
local aButton = mainFrame:addButton():setText("Click me")
aButton:onClick(basalt.schedule(function(self)
self:setBackground(colors.red)
os.sleep(0.1)
self:setBackground(colors.gray)
os.sleep(0.1)
self:setBackground(colors.red)
os.sleep(0.1)
self:setBackground(colors.gray)
os.sleep(0.1)
self:setBackground(colors.red)
os.sleep(0.1)
self:setBackground(colors.gray)
end))
local basalt = require("basalt") -- Loads Basalt into our project
local main = basalt.createFrame() -- Creates a base frame. On that frame we are able to add object's
-- Here we would add additional object's
basalt.autoUpdate() -- Starts listening to incoming events and draw stuff on the screen. This should nearly always be the last line.
```

View File

@@ -0,0 +1,18 @@
# Basalt
## autoUpdate
This starts the event and draw handler for you. The listeners will run until you stop them.
### Parameters
1. `boolean` optional - if you use false as the first parameter it would stop the listeners. Using false is a synonym for [`basalt.stopUpdate()`](objects/Basalt/stopUpdate.md).
### Usage
* Enables the basalt listeners, otherwise the screen will not continue to update
```lua
local main = basalt.createFrame()
basalt.autoUpdate()
```

View File

@@ -0,0 +1,35 @@
# Basalt
## createFrame
Creates a new base-frame, you can have as many base-frames as you want, but only 1 can be active (visible) at the same time.
You can always switch between your base frames.
Only the currently active base-frame listens to incoming events (except for some events like time-events and peripheral-events)
### Parameters
1. `string` id - optional (if you dont set a id it will automatically create a uuid for you)
### Returns
1. `frame` object
### Usage
* How to use multiple base frames:
```lua
local main1 = basalt.createFrame() -- Visible base frame on program start
local main2 = basalt.createFrame()
local main3 = basalt.createFrame()
main1:addButton()
:setPosition(2,2)
:setText("Switch")
:onClick(function()
main2:show() -- this function automatically "hides" the first one and shows the second one
end)
main2:addLabel()
:setText("We are currently on main2")
basalt.autoUpdate()
```

View File

@@ -0,0 +1,29 @@
# Basalt
## debug
Creates a label with some information on the main frame on the bottom left. When you click on that label it will open a log view for you. See it as the new print for debugging
You can also edit the default debug Label (change position, change color or whatever you want) by accessing the variable `basalt.debugLabel`
which returns the debug Label.
`basalt.debugFrame` and `basalt.debugList` are also available.
### Parameters
1. `...` (multiple parameters are possible, like print does)
### Usage
* Prints "Hello! ^-^" to the debug console
```lua
basalt.debug("Hello! ", "^-^")
```
* Changes the debug label's anchor
```lua
basalt.debugLabel:setAnchor("topLeft") -- default anchor is bottomLeft
basalt.debug("Hello!")
```

View File

@@ -0,0 +1,18 @@
# Basalt
## getActiveFrame
Returns the currently active/visible base frame.
### Returns
1. `frame` The current frame
### Usage
* Displays the active frame name in the debug console
```lua
local main = basalt.createFrame()
basalt.debug(basalt.getActiveFrame():getName()) -- returns the id
```

View File

@@ -0,0 +1,31 @@
# Basalt
## getFrame
Returns a base frame by the given id.
### Parameters
1. `string` id
### Returns
1. `frame` The frame with the supplied id.
### Usage
* Creates, fetches and shows the "myFirstFrame" object
```lua
local main = basalt.createFrame("firstBaseFrame")
local main2 = basalt.createFrame("secondBaseFrame")
main:addButton()
:setText("Show")
:onClick(function()
local frame2 = basalt.getFrame("secondBaseFrame")
if(frame2 ~= nil)then
frame2:show()
end
end)
basalt.autoUpdate()
```

View File

@@ -0,0 +1,18 @@
# Basalt
## basalt.getTheme
Returns the current base-theme. This base-theme can be set using setTheme.md.
A list of base-theme keys can be found [here](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua).
### Returns
1. `number` The color of the requested base-theme key.
### Usage
* Displays the color of the main background in the debug console
```lua
basalt.debug(basalt.getTheme("BasaltBG"))
```

View File

@@ -0,0 +1,26 @@
# Basalt
## getVariable
Returns a variable defined with [setVariable](objects/Basalt/setVariable)
### Returns
1. `variable` The variable stored
### Usage
* Displays the stored variable in the debug console
```lua
basalt.setVariable("abc", function()
basalt.debug("I got clicked")
return 1
end)
basalt.debug(basalt.getVariable("abc")()) -- Should debug log "I got clicked" and debug log 1 (which was returned from the function)
```
```xml
<button onClick="abc" text="Click me" />
```

View File

@@ -0,0 +1,17 @@
# Basalt
## getVersion
Returns the currently active/visible base frame.
### Returns
1. `string` The current version of Basalt
### Usage
* Displays the version of Basalt in the debug console
```lua
basalt.debug(basalt.getVersion()) -- Example: 1.6.2
```

View File

@@ -0,0 +1,28 @@
# Basalt
## isKeyDown
Checks if the user is currently holding a key
### Parameters
1. `number` key code (use the [keys table](https://tweaked.cc/module/keys.html) for that)
### Returns
1. `boolean` true or false
### Usage
* Shows a debug message with true or false if the left ctrl key is down, as soon as you click on the button.
```lua
local main = basalt.createFrame()
local aButton = mainFrame:addButton()
:setPosition(2,2)
:setText("Check Ctrl")
:onClick(function()
basalt.debug(basalt.isKeyDown(keys.leftCtrl))
end)
basalt.autoUpdate()
```

View File

@@ -0,0 +1,28 @@
# Basalt
## log
This writes something into a file. The main goal is to make debugging errors easier. Lets say you'r program is crashing and you don't know why, you could use basalt.log The log files will automatically removed after you start your program again.
### Parameters
1. `string` The text to write into the log file
2. `string` - optional (default: "Debug") - the type to write
### Usage
* Writes "Hello!" into the log file
```lua
basalt.log("Hello!")
```
This should result in there beeing a file called `basaltLog.txt`. In the file it should say `[Basalt][Debug]: Hello!`.
* Writes "Config file missing" into the log file, with warning as prefix.
```lua
basalt.log("Config file is missing", "WARNING")
```
This should result in there beeing a file called `basaltLog.txt`. In the file it should say `[Basalt][WARNING]: Config file is missing`.

View File

@@ -0,0 +1,21 @@
# Basalt
## onEvent
This is the top-level method to intercept an event before sending it to the object event handlers. If you use return false, the event is not passed to the event handlers.
### Parameters
1. `function` The function which should be called
### Usage
```lua
local basalt = require("basalt")
basalt.onEvent(function(event)
if(event=="terminate")then
return false
end
end)
```

View File

@@ -0,0 +1,37 @@
# Basalt
## removeFrame
Removes the base frame by it's id. **This only works for base-frames.**
### Parameters
1. `string` id - ID of the base-frame.
### Usage
* Removes the previously created frame with id "secondBaseFrame"
The frame id is gotten from a frame variable's `:getName()`
```lua
local main = basalt.createFrame("firstBaseFrame")
local main2 = basalt.createFrame("secondBaseFrame")
main:addButton()
:setText("Remove")
:onClick(function()
basalt.removeFrame(main2:getName())
end)
```
* Removes the previously created frame with id "secondBaseFrame", without frame stored in variable
The frame id is the frame's name
```lua
local main = basalt.createFrame("firstBaseFrame")
local main2 = basalt.createFrame("secondBaseFrame")
main:addButton()
:setText("Remove")
:onClick(function()
basalt.removeFrame("secondBaseFrame")
end)
```

View File

@@ -0,0 +1,36 @@
# Basalt
## schedule
Schedules a function which gets called in a coroutine. After the coroutine is finished it will get destroyed immediatly. It's something like threads, but with some limits.
**A guide can be found [here](/tips/logic).**
### Parameters
1. `function` a function which should get executed
### Returns
1. `function` it returns the function which you have to execute in order to start the coroutine
### Usage
* Creates a schedule which switches the color between red and gray
```lua
local mainFrame = basalt.createFrame()
local aButton = mainFrame:addButton():setText("Click me")
aButton:onClick(basalt.schedule(function(self)
self:setBackground(colors.red)
os.sleep(0.1)
self:setBackground(colors.gray)
os.sleep(0.1)
self:setBackground(colors.red)
os.sleep(0.1)
self:setBackground(colors.gray)
os.sleep(0.1)
self:setBackground(colors.red)
os.sleep(0.1)
self:setBackground(colors.gray)
end))
```

View File

@@ -0,0 +1,13 @@
# Basalt
## setActiveFrame
Sets what should be the active baseframe.
### Parameters
1. `frame` frame - The frame that should be the active base-frame.
### Usage
TODO

View File

@@ -0,0 +1,18 @@
# Basalt
## setMouseDragThrottle
Changes the drag throttle of all drag events. Default value is 50ms - which is 0.05s.
Instead of sending all mouse_drag events to the :onDrag handlers basalt sends every 0.05s (while dragging) the most recent drag event to all
drag handlers. If you need all drag events - just change the value to 0.
### Parameters
1. `number` A number in miliseconds.
### Usage
```lua
local basalt = require("basalt")
basalt.setMouseDragThrottle(0)
```

View File

@@ -0,0 +1,20 @@
# Basalt
## setMouseMoveThrottle
This feature is only available for [CraftOS-PC](https://www.craftos-pc.cc).
CraftOS-PC has a builtin mouse_move event, which is disabled by default. By using this method it will also enable the event for you. Remember - basalt does not disable the event after closing the program, which means the event stays active. If you want to disable the event please use config.set("mouse_move_throttle", -1) in your lua prompt or your program.
Sidenote: a very low amount can make the program laggy - because it litterally spams the mouse_move event. So use it carefully.
### Parameters
1. `number` A number in miliseconds.
### Usage
```lua
local basalt = require("basalt")
basalt.setMouseMoveThrottle(50)
```

View File

@@ -0,0 +1,21 @@
# Basalt
## 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)
### Parameters
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for a example
### Usage
* Sets the default theme of basalt.
```lua
basalt.setTheme({
ButtonBG = colors.yellow,
ButtonText = colors.red,
...,
})
```

View File

@@ -0,0 +1,25 @@
# Basalt
## setVariable
This stores a variable which you're able to access via xml. You are also able to add a function, which then gets called by object events created in XML.
### Parameters
1. `string` a key name
2. `any` any variable
### Usage
* Adds a function to basalt.
```lua
basalt.setVariable("clickMe", function()
basalt.debug("I got clicked")
end)
```
```xml
<button onClick="clickMe" text="Click me" />
```

View File

@@ -0,0 +1,21 @@
# Basalt
## stopUpdate / stop
Stops the automatic draw and event handler which got started by `basalt.autoUpdate()`.
`basalt.autoUpdate(false)` also does the same.
### Usage
* When the quit button is clicked, the button stops basalt's event listeners and draw handlers
```lua
local main = basalt.createFrame()
main:addButton()
:setPosition(2,2)
:setText("Stop Basalt!")
:onClick(function()
basalt.stopUpdate()
end)
basalt.autoUpdate()
```

View File

@@ -0,0 +1,24 @@
# Basalt
## update
Calls the draw and event handler once - this gives more flexibility about which events basalt should process. For example you could filter the terminate event.
Which means you have to pass the events into basalt.update.
### Parameters
1. `string` The event to be received
2. `...` Additional event variables to capture
### Usage
* Creates and starts a custom update cycle
```lua
local mainFrame = basalt.createFrame()
mainFrame:addButton():setPosition(2,2)
while true do
local ev = table.pack(os.pullEventRaw())
basalt.update(table.unpack(ev))
end
```

View File

@@ -1,73 +1,19 @@
Buttons are objects, which execute something by clicking on them.<br>
The button object is for creating buttons If you click on them, they should execute something. You decide what should happen when clicking on them.
Remember button also inherits from [Object](objects/Object.md)
[Object](objects/Object.md) methods also apply for buttons.
## setText
Sets the displayed button text
#### Parameters:
1. `string` the text the button should show
| | |
|---|---|
|[setText](objects/Button/setText.md)|Changes the button text
|[setHorizontalAlign](objects/Button/setHorizontalAlign.md)|Changes the horizontal text position
|[setVerticalAlign](objects/Button/setVerticalAlign.md)|Changes the vertical text position
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a button with "Click me!" as text.
```lua
local mainFrame = basalt.createFrame()
local button = mainFrame:addButton():setText("Click me!")
```
```xml
<button text="Click me!" />
```
## setHorizontalAlign
Sets the horizontal align of the button text
#### Parameters:
1. `string` the position as string ("left", "center", "right") - default is center.
#### Returns:
1. `object` The object in use
#### Usage:
* Sets the button's horizontal text align to right.
```lua
local mainFrame = basalt.createFrame()
local button = mainFrame:addButton()
:setText("Click me!")
:setHorizontalAlign("right")
```
```xml
<button text="Click me!" horizontalAlign="right" />
```
## setVerticalAlign
Sets the vertical align of the button text
#### Parameters:
1. `string` the position as string ("top", "center", "bottom") - default is center.
#### Returns:
1. `object` The object in use
#### Usage:
* Sets the button's horizontal text align to right and the vertical text align to bottom.
```lua
local mainFrame = basalt.createFrame()
local button = mainFrame:addButton()
:setText("Click me!")
:setHorizontalAlign("right")
:setVerticalAlign("bottom")
```
```xml
<button text="Click me!" horizontalAlign="right" verticalAlign="bottom" />
```
# Example
This is a example on how you would create a fully working button:
```lua
local mainFrame = basalt.createFrame()
local aButton = mainFrame:addButton():setText("Click")
local main = basalt.createFrame()
local aButton = main:addButton():setText("Click")
aButton:onClick(function(self,event,button,x,y)
if(event=="mouse_click")and(button==1)then
@@ -76,15 +22,15 @@ aButton:onClick(function(self,event,button,x,y)
end)
```
and this would be the xml way to do it:
and this would be the xml way:
```lua
local mainFrame = basalt.createFrame():addLayout("example.xml")
basalt.setVariable("buttonClick", function(self,event,button,x,y)
if(event=="mouse_click")and(button==1)then
basalt.debug("Left mousebutton got clicked!")
end
end)
local main = basalt.createFrame():addLayout("example.xml")
```
```xml
<button onClick="buttonClick" text="Click" />

View File

@@ -0,0 +1,20 @@
## setHorizontalAlign
Sets the horizontal align of the button text
#### Parameters:
1. `string` the position as string ("left", "center", "right") - default is center.
#### Returns:
1. `object` The object in use
#### Usage:
* Sets the button's horizontal text align to right.
```lua
local mainFrame = basalt.createFrame()
local button = mainFrame:addButton()
:setText("Click me!")
:setHorizontalAlign("right")
```
```xml
<button text="Click me!" horizontalAlign="right" />
```

View File

@@ -0,0 +1,17 @@
## setText
Sets the displayed button text
#### Parameters:
1. `string` the text the button should show
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a button with "Click me!" as text.
```lua
local mainFrame = basalt.createFrame()
local button = mainFrame:addButton():setText("Click me!")
```
```xml
<button text="Click me!" />
```

View File

@@ -0,0 +1,21 @@
## setVerticalAlign
Sets the vertical align of the button text
#### Parameters:
1. `string` the position as string ("top", "center", "bottom") - default is center.
#### Returns:
1. `object` The object in use
#### Usage:
* Sets the button's horizontal text align to right and the vertical text align to bottom.
```lua
local mainFrame = basalt.createFrame()
local button = mainFrame:addButton()
:setText("Click me!")
:setHorizontalAlign("right")
:setVerticalAlign("bottom")
```
```xml
<button text="Click me!" horizontalAlign="right" verticalAlign="bottom" />
```

View File

@@ -1,14 +1,17 @@
With checkbox objects the user can set a bool to true or false
With checkboxes the user can set a boolean to true or false by clicking on them.
Remember checkbox also inherits from [Object](objects/Object.md)
[Object](objects/Object.md) methods also apply for checkboxes.
| | |
|---|---|
|[setSymbol](objects/Checkbox/setSymbol.md)|Changes the symbol when checkbox is checked
A checkbox does not have any custom methods. All required methods are provided by the base [object](objects/Object.md) class.
# Example
This is how you would create a event which gets fired as soon as the value gets changed:
```lua
local mainFrame = basalt.createFrame()
local aCheckbox = mainFrame:addCheckbox()
local main = basalt.createFrame()
local aCheckbox = main:addCheckbox()
local function checkboxChange(self)
local checked = self:getValue()
@@ -19,7 +22,7 @@ aCheckbox:onChange(checkboxChange)
also possible via xml:
```lua
local mainFrame = basalt.createFrame():addLayout("example.xml")
local main = basalt.createFrame():addLayout("example.xml")
basalt.setVariable("checkboxChange", function(self)
local checked = self:getValue()

Some files were not shown because too many files have changed in this diff Show More