135 Commits
v1.0 ... v1.6.0

Author SHA1 Message Date
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
Robert Jelic
21ff14cf31 Update installer.md 2022-07-28 13:30:35 +02:00
Robert Jelic
8dc84fa241 Update design.md 2022-07-27 17:20:33 +02:00
Robert Jelic
90b450371a Update design.md 2022-07-27 16:56:53 +02:00
Robert Jelic
3e6fae3748 Merge pull request #20 from Erb3/master
Issue Templates
2022-07-27 16:30:33 +02:00
Erlend
c09b778853 Merge branch 'Pyroxenium:master' into master 2022-07-27 16:26:58 +02:00
Erlend
49d4b20ba6 Rename bug report form 2022-07-27 16:25:59 +02:00
Erlend
efcf87e26e Bug report form test 1 2022-07-27 16:24:36 +02:00
Robert Jelic
d30dda60a0 Update basaltPackageManager.lua 2022-07-27 16:18:06 +02:00
Robert Jelic
83a27fbd09 Update Basalt.md 2022-07-27 13:22:04 +02:00
Robert Jelic
763d30a541 fixed bad typing on schedule 2022-07-27 13:21:02 +02:00
Erlend
274aa5babc Add config.yml to issue templates 2022-07-27 12:49:35 +02:00
Erlend
332f19cf8d Rephrase a word on docs issue template 2022-07-27 12:42:45 +02:00
Erlend
a0e17cd425 Add documentation issue templates 2022-07-27 12:41:38 +02:00
Erlend
12e374dcd0 Add feature issue template 2022-07-27 12:40:26 +02:00
Erlend
d0ed3b9e5e Create bug report template 2022-07-27 12:38:01 +02:00
Robert Jelic
5d5df85e8b Update main.lua 2022-07-27 12:37:45 +02:00
Robert Jelic
bb77a42f91 Update basaltPackageManager.lua 2022-07-27 10:06:15 +02:00
Robert Jelic
26b2f5da56 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-07-27 02:48:39 +02:00
Robert Jelic
5bc66a5027 github token
added github token
2022-07-27 02:48:36 +02:00
Robert Jelic
69cd3686ea Update README.md 2022-07-26 00:02:10 +02:00
Robert Jelic
c22ed92d7d Update Home.md 2022-07-26 00:00:22 +02:00
Robert Jelic
168ffcf73c Update main.lua 2022-07-25 23:50:20 +02:00
Robert Jelic
5586eb6fb8 Create basaltPreview2.gif 2022-07-25 22:07:24 +02:00
Robert Jelic
a10cc6eda2 added new preview 2022-07-25 21:39:23 +02:00
Robert Jelic
2638ed84b8 Create discordCC.lua 2022-07-25 21:35:54 +02:00
Robert Jelic
77046d9bce Update installer.md 2022-07-25 21:15:43 +02:00
Robert Jelic
f2e2e773f5 bugfix + changes
- added getMinScroll and getMaxScroll for frames
- fixed a small bug with dynamicvalues
- textfield got a :clear() function
- improved the focus system
- fixed a bug with dynamic values getting into a infinite loop
2022-07-25 21:09:37 +02:00
Robert Jelic
738ad2576e bugfix
- some offset bugfixes
- reworked dynamic values - % got removed for now, now you are able to use parent.w*0.8 instead of 80% - but you are also able to use objectid.x/y/w/h
2022-07-23 21:57:34 +02:00
Robert Jelic
ea36b124be Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-07-18 16:46:01 +02:00
Robert Jelic
9d10e95fae docs 2022-07-18 16:45:59 +02:00
Robert Jelic
dbfa91dc28 Update Basalt.md 2022-07-18 14:16:29 +02:00
Robert Jelic
6ab840cb1c Update Basalt.md 2022-07-18 14:11:37 +02:00
Robert Jelic
8157c025ea docs again 2022-07-18 13:58:43 +02:00
Robert Jelic
af34fa1a18 docs 2022-07-17 23:17:28 +02:00
Robert Jelic
dfc53658f1 Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-07-17 22:39:13 +02:00
Robert Jelic
01412b4c55 docs 2022-07-17 22:37:32 +02:00
Robert Jelic
3107a7adb8 Update Frame.md 2022-07-17 20:24:09 +02:00
Robert Jelic
3819c14c08 Update README.md 2022-07-17 19:33:13 +02:00
Robert Jelic
8242f7868d Delete geometric.lua 2022-07-17 19:25:17 +02:00
Robert Jelic
f6cdd02270 Delete Lerp.lua 2022-07-17 19:24:58 +02:00
Robert Jelic
4d66e2778f Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-07-17 19:20:06 +02:00
Robert Jelic
b940ef7154 added new features
-remade animation
-added xml support
-finished dynamic values
-added new object: graphic
-added themes for frames
-textfield got some basic improvements to create coding editors
2022-07-17 19:20:02 +02:00
Robert Jelic
3e89e73c64 Update Basalt.md 2022-07-12 22:33:53 +02:00
Robert Jelic
fca756888c Update Basalt.md 2022-07-12 22:30:29 +02:00
Robert Jelic
3b33bb7009 small path fix 2022-07-10 19:18:58 +02:00
Robert Jelic
e98c552fa1 Update Basalt.md 2022-07-09 06:35:30 +02:00
Robert Jelic
21b261332d Update Basalt.md 2022-07-08 22:33:37 +02:00
Robert Jelic
f16a32da1a Update Basalt.md 2022-07-08 22:32:22 +02:00
Robert Jelic
842352b473 Update Basalt.md 2022-07-08 22:31:50 +02:00
Robert Jelic
5505e4f3e8 Update main.lua 2022-07-08 21:23:40 +02:00
Robert Jelic
22274b402e Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-07-08 21:06:25 +02:00
Robert Jelic
c6d7929741 small bugfix 2022-07-08 21:06:12 +02:00
Robert Jelic
5bd827618d bugfix
fixed bug where bpm was always creating a single file version
2022-07-08 19:53:15 +02:00
Robert Jelic
b78bf92cca Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-07-08 19:46:33 +02:00
Robert Jelic
cbdf439791 fixed monitors, added setIndex4scrollbars, added dynamic values 2022-07-08 19:46:28 +02:00
Robert Jelic
022bef3b03 Update README.md 2022-07-08 19:43:53 +02:00
Robert Jelic
5f9060dae3 Update basaltPreview.lua 2022-07-06 20:52:16 +02:00
Robert Jelic
b9fd59d961 Update progressBarEnergyExample.lua 2022-07-06 20:51:58 +02:00
Robert Jelic
716c946b96 Update installer.md 2022-07-06 20:50:55 +02:00
Robert Jelic
02b4eb9f75 Update otherEvents.md 2022-07-06 20:36:36 +02:00
Robert Jelic
8945220ac3 Update keyEvents.md 2022-07-06 20:35:51 +02:00
Robert Jelic
7c49917087 Update mouseEvents.md 2022-07-06 20:35:22 +02:00
Robert Jelic
6b2f1ea946 Update Basalt.md 2022-07-06 20:30:16 +02:00
Robert Jelic
4bbdb3ba31 Update basaltPreview.lua 2022-07-06 20:27:22 +02:00
Robert Jelic
79bea8c094 Update progressBarEnergyExample.lua 2022-07-06 20:26:53 +02:00
Robert Jelic
8665eed03e changed how project will be installed from now on 2022-07-06 20:10:40 +02:00
Robert Jelic
9f5b917f87 Delete basaltInstaller.lua 2022-07-06 20:09:14 +02:00
Robert Jelic
975080bc63 Update Quick-Start.md 2022-07-06 20:08:47 +02:00
Robert Jelic
0f77621548 Update Animation.lua 2022-07-06 19:11:41 +02:00
Robert Jelic
36b2f08ad6 finished package manager 2022-07-05 23:02:38 +02:00
Robert Jelic
c16a8afb01 Update basaltPackager.lua 2022-07-05 22:26:50 +02:00
Robert Jelic
436d85dc52 Delete projectFiles.txt 2022-07-04 20:59:33 +02:00
Robert Jelic
8ad1a690ee Update projectFiles.txt 2022-07-03 23:30:24 +02:00
Robert Jelic
f67dda574d Merge branch 'master' of https://github.com/Pyroxenium/Basalt 2022-07-03 21:48:54 +02:00
Robert Jelic
5efda94244 added basaltpackagemanager(not finished), packager and installer 2022-07-03 21:48:37 +02:00
Robert Jelic
e90d907c1e Delete BasaltPackager.lua 2022-07-03 21:47:45 +02:00
Robert Jelic
28462f0f46 Update init.lua 2022-07-03 21:21:22 +02:00
Robert Jelic
1ad5d85a40 Update init.lua 2022-07-03 21:20:57 +02:00
Robert Jelic
02ed64555f Update README.md 2022-07-03 21:19:58 +02:00
Robert Jelic
c00d466b10 changed the projects filesystem to use require() instead of loadfile()
currently preparing for a better package manager/installer
2022-07-03 21:19:01 +02:00
Robert Jelic
1f18db9965 Update Thread.md 2022-07-02 22:49:26 +02:00
Robert Jelic
ae9a6ac605 Update Textfield.md 2022-07-02 22:39:12 +02:00
Robert Jelic
5a4e1f3b61 Update Program.md 2022-07-02 22:07:02 +02:00
Robert Jelic
95a4164755 Update Program.md 2022-07-02 21:32:20 +02:00
Robert Jelic
7e0a61a3e9 Update Basalt.md 2022-06-27 23:18:29 +02:00
Robert Jelic
7082258a9e Update Label.md 2022-06-26 19:49:04 +02:00
Robert Jelic
974cad1466 Update Input.md 2022-06-26 19:17:58 +02:00
Robert Jelic
add4feab3a Update Image.md 2022-06-26 18:59:02 +02:00
Robert Jelic
06c6e86308 Update Menubar.md 2022-06-26 18:23:30 +02:00
Robert Jelic
a34b7270ec Update Dropdown.md 2022-06-26 18:23:04 +02:00
Robert Jelic
3d71041aa2 Update Checkbox.md 2022-06-26 17:52:08 +02:00
Robert Jelic
d324912eb0 Update Button.md 2022-06-26 17:43:21 +02:00
Robert Jelic
6c123f4cc5 Update mouseEvents.md 2022-06-26 09:25:53 +02:00
289 changed files with 13319 additions and 15123 deletions

37
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,37 @@
---
name: Bug report
about: Bug reports for Basalt
title: 'bug: [TITLE]'
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
**Checklist**
[ ] I am running the latest version.
Tick the box if you are running the latest version!

View File

@@ -0,0 +1,45 @@
name: Bug Report w/ BETA form
description: Report a bug for Basalt (Using BETA form)!
title: "bug: [TITLE]"
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?
placeholder: Tell us what you see!
value: "A bug happened!"
validations:
required: true
- type: dropdown
id: ccversion
attributes:
label: Computercraft client
description: What ComputerCraft client are you using?
options:
- Ingame (Default)
- CraftOSPC
- CCemux
- CopyCat
- other
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output, for example the error. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: checkboxes
id: latest
attributes:
label: Latest Basalt Version
description: We only provide support for the latest version of Basalt!
options:
- label: I use the latest stable version
required: true

4
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
contact_links:
- name: Community Support
url: https://discord.gg/yNNnmBVBpE
about: Please ask and answer questions here.

20
.github/ISSUE_TEMPLATE/docs.md vendored Normal file
View File

@@ -0,0 +1,20 @@
---
name: Documentation
about: Anything that you think is wrong about the documentation.
title: 'docs: [TITLE]'
labels: documentation
assignees: ''
---
** Where? **
Please describe what you want changed. Screenshot / Quotes
** Possible solution **
Please describe a possible solution.
** Others **
Anything else you want to say?
** Checklist **
[ ] I am looking at the latest version of the docs.

20
.github/ISSUE_TEMPLATE/feature.md vendored Normal file
View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for Basalt
title: 'feature: [TITLE]'
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

1110
Basalt/Frame.lua Normal file

File diff suppressed because it is too large Load Diff

858
Basalt/Object.lua Normal file
View File

@@ -0,0 +1,858 @@
local basaltEvent = require("basaltEvent")
local utils = require("utils")
local split = utils.splitString
local numberFromString = utils.numberFromString
local xmlValue = utils.getValueFromXML
return function(name)
-- Base object
local objectType = "Object" -- not changeable
local object = {}
local zIndex = 1
local value
local anchor = "topLeft"
local ignOffset = false
local isVisible = true
local initialized = false
local shadow = false
local borderColors = {
left = false,
right = false,
top = false,
bottom = false
}
local shadowColor = colors.black
local isEnabled = true
local isDragging = false
local dragStartX, dragStartY, dragXOffset, dragYOffset = 0, 0, 0, 0
local draw = true
local activeEvents = {}
local eventSystem = basaltEvent()
object = {
x = 1,
y = 1,
width = 1,
height = 1,
bgColor = colors.black,
bgSymbol = " ",
bgSymbolColor = colors.black,
fgColor = colors.white,
transparentColor = false,
name = name or "Object",
parent = nil,
show = function(self)
isVisible = true
self:updateDraw()
return self
end;
hide = function(self)
isVisible = false
self:updateDraw()
return self
end;
enable = function(self)
isEnabled = true
return self
end;
disable = function(self)
isEnabled = false
return self
end;
generateXMLEventFunction = function(self, func, val)
local createF = function(str)
if(str:sub(1,1)=="#")then
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
if(o~=nil)and(o.internalObjetCall~=nil)then
func(self,function()o:internalObjetCall()end)
end
else
func(self,self:getBaseFrame():getVariable(str))
end
end
if(type(val)=="string")then
createF(val)
elseif(type(val)=="table")then
for k,v in pairs(val)do
createF(v)
end
end
return self
end,
setValuesByXMLData = function(self, data)
local baseFrame = self:getBaseFrame()
if(xmlValue("x", data)~=nil)then self:setPosition(xmlValue("x", data), self.y) end
if(xmlValue("y", data)~=nil)then self:setPosition(self.x, xmlValue("y", data)) end
if(xmlValue("width", data)~=nil)then self:setSize(xmlValue("width", data), self.height) end
if(xmlValue("height", data)~=nil)then self:setSize(self.width, xmlValue("height", data)) end
if(xmlValue("bg", data)~=nil)then self:setBackground(colors[xmlValue("bg", data)]) end
if(xmlValue("fg", data)~=nil)then self:setForeground(colors[xmlValue("fg", data)]) end
if(xmlValue("value", data)~=nil)then self:setValue(colors[xmlValue("value", data)]) end
if(xmlValue("visible", data)~=nil)then if(xmlValue("visible", data))then self:show() else self:hide() end end
if(xmlValue("enabled", data)~=nil)then if(xmlValue("enabled", data))then self:enable() else self:disable() end end
if(xmlValue("zIndex", data)~=nil)then self:setZIndex(xmlValue("zIndex", data)) end
if(xmlValue("anchor", data)~=nil)then self:setAnchor(xmlValue("anchor", data)) end
if(xmlValue("shadowColor", data)~=nil)then self:setShadow(colors[xmlValue("shadowColor", data)]) end
if(xmlValue("border", data)~=nil)then self:setBorder(colors[xmlValue("border", data)]) end
if(xmlValue("borderLeft", data)~=nil)then borderColors["left"] = xmlValue("borderLeft", data) end
if(xmlValue("borderTop", data)~=nil)then borderColors["top"] = xmlValue("borderTop", data) end
if(xmlValue("borderRight", data)~=nil)then borderColors["right"] = xmlValue("borderRight", data) end
if(xmlValue("borderBottom", data)~=nil)then borderColors["bottom"] = xmlValue("borderBottom", data) end
if(xmlValue("borderColor", data)~=nil)then self:setBorder(colors[xmlValue("borderColor", data)]) end
if(xmlValue("ignoreOffset", data)~=nil)then if(xmlValue("ignoreOffset", data))then self:ignoreOffset(true) end end
if(xmlValue("onClick", data)~=nil)then self:generateXMLEventFunction(self.onClick, xmlValue("onClick", data)) end
if(xmlValue("onClickUp", data)~=nil)then self:generateXMLEventFunction(self.onClickUp, xmlValue("onClickUp", data)) end
if(xmlValue("onScroll", data)~=nil)then self:generateXMLEventFunction(self.onScroll, xmlValue("onScroll", data)) end
if(xmlValue("onDrag", data)~=nil)then self:generateXMLEventFunction(self.onDrag, xmlValue("onDrag", data)) end
if(xmlValue("onKey", data)~=nil)then self:generateXMLEventFunction(self.onKey, xmlValue("onKey", data)) end
if(xmlValue("onKeyUp", data)~=nil)then self:generateXMLEventFunction(self.onKeyUp, xmlValue("onKeyUp", data)) end
if(xmlValue("onChange", data)~=nil)then self:generateXMLEventFunction(self.onChange, xmlValue("onChange", data)) end
if(xmlValue("onResize", data)~=nil)then self:generateXMLEventFunction(self.onResize, xmlValue("onResize", data)) end
if(xmlValue("onReposition", data)~=nil)then self:generateXMLEventFunction(self.onReposition, xmlValue("onReposition", data)) end
if(xmlValue("onEvent", data)~=nil)then self:generateXMLEventFunction(self.onEvent, xmlValue("onEvent", data)) end
if(xmlValue("onGetFocus", data)~=nil)then self:generateXMLEventFunction(self.onGetFocus, xmlValue("onGetFocus", data)) end
if(xmlValue("onLoseFocus", data)~=nil)then self:generateXMLEventFunction(self.onLoseFocus, xmlValue("onLoseFocus", data)) end
self:updateDraw()
return self
end,
isVisible = function(self)
return isVisible
end;
setFocus = function(self)
if (self.parent ~= nil) then
self.parent:setFocusedObject(self)
end
return self
end;
setZIndex = function(self, index)
zIndex = index
if (self.parent ~= nil) then
self.parent:removeObject(self)
self.parent:addObject(self)
self:updateEventHandlers()
end
return self
end,
updateEventHandlers = function(self)
for k,v in pairs(activeEvents)do
if(v)then
self.parent:addEvent(k, self)
end
end
end,
getZIndex = function(self)
return zIndex;
end;
getType = function(self)
return objectType
end;
getName = function(self)
return self.name
end;
remove = function(self)
if (self.parent ~= nil) then
self.parent:removeObject(self)
end
self:updateDraw()
return self
end;
setParent = function(self, frame)
if (frame.getType ~= nil and frame:getType() == "Frame") then
self:remove()
frame:addObject(self)
if (self.draw) then
self:show()
end
end
return self
end;
setValue = function(self, _value)
if (value ~= _value) then
value = _value
self:updateDraw()
self:valueChangedHandler()
end
return self
end;
getValue = function(self)
return value
end;
getDraw = function(self)
return draw
end;
updateDraw = function(self, change)
draw = change
if(change == nil)then draw = true end
if(draw)then if(self.parent~=nil)then self.parent:updateDraw() end end
return self
end;
getEventSystem = function(self)
return eventSystem
end;
getParent = function(self)
return self.parent
end;
setPosition = function(self, xPos, yPos, rel)
if(type(xPos)=="number")then
self.x = rel and self:getX()+xPos or xPos
end
if(type(yPos)=="number")then
self.y = rel and self:getY()+yPos or yPos
end
if(self.parent~=nil)then
if(type(xPos)=="string")then
self.x = self.parent:newDynamicValue(self, xPos)
end
if(type(yPos)=="string")then
self.y = self.parent:newDynamicValue(self, yPos)
end
self.parent:recalculateDynamicValues()
end
eventSystem:sendEvent("basalt_reposition", self)
self:updateDraw()
return self
end;
getX = function(self)
return type(self.x) == "number" and self.x or math.floor(self.x[1]+0.5)
end;
getY = function(self)
return type(self.y) == "number" and self.y or math.floor(self.y[1]+0.5)
end;
getPosition = function(self)
return self:getX(), self:getY()
end;
getVisibility = function(self)
return isVisible
end;
setVisibility = function(self, _isVisible)
isVisible = _isVisible or not isVisible
self:updateDraw()
return self
end;
setSize = function(self, width, height, rel)
if(type(width)=="number")then
self.width = rel and self.width+width or width
end
if(type(height)=="number")then
self.height = rel and self.height+height or height
end
if(self.parent~=nil)then
if(type(width)=="string")then
self.width = self.parent:newDynamicValue(self, width)
end
if(type(height)=="string")then
self.height = self.parent:newDynamicValue(self, height)
end
self.parent:recalculateDynamicValues()
end
eventSystem:sendEvent("basalt_resize", self)
self:updateDraw()
return self
end;
getHeight = function(self)
return type(self.height) == "number" and self.height or math.floor(self.height[1]+0.5)
end;
getWidth = function(self)
return type(self.width) == "number" and self.width or math.floor(self.width[1]+0.5)
end;
getSize = function(self)
return self:getWidth(), self:getHeight()
end;
calculateDynamicValues = function(self)
if(type(self.width)=="table")then self.width:calculate() end
if(type(self.height)=="table")then self.height:calculate() end
if(type(self.x)=="table")then self.x:calculate() end
if(type(self.y)=="table")then self.y:calculate() end
self:updateDraw()
return self
end,
setBackground = function(self, color, symbol, symbolCol)
self.bgColor = color or false
self.bgSymbol = symbol or (self.bgColor~=false and self.bgSymbol or false)
self.bgSymbolColor = symbolCol or self.bgSymbolColor
self:updateDraw()
return self
end;
setTransparent = function(self, color)
self.transparentColor = color or false
self.bgSymbol = false
self.bgSymbolColor = false
self:updateDraw()
return self
end;
getBackground = function(self)
return self.bgColor
end;
setForeground = function(self, color)
self.fgColor = color or false
self:updateDraw()
return self
end;
getForeground = function(self)
return self.fgColor
end;
setShadow = function(self, color)
if(color==false)then
shadow = false
else
shadowColor = color
shadow = true
end
self:updateDraw()
return self
end;
isShadowActive = function(self)
return shadow;
end;
setBorder = function(self, ...)
if(...~=nil)then
local t = {...}
for k,v in pairs(t)do
if(v=="left")or(#t==1)then
borderColors["left"] = t[1]
end
if(v=="top")or(#t==1)then
borderColors["top"] = t[1]
end
if(v=="right")or(#t==1)then
borderColors["right"] = t[1]
end
if(v=="bottom")or(#t==1)then
borderColors["bottom"] = t[1]
end
end
end
self:updateDraw()
return self
end;
getBorder = function(self, side)
if(side=="left")then
return borderLeft;
end
if(side=="top")then
return borderTop;
end
if(side=="right")then
return borderRight;
end
if(side=="bottom")then
return borderBottom;
end
end;
draw = function(self)
if (isVisible)then
if(self.parent~=nil)then
local x, y = self:getAnchorPosition()
local w,h = self:getSize()
local wP,hP = self.parent:getSize()
if(x+w<1)or(x>wP)or(y+h<1)or(y>hP)then return false end
if(self.transparentColor~=false)then
self.parent:drawForegroundBox(x, y, w, h, self.transparentColor)
end
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(x, y, w, h, self.bgColor)
end
if(self.bgSymbol~=false)then
self.parent:drawTextBox(x, y, w, h, self.bgSymbol)
if(self.bgSymbol~=" ")then
self.parent:drawForegroundBox(x, y, w, h, self.bgSymbolColor)
end
end
if(shadow)then
self.parent:drawBackgroundBox(x+1, y+h, w, 1, shadowColor)
self.parent:drawBackgroundBox(x+w, y+1, 1, h, shadowColor)
self.parent:drawForegroundBox(x+1, y+h, w, 1, shadowColor)
self.parent:drawForegroundBox(x+w, y+1, 1, h, shadowColor)
end
if(borderColors["left"]~=false)then
self.parent:drawTextBox(x-1, y, 1, h, "\149")
self.parent:drawBackgroundBox(x-1, y, 1, h, borderColors["left"])
self.parent:drawForegroundBox(x-1, y, 1, h, self.parent.bgColor)
end
if(borderColors["left"]~=false)and(borderColors["top"]~=false)then
self.parent:drawTextBox(x-1, y-1, 1, 1, "\151")
self.parent:drawBackgroundBox(x-1, y-1, 1, 1, borderColors["left"])
self.parent:drawForegroundBox(x-1, y-1, 1, 1, self.parent.bgColor)
end
if(borderColors["top"]~=false)then
self.parent:drawTextBox(x, y-1, w, 1, "\131")
self.parent:drawBackgroundBox(x, y-1, w, 1, borderColors["top"])
self.parent:drawForegroundBox(x, y-1, w, 1, self.parent.bgColor)
end
if(borderColors["top"]~=false)and(borderColors["right"]~=false)then
self.parent:drawTextBox(x+w, y-1, 1, 1, "\148")
self.parent:drawForegroundBox(x+w, y-1, 1, 1, borderColors["right"])
end
if(borderColors["right"]~=false)then
self.parent:drawTextBox(x+w, y, 1, h, "\149")
self.parent:drawForegroundBox(x+w, y, 1, h, borderColors["right"])
end
if(borderColors["right"]~=false)and(borderColors["bottom"]~=false)then
self.parent:drawTextBox(x+w, y+h, 1, 1, "\129")
self.parent:drawForegroundBox(x+w, y+h, 1, 1, borderColors["right"])
end
if(borderColors["bottom"]~=false)then
self.parent:drawTextBox(x, y+h, w, 1, "\131")
self.parent:drawForegroundBox(x, y+h, w, 1, borderColors["bottom"])
end
if(borderColors["bottom"]~=false)and(borderColors["left"]~=false)then
self.parent:drawTextBox(x-1, y+h, 1, 1, "\130")
self.parent:drawForegroundBox(x-1, y+h, 1, 1, borderColors["left"])
end
end
draw = false
return true
end
return false
end;
getAbsolutePosition = function(self, x, y)
-- relative position to absolute position
if (x == nil) or (y == nil) then
x, y = self:getAnchorPosition()
end
if (self.parent ~= nil) then
local fx, fy = self.parent:getAbsolutePosition()
x = fx + x - 1
y = fy + y - 1
end
return x, y
end;
getAnchorPosition = function(self, x, y, ignOff)
if (x == nil) then
x = self:getX()
end
if (y == nil) then
y = self:getY()
end
if(self.parent~=nil)then
local pw,ph = self.parent:getSize()
if (anchor == "top") then
x = math.floor(pw/2) + x - 1
elseif(anchor == "topRight") then
x = pw + x - 1
elseif(anchor == "right") then
x = pw + x - 1
y = math.floor(ph/2) + y - 1
elseif(anchor == "bottomRight") then
x = pw + x - 1
y = ph + y - 1
elseif(anchor == "bottom") then
x = math.floor(pw/2) + x - 1
y = ph + y - 1
elseif(anchor == "bottomLeft") then
y = ph + y - 1
elseif(anchor == "left") then
y = math.floor(ph/2) + y - 1
elseif(anchor == "center") then
x = math.floor(pw/2) + x - 1
y = math.floor(ph/2) + y - 1
end
local xO, yO = self.parent:getOffsetInternal()
if not(ignOffset or ignOff) then
return x+xO, y+yO
end
end
return x, y
end;
ignoreOffset = function(self, ignore)
ignOffset = ignore
if(ignore==nil)then ignOffset = true end
return self
end;
getBaseFrame = function(self)
if(self.parent~=nil)then
return self.parent:getBaseFrame()
end
return self
end;
setAnchor = function(self, newAnchor)
anchor = newAnchor
self:updateDraw()
return self
end;
getAnchor = function(self)
return anchor
end;
onChange = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("value_changed", v)
end
end
return self
end;
onClick = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_click", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("mouse_click", self)
activeEvents["mouse_click"] = true
end
return self
end;
onClickUp = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_up", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("mouse_up", self)
activeEvents["mouse_up"] = true
end
return self
end;
onScroll = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_scroll", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("mouse_scroll", self)
activeEvents["mouse_scroll"] = true
end
return self
end;
onDrag = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("mouse_drag", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("mouse_drag", self)
activeEvents["mouse_drag"] = true
self.parent:addEvent("mouse_click", self)
activeEvents["mouse_click"] = true
self.parent:addEvent("mouse_up", self)
activeEvents["mouse_up"] = true
end
return self
end;
onEvent = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("other_event", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("other_event", self)
activeEvents["other_event"] = true
end
return self
end;
onKey = function(self, ...)
if(isEnabled)then
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("key", v)
self:registerEvent("char", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("key", self)
self.parent:addEvent("char", self)
activeEvents["key"] = true
activeEvents["char"] = true
end
end
return self
end;
onResize = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("basalt_resize", v)
end
end
return self
end;
onReposition = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("basalt_reposition", v)
end
end
return self
end;
onKeyUp = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("key_up", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("key_up", self)
activeEvents["key_up"] = true
end
return self
end;
isFocused = function(self)
if (self.parent ~= nil) then
return self.parent:getFocusedObject() == self
end
return false
end;
onGetFocus = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("get_focus", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("mouse_click", self)
activeEvents["mouse_click"] = true
end
return self
end;
onLoseFocus = function(self, ...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
self:registerEvent("lose_focus", v)
end
end
if(self.parent~=nil)then
self.parent:addEvent("mouse_click", self)
activeEvents["mouse_click"] = true
end
return self
end;
registerEvent = function(self, event, func)
return eventSystem:registerEvent(event, func)
end;
removeEvent = function(self, event, index)
return eventSystem:removeEvent(event, index)
end;
sendEvent = function(self, event, ...)
return eventSystem:sendEvent(event, self, ...)
end;
isCoordsInObject = function(self, x, y)
if(isVisible)and(isEnabled)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) then
return true
end
end
return false
end,
mouseHandler = function(self, button, x, y, isMon)
if(self:isCoordsInObject(x, y))then
local val = eventSystem:sendEvent("mouse_click", self, "mouse_click", button, x, y, isMon)
if(val==false)then return false end
if(self.parent~=nil)then
self.parent:setFocusedObject(self)
end
isDragging = true
dragStartX, dragStartY = x, y
return true
end
return false
end,
mouseUpHandler = function(self, button, x, y)
isDragging = false
if(self:isCoordsInObject(x, y))then
local val = eventSystem:sendEvent("mouse_up", self, "mouse_up", button, x, y)
if(val==false)then return false end
return true
end
return false
end,
dragHandler = function(self, button, x, y)
if(isDragging)then
local xO, yO, parentX, parentY = 0, 0, 1, 1
if (self.parent ~= nil) then
xO, yO = self.parent:getOffsetInternal()
xO = xO < 0 and math.abs(xO) or -xO
yO = yO < 0 and math.abs(yO) or -yO
parentX, parentY = self.parent:getAbsolutePosition(self.parent:getAnchorPosition())
end
local dX, dY = x + dragXOffset - (parentX - 1) + xO, y + dragYOffset - (parentY - 1) + yO
local val = eventSystem:sendEvent("mouse_drag", self, button, dX, dY, dragStartX-x, dragStartY-y, x, y)
local objX, objY = self:getAbsolutePosition(self:getAnchorPosition())
dragStartX, dragStartY = x, y
if(val~=nil)then return val end
if(self.parent~=nil)then
self.parent:setFocusedObject(self)
end
return true
end
if(self:isCoordsInObject(x, y))then
local objX, objY = self:getAbsolutePosition(self:getAnchorPosition())
dragStartX, dragStartY = x, y
dragXOffset, dragYOffset = objX - x, objY - y
end
return false
end,
scrollHandler = function(self, dir, x, y)
if(self:isCoordsInObject(x, y))then
local val = eventSystem:sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y)
if(val==false)then return false end
if(self.parent~=nil)then
self.parent:setFocusedObject(self)
end
return true
end
return false
end,
keyHandler = function(self, key, isHolding)
if(isEnabled)and(isVisible)then
if (self:isFocused()) then
local val = eventSystem:sendEvent("key", self, "key", key, isHolding)
if(val==false)then return false end
return true
end
end
return false
end;
keyUpHandler = function(self, key)
if(isEnabled)and(isVisible)then
if (self:isFocused()) then
local val = eventSystem:sendEvent("key_up", self, "key_up", key)
if(val==false)then return false end
return true
end
end
return false
end;
charHandler = function(self, char)
if(isEnabled)and(isVisible)then
if (self:isFocused()) then
local val = eventSystem:sendEvent("char", self, "char", char)
if(val==false)then return false end
return true
end
end
return false
end,
valueChangedHandler = function(self)
eventSystem:sendEvent("value_changed", self, value)
end;
eventHandler = function(self, event, p1, p2, p3, p4)
local val = eventSystem:sendEvent("other_event", self, event, p1, p2, p3, p4)
if(val~=nil)then return val end
return true
end;
getFocusHandler = function(self)
local val = eventSystem:sendEvent("get_focus", self)
if(val~=nil)then return val end
return true
end;
loseFocusHandler = function(self)
isDragging = false
local val = eventSystem:sendEvent("lose_focus", self)
if(val~=nil)then return val end
return true
end;
init = function(self)
if(self.parent~=nil)then
for k,v in pairs(activeEvents)do
if(v)then
self.parent:addEvent(k, self)
end
end
end
if not(initialized)then
initialized = true
return true
end
end
}
object.__index = object
return object
end

10
Basalt/init.lua Normal file
View File

@@ -0,0 +1,10 @@
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")
local Basalt = require("main")
package.path = defaultPath
return Basalt

View File

@@ -1,5 +1,9 @@
local function basaltDrawHelper(drawTerm)
local terminal = drawTerm
local tHex = require("tHex")
local sub,rep = string.sub,string.rep
return function(drawTerm)
local terminal = drawTerm or term.current()
local mirrorTerm
local width, height = terminal.getSize()
local cacheT = {}
local cacheBG = {}
@@ -13,17 +17,18 @@ local function basaltDrawHelper(drawTerm)
local emptyColorLines = {}
local function createEmptyLines()
emptySpaceLine = (" "):rep(width)
emptySpaceLine = rep(" ", width)
for n = 0, 15 do
local nColor = 2 ^ n
local sHex = tHex[nColor]
emptyColorLines[nColor] = sHex:rep(width)
emptyColorLines[nColor] = rep(sHex, width)
end
end
----
createEmptyLines()
local function recreateWindowArray()
createEmptyLines()
local emptyText = emptySpaceLine
local emptyFG = emptyColorLines[colors.white]
local emptyBG = emptyColorLines[colors.black]
@@ -122,6 +127,14 @@ local function basaltDrawHelper(drawTerm)
end
local drawHelper = {
setSize = function(w, h)
width, height = w, h
recreateWindowArray()
end,
setMirror = function(mirror)
mirrorTerm = mirror
end,
setBG = function(x, y, colorStr)
setBG(x, y, colorStr)
end;
@@ -136,25 +149,29 @@ local function basaltDrawHelper(drawTerm)
drawBackgroundBox = function(x, y, width, height, bgCol)
for n = 1, height do
setBG(x, y + (n - 1), tHex[bgCol]:rep(width))
setBG(x, y + (n - 1), rep(tHex[bgCol], width))
end
end;
drawForegroundBox = function(x, y, width, height, fgCol)
for n = 1, height do
setFG(x, y + (n - 1), tHex[fgCol]:rep(width))
setFG(x, y + (n - 1) ,rep(tHex[fgCol], width))
end
end;
drawTextBox = function(x, y, width, height, symbol)
for n = 1, height do
setText(x, y + (n - 1), symbol:rep(width))
setText(x, y + (n - 1), rep(symbol, width))
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, tHex[bgCol]:rep(text:len()))
setFG(x, y, tHex[fgCol]:rep(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()
@@ -164,13 +181,24 @@ local function basaltDrawHelper(drawTerm)
isBlinking = terminal.getCursorBlink()
end
terminal.setCursorBlink(false)
if(mirrorTerm~=nil)then terminal.setCursorBlink(false) end
for n = 1, height do
terminal.setCursorPos(1, n)
terminal.blit(cacheT[n], cacheFG[n], cacheBG[n])
if(mirrorTerm~=nil)then
mirrorTerm.setCursorPos(1, n)
mirrorTerm.blit(cacheT[n], cacheFG[n], cacheBG[n])
end
end
terminal.setBackgroundColor(colors.black)
terminal.setCursorBlink(isBlinking)
terminal.setCursorPos(xC, yC)
if(mirrorTerm~=nil)then
mirrorTerm.setBackgroundColor(colors.black)
mirrorTerm.setCursorBlink(isBlinking)
mirrorTerm.setCursorPos(xC, yC)
end
end;
setTerm = function(newTerm)

View File

@@ -1,5 +1,4 @@
local function BasaltEvents()
return function()
local events = {}
local index = {}
@@ -33,5 +32,4 @@ local function BasaltEvents()
}
event.__index = event
return event
end
local eventSystem = BasaltEvents()
end

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

File diff suppressed because one or more lines are too long

View File

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

147
Basalt/libraries/layout.lua Normal file
View File

@@ -0,0 +1,147 @@
local function newNode(name)
local node = {}
node.___value = nil
node.___name = name
node.___children = {}
node.___props = {}
function node:value() return self.___value end
function node:setValue(val) self.___value = val end
function node:name() return self.___name end
function node:setName(name) self.___name = name end
function node:children() return self.___children end
function node:numChildren() return #self.___children end
function node:addChild(child)
if self[child:name()] ~= nil then
if type(self[child:name()].name) == "function" then
local tempTable = {}
table.insert(tempTable, self[child:name()])
self[child:name()] = tempTable
end
table.insert(self[child:name()], child)
else
self[child:name()] = child
end
table.insert(self.___children, child)
end
function node:properties() return self.___props end
function node:numProperties() return #self.___props end
function node:addProperty(name, value)
local lName = "@" .. name
if self[lName] ~= nil then
if type(self[lName]) == "string" then
local tempTable = {}
table.insert(tempTable, self[lName])
self[lName] = tempTable
end
table.insert(self[lName], value)
else
self[lName] = value
end
table.insert(self.___props, { name = name, value = self[name] })
end
return node
end
local XmlParser = {};
function XmlParser:ToXmlString(value)
value = string.gsub(value, "&", "&amp;"); -- '&' -> "&amp;"
value = string.gsub(value, "<", "&lt;"); -- '<' -> "&lt;"
value = string.gsub(value, ">", "&gt;"); -- '>' -> "&gt;"
value = string.gsub(value, "\"", "&quot;"); -- '"' -> "&quot;"
value = string.gsub(value, "([^%w%&%;%p%\t% ])",
function(c)
return string.format("&#x%X;", string.byte(c))
end);
return value;
end
function XmlParser:FromXmlString(value)
value = string.gsub(value, "&#x([%x]+)%;",
function(h)
return string.char(tonumber(h, 16))
end);
value = string.gsub(value, "&#([0-9]+)%;",
function(h)
return string.char(tonumber(h, 10))
end);
value = string.gsub(value, "&quot;", "\"");
value = string.gsub(value, "&apos;", "'");
value = string.gsub(value, "&gt;", ">");
value = string.gsub(value, "&lt;", "<");
value = string.gsub(value, "&amp;", "&");
return value;
end
function XmlParser:ParseArgs(node, s)
string.gsub(s, "(%w+)=([\"'])(.-)%2", function(w, _, a)
node:addProperty(w, self:FromXmlString(a))
end)
end
function XmlParser:ParseXmlText(xmlText)
local stack = {}
local top = newNode()
table.insert(stack, top)
local ni, c, label, xarg, empty
local i, j = 1, 1
while true do
ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w_:]+)(.-)(%/?)>", i)
if not ni then break end
local text = string.sub(xmlText, i, ni - 1);
if not string.find(text, "^%s*$") then
local lVal = (top:value() or "") .. self:FromXmlString(text)
stack[#stack]:setValue(lVal)
end
if empty == "/" then -- empty element tag
local lNode = newNode(label)
self:ParseArgs(lNode, xarg)
top:addChild(lNode)
elseif c == "" then -- start tag
local lNode = newNode(label)
self:ParseArgs(lNode, xarg)
table.insert(stack, lNode)
top = lNode
else -- end tag
local toclose = table.remove(stack) -- remove top
top = stack[#stack]
if #stack < 1 then
error("XmlParser: nothing to close with " .. label)
end
if toclose:name() ~= label then
error("XmlParser: trying to close " .. toclose.name .. " with " .. label)
end
top:addChild(toclose)
end
i = j + 1
end
local text = string.sub(xmlText, i);
if #stack > 1 then
error("XmlParser: unclosed " .. stack[#stack]:name())
end
return top
end
function XmlParser:loadFile(xmlFilename, base)
if not base then
base = system.ResourceDirectory
end
local path = system.pathForFile(xmlFilename, base)
local hFile, err = io.open(path, "r");
if hFile and not err then
local xmlText = hFile:read("*a"); -- read file content
io.close(hFile);
return self:ParseXmlText(xmlText), nil;
else
print(err)
return nil
end
end
return XmlParser

View File

@@ -3,12 +3,12 @@ local process = {}
local processId = 0
function process:new(path, window, ...)
local args = table.pack(...)
local args = {...}
local newP = setmetatable({ path = path }, { __index = self })
newP.window = window
newP.processId = processId
newP.coroutine = coroutine.create(function()
os.run({ }, path, table.unpack(args))
shell.execute(path, table.unpack(args))
end)
processes[processId] = newP
processId = processId + 1
@@ -17,12 +17,16 @@ end
function process:resume(event, ...)
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)
error(result)
end
end
@@ -47,4 +51,6 @@ end
function process:start()
coroutine.resume(self.coroutine)
end
end
return process

View File

@@ -1,17 +1,4 @@
local basalt = { debugger = true, version = 1 }
local keyActive = {}
local focusedObject
local frames = {}
local activeFrame
local mainFrame
local monFrames = {}
local parentTerminal = term.current()
local sub = string.sub
local tHex = { -- copy paste is a very important feature
return { -- copy paste is a very important feature
[colors.white] = "0",
[colors.orange] = "1",
[colors.magenta] = "2",

120
Basalt/libraries/utils.lua Normal file
View File

@@ -0,0 +1,120 @@
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
return {
getTextHorizontalAlign = function(text, width, textAlign, replaceChar)
text = string.sub(text, 1, width)
local offset = width - string.len(text)
if (textAlign == "right") then
text = string.rep(replaceChar or " ", offset) .. text
elseif (textAlign == "center") then
text = string.rep(replaceChar or " ", math.floor(offset / 2)) .. text .. string.rep(replaceChar or " ", math.floor(offset / 2))
text = text .. (string.len(text) < width and (replaceChar or " ") or "")
else
text = text .. string.rep(replaceChar or " ", offset)
end
return text
end,
getTextVerticalAlign = function(h, textAlign)
local offset = 0
if (textAlign == "center") then
offset = math.ceil(h / 2)
if (offset < 1) then
offset = 1
end
end
if (textAlign == "bottom") then
offset = h
end
if(offset<1)then offset=1 end
return offset
end,
rpairs = function(t)
return function(t, i)
i = i - 1
if i ~= 0 then
return i, t[i]
end
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 = {}
for k,v in pairs(uniqueLines)do
local line = ""
local words = splitString(v, " ")
for a,b in pairs(words)do
if(#line+#b <= width)then
line = line=="" and b or line.." "..b
if(a==#words)then table.insert(lines, line) end
else
table.insert(lines, line)
line = b:sub(1,width)
if(a==#words)then table.insert(lines, line) end
end
end
end
return lines
end,
getValueFromXML = function(name, tab)
local var
if(type(tab)~="table")then return end
if(tab[name]~=nil)then
if(type(tab[name])=="table")then
if(tab[name].value~=nil)then
var = tab[name]:value()
end
end
end
if(var==nil)then var = tab["@"..name] end
if(var=="true")then
var = true
elseif(var=="false")then
var = false
elseif(tonumber(var)~=nil)then
var = tonumber(var)
end
return var
end,
numberFromString = function(str)
return load("return " .. str)()
end,
uuid = function()
local random = math.random
local function uuid()
local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
return string.gsub(template, '[xy]', function (c)
local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
return string.format('%x', v)
end)
end
return uuid()
end,
}

21
Basalt/loadObjects.lua Normal file
View File

@@ -0,0 +1,21 @@
local _OBJECTS = {}
if(packaged)then
for k,v in pairs(getProject("objects"))do
_OBJECTS[k] = v()
end
return _OBJECTS
end
local args = table.pack(...)
local dir = fs.getDir(args[2] or "Basalt")
if(dir==nil)then
error("Unable to find directory "..args[2].." please report this bug to our discord.")
end
for _,v in pairs(fs.list(fs.combine(dir, "objects")))do
if(v~="example.lua")then
local name = v:gsub(".lua", "")
_OBJECTS[name] = require(name)
end
end
return _OBJECTS

357
Basalt/main.lua Normal file
View File

@@ -0,0 +1,357 @@
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 baseTerm = term.current()
local version = "1.6.0"
local debugger = true
local projectDirectory = fs.getDir(table.pack(...)[2] or "")
local activeKey, frames, monFrames, 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 function stop()
updaterActive = false
baseTerm.clear()
baseTerm.setCursorPos(1, 1)
end
local setVariable = function(name, var)
variables[name] = var
end
local getVariable = function(name)
return variables[name]
end
local setTheme = function(_theme)
theme = _theme
end
local getTheme = function(name)
return theme[name]
end
local bInstance = {
getMainFrame = function()
return mainFrame
end,
setVariable = setVariable,
getVariable = getVariable,
getTheme = getTheme,
setMainFrame = function(mFrame)
mainFrame = mFrame
end,
getActiveFrame = function()
return activeFrame
end,
setActiveFrame = function(aFrame)
activeFrame = aFrame
end,
getFocusedObject = function()
return focusedObject
end,
setFocusedObject = function(focused)
focusedObject = focused
end,
getMonitorFrame = function(name)
return monFrames[name]
end,
setMonitorFrame = function(name, frame)
if(mainFrame == frame)then mainFrame = nil end
monFrames[name] = frame
end,
getBaseTerm = function()
return baseTerm
end,
stop = stop,
newFrame = Frame,
getDirectory = function()
return projectDirectory
end
}
local basaltError = function(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 handleSchedules(event, p1, p2, p3, p4)
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)
end
else
table.insert(finished, n)
end
end
end
for n=1,#finished do
table.remove(schedules, finished[n]-(n-1))
end
end
end
local function drawFrames()
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
end
local function basaltUpdateEvent(event, p1, p2, p3, p4)
if(basaltEvent:sendEvent("basaltEventCycle", event, p1, p2, p3, p4)==false)then return end
if(mainFrame~=nil)then
if (event == "mouse_click") then
mainFrame:mouseHandler(p1, p2, p3, false)
activeFrame = mainFrame
elseif (event == "mouse_drag") then
mainFrame:dragHandler(p1, p2, p3, p4)
activeFrame = mainFrame
elseif (event == "mouse_up") then
mainFrame:mouseUpHandler(p1, p2, p3, p4)
activeFrame = mainFrame
elseif (event == "mouse_scroll") then
mainFrame:scrollHandler(p1, p2, p3, p4)
activeFrame = mainFrame
end
end
if(event == "monitor_touch") then
if(monFrames[p1]~=nil)then
monFrames[p1]:mouseHandler(1, p2, p3, true)
activeFrame = monFrames[p1]
end
end
if(event == "char")then
if(activeFrame~=nil)then
activeFrame:charHandler(p1)
end
end
if(event == "key_up")then
if(activeFrame~=nil)then
activeFrame:keyUpHandler(p1)
end
activeKey[p1] = false
end
if(event == "key")then
if(activeFrame~=nil)then
activeFrame:keyHandler(p1, p2)
end
activeKey[p1] = true
end
if(event == "terminate")then
if(activeFrame~=nil)then
activeFrame:eventHandler(event)
if(updaterActive==false)then return end
end
end
if(event~="mouse_click")and(event~="mouse_up")and(event~="mouse_scroll")and(event~="mouse_drag")and(event~="key")and(event~="key_up")and(event~="char")and(event~="terminate")then
for k, v in pairs(frames) do
v:eventHandler(event, p1, p2, p3, p4)
end
end
handleSchedules(event, p1, p2, p3, p4)
drawFrames()
end
basalt = {
logging = false,
setTheme = setTheme,
getTheme = getTheme,
drawFrames = drawFrames,
getVersion = function()
return version
end,
setVariable = setVariable,
getVariable = getVariable,
setBaseTerm = function(_baseTerm)
baseTerm = _baseTerm
end,
log = function(...)
log(...)
end,
autoUpdate = function(isActive)
updaterActive = isActive
if(isActive==nil)then updaterActive = true end
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, p1, p2, p3, p4)
if (event ~= nil) then
local ok, err = xpcall(basaltUpdateEvent, debug.traceback, event, p1, p2, p3, p4)
if not(ok)then
basaltError(err)
return
end
end
end,
stop = stop,
stopUpdate = stop,
isKeyDown = function(key)
if(activeKey[key]==nil)then return false end
return activeKey[key];
end,
getFrame = function(name)
for _, value in pairs(frames) do
if (value.name == name) then
return value
end
end
end,
getActiveFrame = function()
return activeFrame
end,
setActiveFrame = function(frame)
if (frame:getType() == "Frame") then
activeFrame = frame
return true
end
return false
end,
onEvent = function(...)
for _,v in pairs(table.pack(...))do
if(type(v)=="function")then
basaltEvent:registerEvent("basaltEventCycle", v)
end
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,
createFrame = function(name)
name = name or uuid()
for _, v in pairs(frames) do
if (v.name == name) then
return nil
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()
end
return newFrame
end,
removeFrame = function(name)
frames[name] = nil
end,
setProjectDir = function(dir)
projectDirectory = dir
end,
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)
end
end
local str = ""
for key, value in pairs(args) do
str = str .. tostring(value) .. (#args ~= key and ", " or "")
end
basalt.debugLabel:setText("[Debug] " .. str)
for k,v in pairs(createText(str, basalt.debugList:getWidth()))do
basalt.debugList:addItem(v)
end
if (basalt.debugList:getItemCount() > 50) then
basalt.debugList:removeItem(1)
end
basalt.debugList:setValue(basalt.debugList:getItem(basalt.debugList:getItemCount()))
if(basalt.debugList.getItemCount() > basalt.debugList:getHeight())then
basalt.debugList:setOffset(basalt.debugList:getItemCount() - basalt.debugList:getHeight())
end
basalt.debugLabel:show()
end,
}
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("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

View File

@@ -0,0 +1,471 @@
local xmlValue = require("utils").getValueFromXML
local basaltEvent = require("basaltEvent")
local floor,sin,cos,pi = math.floor,math.sin,math.cos,math.pi
local lerp = function(s, e, pct)
return s + (e - s) * pct
end
local linear = function (t)
return t
end
local flip = function (t)
return 1 - t
end
local easeIn = function (t)
return t * t * t
end
local easeOut = function(t)
return flip(easeIn(flip(t)))
end
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 lerp = {
linear = linear,
lerp = lerp,
flip=flip,
easeIn=easeIn,
easeOut=easeOut,
easeInOut=easeInOut,
easeOutSine = easeOutSine,
easeInSine = easeInSine,
easeInOutSine = easeInOutSine,
}
local activeAnimations = {}
return function(name)
local object = {}
local objectType = "Animation"
local timerObj
local animations = {}
local animationTime = 0
local animationActive = false
local index = 1
local infinitePlay = false
local eventSystem = basaltEvent()
local nextWaitTimer = 0
local lastFunc
local loop=false
local autoDestroy = false
local mode = "easeOut"
local _OBJ
local function call(tab)
for k,v in pairs(tab)do
v(object, animations[index].t, index)
end
end
local function onPlay(self)
if(index==1)then self:animationStartHandler() end
if (animations[index] ~= nil) then
call(animations[index].f)
animationTime = animations[index].t
end
index = index + 1
if(animations[index]==nil)then
if(infinitePlay)then
index = 1
animationTime = 0
else
self:animationDoneHandler()
return
end
end
if (animations[index].t > 0) then
timerObj = os.startTimer(animations[index].t - animationTime)
else
onPlay(self)
end
end
local function addAnimationPart(time, f)
for n=1,#animations do
if(animations[n].t==time)then
table.insert(animations[n].f, f)
return
end
end
for n=1,#animations do
if(animations[n].t>time)then
if(animations[n-1]~=nil)then
if(animations[n-1].t<time)then
table.insert(animations, n-1, {t=time, f={f}})
return
end
else
table.insert(animations, n, {t=time, f={f}})
return
end
end
end
if(#animations<=0)then
table.insert(animations, 1, {t=time, f={f}})
return
elseif(animations[#animations].t<time)then
table.insert(animations, {t=time, f={f}})
end
end
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()
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.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)
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;
object = {
name = name,
getType = function(self)
return objectType
end;
getBaseFrame = function(self)
if(self.parent~=nil)then
return self.parent:getBaseFrame()
end
return self
end;
setMode = function(self, newMode)
mode = newMode
return self
end,
generateXMLEventFunction = function(self, func, val)
local createF = function(str)
if(str:sub(1,1)=="#")then
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
if(o~=nil)and(o.internalObjetCall~=nil)then
func(self,function()o:internalObjetCall()end)
end
else
func(self,self:getBaseFrame():getVariable(str))
end
end
if(type(val)=="string")then
createF(val)
elseif(type(val)=="table")then
for k,v in pairs(val)do
createF(v)
end
end
return self
end,
setValuesByXMLData = function(self, data)
loop = xmlValue("loop", data)==true and true or false
if(xmlValue("object", data)~=nil)then
local o = self:getBaseFrame():getDeepObject(xmlValue("object", data))
if(o==nil)then
o = self:getBaseFrame():getVariable(xmlValue("object", data))
end
if(o~=nil)then
self:setObject(o)
end
end
if(data["move"]~=nil)then
local x = xmlValue("x", data["move"])
local y = xmlValue("y", data["move"])
local duration = xmlValue("duration", data["move"])
local time = xmlValue("time", data["move"])
self:move(x, y, duration, time)
end
if(data["size"]~=nil)then
local w = xmlValue("width", data["size"])
local h = xmlValue("height", data["size"])
local duration = xmlValue("duration", data["size"])
local time = xmlValue("time", data["size"])
self:size(w, h, duration, time)
end
if(data["offset"]~=nil)then
local x = xmlValue("x", data["offset"])
local y = xmlValue("y", data["offset"])
local duration = xmlValue("duration", data["offset"])
local time = xmlValue("time", data["offset"])
self:offset(x, y, duration, time)
end
if(data["textColor"]~=nil)then
local duration = xmlValue("duration", data["textColor"])
local timer = xmlValue("time", data["textColor"])
local t = {}
local tab = data["textColor"]["color"]
if(tab~=nil)then
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
table.insert(t, colors[v:value()])
end
end
if(duration~=nil)and(#t>0)then
self:changeTextColor(duration, timer or 0, table.unpack(t))
end
end
if(data["background"]~=nil)then
local duration = xmlValue("duration", data["background"])
local timer = xmlValue("time", data["background"])
local t = {}
local tab = data["background"]["color"]
if(tab~=nil)then
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
table.insert(t, colors[v:value()])
end
end
if(duration~=nil)and(#t>0)then
self:changeBackground(duration, timer or 0, table.unpack(t))
end
end
if(data["text"]~=nil)then
local duration = xmlValue("duration", data["text"])
local timer = xmlValue("time", data["text"])
local t = {}
local tab = data["text"]["text"]
if(tab~=nil)then
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
table.insert(t, v:value())
end
end
if(duration~=nil)and(#t>0)then
self:changeText(duration, timer or 0, table.unpack(t))
end
end
if(xmlValue("onDone", data)~=nil)then self:generateXMLEventFunction(self.onDone, xmlValue("onDone", data)) end
if(xmlValue("onStart", data)~=nil)then self:generateXMLEventFunction(self.onDone, xmlValue("onStart", data)) end
if(xmlValue("autoDestroy", data)~=nil)then
if(xmlValue("autoDestroy", data))then
autoDestroy = true
end
end
mode = xmlValue("mode", data) or mode
if(xmlValue("play", data)~=nil)then if(xmlValue("play", data))then self:play(loop) end end
return self
end,
getZIndex = function(self)
return 1
end;
getName = function(self)
return self.name
end;
setObject = function(self, obj)
_OBJ = obj
return self
end;
move = function(self, x, y, duration, timer, obj)
_OBJ = obj or _OBJ
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, "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, "size", self)
return self
end,
changeText = function(self, duration, timer, ...)
local text = {...}
timer = timer or 0
_OBJ = obj or _OBJ
for n=1,#text do
addAnimationPart(timer+n*(duration/#text), function()
_OBJ.setText(_OBJ, text[n])
end)
end
return self
end,
changeBackground = function(self, duration, timer, ...)
local colors = {...}
timer = timer or 0
_OBJ = obj or _OBJ
for n=1,#colors do
addAnimationPart(timer+n*(duration/#colors), function()
_OBJ.setBackground(_OBJ, colors[n])
end)
end
return self
end,
changeTextColor = function(self, duration, timer, ...)
local colors = {...}
timer = timer or 0
_OBJ = obj or _OBJ
for n=1,#colors do
addAnimationPart(timer+n*(duration/#colors), function()
_OBJ.setForeground(_OBJ, colors[n])
end)
end
return self
end,
add = function(self, func, wait)
lastFunc = func
addAnimationPart((wait or nextWaitTimer) + (animations[#animations]~=nil and animations[#animations].t or 0), func)
return self
end;
wait = function(self, wait)
nextWaitTimer = wait
return self
end;
rep = function(self, reps)
if(lastFunc~=nil)then
for n = 1, reps or 1 do
addAnimationPart((wait or nextWaitTimer) + (animations[#animations]~=nil and animations[#animations].t or 0), lastFunc)
end
end
return self
end;
onDone = function(self, f)
eventSystem:registerEvent("animation_done", f)
return self
end,
onStart = function(self, f)
eventSystem:registerEvent("animation_start", f)
return self
end,
setAutoDestroy = function(self, destroy)
autoDestroy = destroy~=nil and destroy or true
return self
end,
animationDoneHandler = function(self)
eventSystem:sendEvent("animation_done", self)
self.parent:removeEvent("other_event", self)
if(autoDestroy)then
self.parent:removeObject(self)
self = nil
end
end;
animationStartHandler = function(self)
eventSystem:sendEvent("animation_start", self)
end;
clear = function(self)
animations = {}
lastFunc = nil
nextWaitTimer = 0
index = 1
animationTime = 0
infinitePlay = false
return self
end;
play = function(self, infinite)
self:cancel()
animationActive = true
infinitePlay = infinite and true or false
index = 1
animationTime = 0
if (animations[index] ~= nil) then
if (animations[index].t > 0) then
timerObj = os.startTimer(animations[index].t)
else
onPlay(self)
end
else
self:animationDoneHandler()
end
self.parent:addEvent("other_event", self)
return self
end;
cancel = function(self)
if(timerObj~=nil)then
os.cancelTimer(timerObj)
infinitePlay = false
end
animationActive = false
self.parent:removeEvent("other_event", self)
return self
end;
internalObjetCall = function(self)
self:play(loop)
end,
eventHandler = function(self, event, tObj)
if(animationActive)then
if (event == "timer") and (tObj == timerObj) then
if (animations[index] ~= nil) then
onPlay(self)
else
self:animationDoneHandler()
end
end
end
end;
}
object.__index = object
return object
end

71
Basalt/objects/Button.lua Normal file
View File

@@ -0,0 +1,71 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
-- Button
local base = Object(name)
local objectType = "Button"
local textHorizontalAlign = "center"
local textVerticalAlign = "center"
base:setZIndex(5)
base:setValue("Button")
base.width = 12
base.height = 3
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("ButtonBG")
self.fgColor = self.parent:getTheme("ButtonText")
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)
self:updateDraw()
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end
if(xmlValue("horizontalAlign", data)~=nil)then textHorizontalAlign = xmlValue("horizontalAlign", data) end
if(xmlValue("verticalAlign", data)~=nil)then textVerticalAlign = xmlValue("verticalAlign", data) end
return self
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
for n = 1, h do
if (n == verticalAlign) then
self.parent:setText(obx, oby + (n - 1), utils.getTextHorizontalAlign(self:getValue(), w, textHorizontalAlign))
self.parent:setFG(obx, oby + (n - 1), utils.getTextHorizontalAlign(tHex[self.fgColor]:rep(self:getValue():len()), w, textHorizontalAlign))
end
end
end
end
end,
}
return setmetatable(object, base)
end

View File

@@ -0,0 +1,83 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
return function(name)
-- Checkbox
local base = Object(name)
local objectType = "Checkbox"
base:setZIndex(5)
base:setValue(false)
base.width = 1
base.height = 1
local symbol = "\42"
local object = {
getType = function(self)
return objectType
end;
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
self:updateDraw()
return true
end
end
return false
end,
touchHandler = function(self, x, y)
return self:mouseHandler(1, x, y)
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("checked", data)~=nil)then if(xmlValue("checked", data))then self:setValue(true) else self:setValue(false) end end
return self
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, "center")
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
for n = 1, h do
if (n == verticalAlign) then
if (self:getValue() == true) then
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(symbol, w, "center"), self.bgColor, self.fgColor)
else
self.parent:writeText(obx, oby + (n - 1), utils.getTextHorizontalAlign(" ", w, "center"), self.bgColor, self.fgColor)
end
end
end
end
end
end,
init = function(self)
base.init(self)
self.bgColor = self.parent:getTheme("CheckboxBG")
self.fgColor = self.parent:getTheme("CheckboxText")
self.parent:addEvent("mouse_click", self)
end,
}
return setmetatable(object, base)
end

241
Basalt/objects/Dropdown.lua Normal file
View File

@@ -0,0 +1,241 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = require("utils").getValueFromXML
return function(name)
local base = Object(name)
local objectType = "Dropdown"
base.width = 12
base.height = 1
base:setZIndex(6)
local list = {}
local itemSelectedBG
local itemSelectedFG
local selectionColorActive = true
local align = "left"
local yOffset = 0
local dropdownW = 16
local dropdownH = 6
local closedSymbol = "\16"
local openedSymbol = "\31"
local isOpened = false
local object = {
getType = function(self)
return objectType
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
if(xmlValue("dropdownWidth", data)~=nil)then dropdownW = xmlValue("dropdownWidth", data) end
if(xmlValue("dropdownHeight", data)~=nil)then dropdownH = xmlValue("dropdownHeight", data) end
if(xmlValue("offset", data)~=nil)then yOffset = xmlValue("offset", data) end
if(data["item"]~=nil)then
local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
end
end
end,
setOffset = function(self, yOff)
yOffset = yOff
self:updateDraw()
return self
end;
getOffset = function(self)
return yOffset
end;
addItem = function(self, text, bgCol, fgCol, ...)
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
getAll = function(self)
return list
end;
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
getItem = function(self, index)
return list[index]
end;
getItemIndex = function(self)
local selected = self:getValue()
for key, value in pairs(list) do
if (value == selected) then
return key
end
end
end;
clear = function(self)
list = {}
self:setValue({})
self:updateDraw()
return self
end;
getItemCount = function(self)
return #list
end;
editItem = function(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {})
self:updateDraw()
return self
end;
setSelectedItem = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self.bgColor
itemSelectedFG = fgCol or self.fgColor
selectionColorActive = active
self:updateDraw()
return self
end;
setDropdownSize = function(self, width, height)
dropdownW, dropdownH = width, height
self:updateDraw()
return self
end,
mouseHandler = 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
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,
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
end
end
end
end
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,
draw = function(self)
if (base.draw(self)) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (self.parent ~= nil) then
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
local val = self:getValue()
local text = utils.getTextHorizontalAlign((val~=nil and val.text or ""), w, align):sub(1, w - 1) .. (isOpened and openedSymbol or closedSymbol)
self.parent:writeText(obx, oby, text, self.bgColor, self.fgColor)
if (isOpened) then
for n = 1, dropdownH do
if (list[n + yOffset] ~= nil) then
if (list[n + yOffset] == val) then
if (selectionColorActive) then
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), itemSelectedBG, itemSelectedFG)
else
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
end
else
self.parent:writeText(obx, oby + n, utils.getTextHorizontalAlign(list[n + yOffset].text, dropdownW, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
end
end
end
end
end
end
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")
if(self.parent~=nil)then
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_up", self)
self.parent:addEvent("mouse_scroll", self)
end
end,
}
return setmetatable(object, base)
end

471
Basalt/objects/Graphic.lua Normal file
View File

@@ -0,0 +1,471 @@
local Object = require("Object")
local geometric = require("geometricPoints")
local tHex = require("tHex")
local xmlValue = require("utils").getValueFromXML
local sub,len,max,min = string.sub,string.len,math.max,math.min
return function(name)
-- Graphic
local base = Object(name)
local objectType = "Graphic"
base:setZIndex(2)
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()
end
redraw()
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
end
return false
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 (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))
end
end
end
end
self:setVisualChanged(false)
end
end;
}
return setmetatable(object, base)
end

View File

@@ -1,5 +1,8 @@
local function Image(name)
-- Pane
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
return function(name)
-- Image
local base = Object(name)
local objectType = "Image"
base:setZIndex(2)
@@ -8,7 +11,6 @@ local function Image(name)
local imageGotShrinked = 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 } }
@@ -130,6 +132,9 @@ local function Image(name)
end
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("ImageBG")
end,
getType = function(self)
return objectType
end;
@@ -137,26 +142,31 @@ local function Image(name)
loadImage = function(self, path)
image = paintutils.loadImage(path)
imageGotShrinked = false
self:updateDraw()
return self
end;
loadBlittleImage = function(self, path) -- not done yet
--image = paintutils.loadImage(path)
--imageGotShrinked = true
return self
end;
shrink = function(self)
shrink()
imageGotShrinked = true
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]
@@ -173,9 +183,9 @@ local function Image(name)
end
end
else
for yPos = 1, math.min(#image, self.height) do
for yPos = 1, math.min(#image, h) do
local line = image[yPos]
for xPos = 1, math.min(#line, self.width) do
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
@@ -184,9 +194,8 @@ local function Image(name)
end
end
end
self:setVisualChanged(false)
end
end;
end,
}
return setmetatable(object, base)

View File

@@ -1,4 +1,9 @@
local function Input(name)
local Object = require("Object")
local utils = require("utils")
local log = require("basaltLogs")
local xmlValue = utils.getValueFromXML
return function(name)
-- Input
local base = Object(name)
local objectType = "Input"
@@ -9,8 +14,6 @@ local function Input(name)
base:setValue("")
base.width = 10
base.height = 1
base.bgColor = theme.InputBG
base.fgColor = theme.InputFG
local textX = 1
local wIndex = 1
@@ -22,7 +25,6 @@ local function Input(name)
local internalValueChange = false
local object = {
getType = function(self)
return objectType
end;
@@ -31,6 +33,7 @@ local function Input(name)
if (iType == "password") or (iType == "number") or (iType == "text") then
inputType = iType
end
self:updateDraw()
return self
end;
@@ -43,6 +46,7 @@ local function Input(name)
else
showingText = defaultText
end
self:updateDraw()
return self
end;
@@ -53,8 +57,14 @@ local function Input(name)
setValue = function(self, val)
base.setValue(self, tostring(val))
if not (internalValueChange) then
textX = tostring(val):len() + 1
if(self:isFocused())then
textX = tostring(val):len() + 1
wIndex = math.max(1, textX-self:getWidth()+1)
local obx, oby = self:getAnchorPosition()
self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor)
end
end
self:updateDraw()
return self
end;
@@ -65,6 +75,7 @@ local function Input(name)
setInputLimit = function(self, limit)
inputLimit = tonumber(limit) or inputLimit
self:updateDraw()
return self
end;
@@ -72,29 +83,44 @@ local function Input(name)
return inputLimit
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
local dBG,dFG
if(xmlValue("defaultBG", data)~=nil)then dBG = xmlValue("defaultBG", data) end
if(xmlValue("defaultFG", data)~=nil)then dFG = xmlValue("defaultFG", data) end
if(xmlValue("default", data)~=nil)then self:setDefaultText(xmlValue("default", data), dFG~=nil and colors[dFG], dBG~=nil and colors[dBG]) end
if(xmlValue("limit", data)~=nil)then self:setInputLimit(xmlValue("limit", data)) end
if(xmlValue("type", data)~=nil)then self:setInputType(xmlValue("type", data)) end
return self
end,
getFocusHandler = function(self)
base.getFocusHandler(self)
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
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())
@@ -127,8 +153,8 @@ local function Input(name)
if (textX < 1) then
textX = 1
end
if (textX < wIndex) or (textX >= self.width + wIndex) then
wIndex = textX - self.width + 1
if (textX < wIndex) or (textX >= w + wIndex) then
wIndex = textX - w + 1
end
if (wIndex < 1) then
wIndex = 1
@@ -139,7 +165,7 @@ local function Input(name)
-- left arrow
textX = textX - 1
if (textX >= 1) then
if (textX < wIndex) or (textX >= self.width + wIndex) then
if (textX < wIndex) or (textX >= w + wIndex) then
wIndex = textX
end
end
@@ -150,61 +176,135 @@ local function Input(name)
wIndex = 1
end
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 (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()))
if (cursorX > self.x + w - 1) then
cursorX = self.x + w - 1
end
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
end
internalValueChange = false
return true
end
return false
end,
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 (char == ".") or (tonumber(char) ~= nil) then
self:setValue(text:sub(1, textX - 1) .. char .. text:sub(textX, text:len()))
textX = textX + 1
end
if (textX >= self.width + wIndex) then
wIndex = wIndex + 1
if (tonumber(base.getValue()) == nil) then
self:setValue(cache)
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 + self.width - 1) then
cursorX = self.x + self.width - 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(self.height/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, obx + textX-1, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor)
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 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
end,
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local verticalAlign = getTextVerticalAlign(self.height, "center")
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, "center")
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor) end
for n = 1, self.height do
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
for n = 1, h do
if (n == verticalAlign) then
local val = tostring(base.getValue())
local bCol = self.bgColor
@@ -220,22 +320,35 @@ local function Input(name)
if (val ~= "") then
text = val
end
text = text:sub(wIndex, self.width + wIndex - 1)
local space = self.width - text:len()
text = text:sub(wIndex, w + wIndex - 1)
local space = w - text:len()
if (space < 0) then
space = 0
end
if (inputType == "password") and (val ~= "") then
text = string.rep("*", text:len())
end
text = text .. string.rep(" ", space)
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.max(math.ceil(self:getHeight()/2-1, 1)), self.fgColor)
end
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.bgColor = self.parent:getTheme("InputBG")
self.fgColor = self.parent:getTheme("InputText")
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)
end
end,
}
return setmetatable(object, base)

136
Basalt/objects/Label.lua Normal file
View File

@@ -0,0 +1,136 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local createText = utils.createText
local tHex = require("tHex")
local bigFont = require("bigfont")
return function(name)
-- Label
local base = Object(name)
local objectType = "Label"
base:setZIndex(3)
local autoSize = true
base:setValue("Label")
base.width = 5
local textHorizontalAlign = "left"
local textVerticalAlign = "top"
local fontsize = 0
local fgColChanged,bgColChanged = false,false
local object = {
getType = function(self)
return objectType
end;
setText = function(self, text)
text = tostring(text)
base:setValue(text)
if (autoSize) then
self.width = text:len()
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:updateDraw()
return self
end;
setFontSize = function(self, size)
if(size>0)and(size<=4)then
fontsize = size-1 or 0
end
self:updateDraw()
return self
end;
getFontSize = function(self)
return fontsize+1
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end
if(xmlValue("verticalAlign", data)~=nil)then textVerticalAlign = xmlValue("verticalAlign", data) end
if(xmlValue("horizontalAlign", data)~=nil)then textHorizontalAlign = xmlValue("horizontalAlign", data) end
if(xmlValue("font", data)~=nil)then self:setFontSize(xmlValue("font", data)) end
return self
end,
setSize = function(self, width, height, rel)
base.setSize(self, width, height, rel)
autoSize = false
self:updateDraw()
return self
end;
draw = function(self)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
local verticalAlign = utils.getTextVerticalAlign(h, textVerticalAlign)
if(fontsize==0)then
if not(autoSize)then
local text = createText(self:getValue(), self:getWidth())
for k,v in pairs(text)do
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
end
else
self.parent:writeText(obx, oby, self:getValue(), self.bgColor, self.fgColor)
end
else
local tData = bigFont(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.lightGray)
if(autoSize)then
self:setSize(#tData[1][1], #tData[1]-1)
end
local oX, oY = self.parent:getSize()
local cX, cY = #tData[1][1], #tData[1]
obx = obx or math.floor((oX - cX) / 2) + 1
oby = oby or math.floor((oY - cY) / 2) + 1
for i = 1, cY do
self.parent:setFG(obx, oby + i - 2, tData[2][i])
self.parent:setBG(obx, oby + i - 2, tData[3][i])
self.parent:setText(obx, oby + i - 2, tData[1][i])
end
end
end
end
end,
init = function(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
}
return setmetatable(object, base)
end

213
Basalt/objects/List.lua Normal file
View File

@@ -0,0 +1,213 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
return function(name)
local base = Object(name)
local objectType = "List"
base.width = 16
base.height = 6
base:setZIndex(5)
local list = {}
local itemSelectedBG
local itemSelectedFG
local selectionColorActive = true
local align = "left"
local yOffset = 0
local scrollable = true
local object = {
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])
end
self:updateDraw()
return self
end;
setOffset = function(self, yOff)
yOffset = yOff
self:updateDraw()
return self
end;
getOffset = function(self)
return yOffset
end;
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
getItem = function(self, index)
return list[index]
end;
getAll = function(self)
return list
end;
getItemIndex = function(self)
local selected = self:getValue()
for key, value in pairs(list) do
if (value == selected) then
return key
end
end
end;
clear = function(self)
list = {}
self:setValue({})
self:updateDraw()
return self
end;
getItemCount = function(self)
return #list
end;
editItem = function(self, index, text, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {})
self:updateDraw()
return self
end;
setSelectedItem = function(self, bgCol, fgCol, active)
itemSelectedBG = bgCol or self.bgColor
itemSelectedFG = fgCol or self.fgColor
selectionColorActive = active~=nil and active 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;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
if(xmlValue("scrollable", data)~=nil)then if(xmlValue("scrollable", data))then self:setScrollable(true) else self:setScrollable(false) end end
if(xmlValue("offset", data)~=nil)then yOffset = xmlValue("offset", data) end
if(data["item"]~=nil)then
local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
end
end
return self
end,
scrollHandler = function(self, dir, x, y)
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 (dir >= 1) then
if (#list > h) then
if (yOffset > #list - h) then
yOffset = #list - h
end
if (yOffset >= #list) then
yOffset = #list - 1
end
else
yOffset = yOffset - 1
end
end
self:updateDraw()
end
return true
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
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
end
for n = 1, h do
if (list[n + yOffset] ~= nil) then
if (list[n + yOffset] == self:getValue()) then
if (selectionColorActive) then
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), itemSelectedBG, itemSelectedFG)
else
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
end
else
self.parent:writeText(obx, oby + n - 1, utils.getTextHorizontalAlign(list[n + yOffset].text, w, align), list[n + yOffset].bgCol, list[n + yOffset].fgCol)
end
end
end
end
end
end,
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")
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
end,
}
return setmetatable(object, base)
end

View File

@@ -1,17 +1,20 @@
local function Menubar(name)
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
local tHex = require("tHex")
return function(name)
local base = Object(name)
local objectType = "Menubar"
local object = {}
base.width = 30
base.height = 1
base.bgColor = colors.gray
base.fgColor = colors.lightGray
base:setZIndex(5)
local list = {}
local itemSelectedBG = theme.selectionBG
local itemSelectedFG = theme.selectionFG
local itemSelectedBG
local itemSelectedFG
local selectionColorActive = true
local align = "left"
local itemOffset = 0
@@ -21,10 +24,11 @@ local function Menubar(name)
local function maxScroll()
local mScroll = 0
local xPos = 0
local w = object:getWidth()
for n = 1, #list do
if (xPos + list[n].text:len() + space * 2 > object.width) then
if(xPos < object.width)then
mScroll = mScroll + (list[n].text:len() + space * 2-(object.width - xPos))
if (xPos + list[n].text:len() + space * 2 > w) then
if(xPos < w)then
mScroll = mScroll + (list[n].text:len() + space * 2-(w - xPos))
else
mScroll = mScroll + list[n].text:len() + space * 2
end
@@ -41,10 +45,11 @@ local function Menubar(name)
end;
addItem = function(self, text, bgCol, fgCol, ...)
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
table.insert(list, { text = tostring(text), bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
if (#list == 1) then
self:setValue(list[1])
end
self:updateDraw()
return self
end;
@@ -64,15 +69,17 @@ local function Menubar(name)
clear = function(self)
list = {}
self:setValue({})
self:updateDraw()
return self
end;
setSpace = function(self, _space)
space = _space or space
self:updateDraw()
return self
end;
setPositionOffset = function(self, offset)
setOffset = function(self, offset)
itemOffset = offset or 0
if (itemOffset < 0) then
itemOffset = 0
@@ -82,10 +89,11 @@ local function Menubar(name)
if (itemOffset > mScroll) then
itemOffset = mScroll
end
self:updateDraw()
return self
end;
getPositionOffset = function(self)
getOffset = function(self)
return itemOffset
end;
@@ -95,8 +103,26 @@ local function Menubar(name)
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
if(xmlValue("scrollable", data)~=nil)then if(xmlValue("scrollable", data))then self:setScrollable(true) else self:setScrollable(false) end end
if(xmlValue("offset", data)~=nil)then self:setOffset(xmlValue("offset", data)) end
if(xmlValue("space", data)~=nil)then space = xmlValue("space", data) end
if(data["item"]~=nil)then
local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
self:addItem(xmlValue("text", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
end
end
return self
end,
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
@@ -111,11 +137,13 @@ local function Menubar(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:updateDraw()
return self
end;
@@ -123,55 +151,57 @@ local function Menubar(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())
if (objX <= x) and (objX + self.width > x) and (objY <= y) and (objY + self.height > 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 (xPos-1 + list[n].text:len() + space * 2 <= self.width) 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 w,h = self:getSize()
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
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, self.width, self.height, self.bgColor)
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
end
local text = ""
local textBGCol = ""
@@ -188,13 +218,23 @@ local function Menubar(name)
end
end
self.parent:setText(obx, oby, text:sub(itemOffset+1, self.width+itemOffset))
self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, self.width+itemOffset))
self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, self.width+itemOffset))
self.parent:setText(obx, oby, text:sub(itemOffset+1, w+itemOffset))
self.parent:setBG(obx, oby, textBGCol:sub(itemOffset+1, w+itemOffset))
self.parent:setFG(obx, oby, textFGCol:sub(itemOffset+1, w+itemOffset))
end
self:setVisualChanged(false)
end
end;
end,
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")
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_scroll", self)
end,
}
return setmetatable(object, base)

28
Basalt/objects/Pane.lua Normal file
View File

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

View File

@@ -1,10 +1,19 @@
local function Program(name)
local Object = require("Object")
local tHex = require("tHex")
local process = require("process")
local xmlValue = require("utils").getValueFromXML
local log = require("basaltLogs")
local sub = string.sub
return function(name, parent)
local base = Object(name)
local objectType = "Program"
base:setZIndex(5)
local object
local cachedPath
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
@@ -21,7 +30,7 @@ local function Program(name)
for i = 0, 15 do
local c = 2 ^ i
tPalette[c] = { parentTerminal.getPaletteColour(c) }
tPalette[c] = { parent:getBasaltInstance().getBaseTerm().getPaletteColour(c) }
end
local function createEmptyLines()
@@ -43,6 +52,7 @@ local function Program(name)
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()
@@ -110,6 +120,7 @@ local function Program(name)
cacheFG[yCursor] = sNewTextColor
cacheBG[yCursor] = sNewBackgroundColor
end
object:updateDraw()
end
xCursor = nEnd + 1
if (visible) then
@@ -125,6 +136,7 @@ local function Program(name)
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)
@@ -134,6 +146,7 @@ local function Program(name)
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)
@@ -143,6 +156,7 @@ local function Program(name)
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)
@@ -305,11 +319,11 @@ local function Program(name)
end;
basalt_update = function()
if (object.parent ~= nil) then
if (parent ~= nil) then
for n = 1, height do
object.parent:setText(x, y + (n - 1), cacheT[n])
object.parent:setBG(x, y + (n - 1), cacheBG[n])
object.parent:setFG(x, y + (n - 1), cacheFG[n])
parent:setText(x, y + (n - 1), cacheT[n])
parent:setBG(x, y + (n - 1), cacheBG[n])
parent:setFG(x, y + (n - 1), cacheFG[n])
end
end
end;
@@ -342,11 +356,11 @@ local function Program(name)
isColor = function()
return parentTerminal.isColor()
return parent:getBasaltInstance().getBaseTerm().isColor()
end;
isColour = function()
return parentTerminal.isColor()
return parent:getBasaltInstance().getBaseTerm().isColor()
end;
write = function(text)
@@ -392,10 +406,6 @@ local function Program(name)
error("Arguments must be the same length", 2)
end
if (visible) then
--setText(xCursor, yCursor, text)
--setBG(xCursor, yCursor, bgcol)
--setFG(xCursor, yCursor, fgcol)
--xCursor = xCursor+text:len()
internalBlit(text, fgcol, bgcol)
end
end
@@ -413,6 +423,42 @@ local function Program(name)
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(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
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))
curProcess:resume(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
curProcess:resume(event, key, isHolding)
updateCursor(self)
end
end
end
end
object = {
getType = function(self)
return objectType
@@ -438,6 +484,12 @@ local function Program(name)
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("path", data)~=nil)then cachedPath = xmlValue("path", data) end
if(xmlValue("execute", data)~=nil)then if(xmlValue("execute", data))then if(cachedPath~=nil)then self:execute(cachedPath) end end end
end,
getBasaltWindow = function()
return pWindow
end;
@@ -446,9 +498,9 @@ local function Program(name)
return curProcess
end;
setSize = function(self, width, height)
base.setSize(self, width, height)
pWindow.basalt_resize(self.width, self.height)
setSize = function(self, width, height, rel)
base.setSize(self, width, height, rel)
pWindow.basalt_resize(self:getWidth(), self:getHeight())
return self
end;
@@ -460,13 +512,27 @@ local function Program(name)
end;
execute = function(self, path, ...)
curProcess = process:new(path, pWindow, ...)
cachedPath = path or cachedPath
curProcess = process:new(cachedPath, pWindow, ...)
pWindow.setBackgroundColor(colors.black)
pWindow.setTextColor(colors.white)
pWindow.clear()
pWindow.setCursorPos(1, 1)
pWindow.setBackgroundColor(self.bgColor)
pWindow.setTextColor(self.fgColor)
pWindow.basalt_setVisible(true)
curProcess:resume()
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;
@@ -481,6 +547,7 @@ local function Program(name)
end
end
end
self.parent:removeEvents(self)
return self
end;
@@ -534,37 +601,61 @@ local function Program(name)
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))
basalt.debug(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)
@@ -575,7 +666,8 @@ local function Program(name)
local xCur, yCur = pWindow.getCursorPos()
local obx, oby = self:getAnchorPosition()
if (self.parent ~= nil) then
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + self.width - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + self.height - 1) then
local w,h = self:getSize()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
@@ -583,7 +675,7 @@ local function Program(name)
end
end
end
end;
end,
loseFocusHandler = function(self)
base.loseFocusHandler(self)
@@ -594,51 +686,69 @@ local function Program(name)
end
end
end
end;
end,
eventHandler = function(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(base.eventHandler(self, event, p1, p2, p3, p4))then
if (curProcess == nil) then
return
end
if(event=="dynamicValueEvent")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
curProcess:resume("term_resize")
end
end
if (self:isFocused()) then
local obx, oby = self:getAnchorPosition()
local xCur, yCur = pWindow.getCursorPos()
if (self.parent ~= nil) then
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + self.width - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + self.height - 1) then
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
pWindow.basalt_reposition(self:getAnchorPosition())
end
if not (curProcess:isDead()) then
if not (paused) then
if(event ~= "terminate") then
curProcess:resume(event, p1, p2, p3, p4)
end
if (self:isFocused()) then
local obx, oby = self:getAnchorPosition()
local xCur, yCur = pWindow.getCursorPos()
if (self.parent ~= nil) then
local w,h = self:getSize()
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
end
end
if (event == "terminate") then
log(self:isFocused())
curProcess:resume(event)
self.parent:setCursor(false)
return true
end
end
if (event == "terminate") and (self:isFocused()) then
self:stop()
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
else
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
end
end
return false
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()
pWindow.basalt_reposition(obx, oby)
if(self.bgColor~=false)then
self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor)
end
pWindow.basalt_update()
end
self:setVisualChanged(false)
end
end;
end,
init = function(self)
self.bgColor = self.parent:getTheme("ProgramBG")
end,
}

View File

@@ -1,4 +1,7 @@
local function Progressbar(name)
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
return function(name)
-- Checkbox
local base = Object(name)
local objectType = "Progressbar"
@@ -9,23 +12,37 @@ local function Progressbar(name)
base:setValue(false)
base.width = 25
base.height = 1
base.bgColor = theme.CheckboxBG
base.fgColor = theme.CheckboxFG
local activeBarColor = colors.black
local activeBarColor
local activeBarSymbol = ""
local activeBarSymbolCol = colors.white
local bgBarSymbol = ""
local direction = 0
local object = {
init = function(self)
self.bgColor = self.parent:getTheme("ProgressbarBG")
self.fgColor = self.parent:getTheme("ProgressbarText")
activeBarColor = self.parent:getTheme("ProgressbarActiveBG")
end,
getType = function(self)
return objectType
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("direction", data)~=nil)then direction = xmlValue("direction", data) end
if(xmlValue("progressColor", data)~=nil)then activeBarColor = colors[xmlValue("progressColor", data)] end
if(xmlValue("progressSymbol", data)~=nil)then activeBarSymbol = xmlValue("progressSymbol", data) end
if(xmlValue("backgroundSymbol", data)~=nil)then bgBarSymbol = xmlValue("backgroundSymbol", data) end
if(xmlValue("progressSymbolColor", data)~=nil)then activeBarSymbolCol = colors[xmlValue("progressSymbolColor", data)] end
if(xmlValue("onDone", data)~=nil)then self:generateXMLEventFunction(self.onProgressDone, xmlValue("onDone", data)) end
return self
end,
setDirection = function(self, dir)
direction = dir
self:updateDraw()
return self
end;
@@ -33,11 +50,13 @@ local function Progressbar(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;
@@ -49,6 +68,7 @@ local function Progressbar(name)
self:progressDoneHandler()
end
end
self:updateDraw()
return self
end;
@@ -69,30 +89,30 @@ local function Progressbar(name)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor)
self.parent:drawForegroundBox(obx, oby, self.width, self.height, self.fgColor)
self.parent:drawTextBox(obx, oby, self.width, self.height, bgBarSymbol)
local w,h = self:getSize()
if(self.bgColor~=false)then self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor) end
if(bgBarSymbol~="")then self.parent:drawTextBox(obx, oby, w, h, bgBarSymbol) end
if(self.fgColor~=false)then self.parent:drawForegroundBox(obx, oby, w, h, self.fgColor) end
if (direction == 1) then
self.parent:drawBackgroundBox(obx, oby, self.width, self.height / 100 * progress, activeBarColor)
self.parent:drawForegroundBox(obx, oby, self.width, self.height / 100 * progress, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby, self.width, self.height / 100 * progress, activeBarSymbol)
self.parent:drawBackgroundBox(obx, oby, w, h / 100 * progress, activeBarColor)
self.parent:drawForegroundBox(obx, oby, w, h / 100 * progress, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby, w, h / 100 * progress, activeBarSymbol)
elseif (direction == 2) then
self.parent:drawBackgroundBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarColor)
self.parent:drawForegroundBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby + math.ceil(self.height - self.height / 100 * progress), self.width, self.height / 100 * progress, activeBarSymbol)
self.parent:drawBackgroundBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarColor)
self.parent:drawForegroundBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby + math.ceil(h - h / 100 * progress), w, h / 100 * progress, activeBarSymbol)
elseif (direction == 3) then
self.parent:drawBackgroundBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarColor)
self.parent:drawForegroundBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarSymbolCol)
self.parent:drawTextBox(obx + math.ceil(self.width - self.width / 100 * progress), oby, self.width / 100 * progress, self.height, activeBarSymbol)
self.parent:drawBackgroundBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarColor)
self.parent:drawForegroundBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarSymbolCol)
self.parent:drawTextBox(obx + math.ceil(w - w / 100 * progress), oby, w / 100 * progress, h, activeBarSymbol)
else
self.parent:drawBackgroundBox(obx, oby, self.width / 100 * progress, self.height, activeBarColor)
self.parent:drawForegroundBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby, self.width / 100 * progress, self.height, activeBarSymbol)
self.parent:drawBackgroundBox(obx, oby, w / 100 * progress, h, activeBarColor)
self.parent:drawForegroundBox(obx, oby, w / 100 * progress, h, activeBarSymbolCol)
self.parent:drawTextBox(obx, oby, w / 100 * progress, h, activeBarSymbol)
end
end
self:setVisualChanged(false)
end
end;
end,
}

167
Basalt/objects/Radio.lua Normal file
View File

@@ -0,0 +1,167 @@
local Object = require("Object")
local utils = require("utils")
local xmlValue = utils.getValueFromXML
return function(name)
local base = Object(name)
local objectType = "Radio"
base.width = 8
base:setZIndex(5)
local list = {}
local itemSelectedBG
local itemSelectedFG
local boxSelectedBG
local boxSelectedFG
local boxNotSelectedBG
local boxNotSelectedFG
local selectionColorActive = true
local symbol = "\7"
local align = "left"
local object = {
getType = function(self)
return objectType
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("selectionBG", data)~=nil)then itemSelectedBG = colors[xmlValue("selectionBG", data)] end
if(xmlValue("selectionFG", data)~=nil)then itemSelectedFG = colors[xmlValue("selectionFG", data)] end
if(xmlValue("boxBG", data)~=nil)then boxSelectedBG = colors[xmlValue("boxBG", data)] end
if(xmlValue("inactiveBoxBG", data)~=nil)then boxNotSelectedBG = colors[xmlValue("inactiveBoxBG", data)] end
if(xmlValue("inactiveBoxFG", data)~=nil)then boxNotSelectedFG = colors[xmlValue("inactiveBoxFG", data)] end
if(xmlValue("boxFG", data)~=nil)then boxSelectedFG = colors[xmlValue("boxFG", data)] end
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data) end
if(data["item"]~=nil)then
local tab = data["item"]
if(tab.properties~=nil)then tab = {tab} end
for k,v in pairs(tab)do
self:addItem(xmlValue("text", v), xmlValue("x", v), xmlValue("y", v), colors[xmlValue("bg", v)], colors[xmlValue("fg", v)])
end
end
return self
end,
addItem = function(self, text, x, y, bgCol, fgCol, ...)
table.insert(list, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
if (#list == 1) then
self:setValue(list[1])
end
self:updateDraw()
return self
end;
getAll = function(self)
return list
end;
removeItem = function(self, index)
table.remove(list, index)
self:updateDraw()
return self
end;
getItem = function(self, index)
return list[index]
end;
getItemIndex = function(self)
local selected = self:getValue()
for key, value in pairs(list) do
if (value == selected) then
return key
end
end
end;
clear = function(self)
list = {}
self:setValue({})
self:updateDraw()
return self
end;
getItemCount = function(self)
return #list
end;
editItem = function(self, index, text, x, y, bgCol, fgCol, ...)
table.remove(list, index)
table.insert(list, index, { x = x or 1, y = y or 1, text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
self:updateDraw()
return self
end;
selectItem = function(self, index)
self:setValue(list[index] or {})
self:updateDraw()
return self
end;
setActiveSymbol = function(self, sym)
symbol = sym:sub(1,1)
self:updateDraw()
return self
end,
setSelectedItem = function(self, bgCol, fgCol, boxBG, boxFG, active)
itemSelectedBG = bgCol or itemSelectedBG
itemSelectedFG = fgCol or itemSelectedFG
boxSelectedBG = boxBG or boxSelectedBG
boxSelectedFG = boxFG or boxSelectedFG
selectionColorActive = active~=nil and active or true
self:updateDraw()
return self
end;
mouseHandler = function(self, button, x, y)
if (#list > 0) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
for _, value in pairs(list) do
if (obx + value.x - 1 <= x) and (obx + value.x - 1 + value.text:len() + 1 >= x) and (oby + value.y - 1 == y) then
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
return false
end;
draw = function(self)
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
return true
end
end,
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")
self.parent:addEvent("mouse_click", self)
end,
}
return setmetatable(object, base)
end

View File

@@ -0,0 +1,186 @@
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
return function(name)
local base = Object(name)
local objectType = "Scrollbar"
base.width = 1
base.height = 8
base:setValue(1)
base:setZIndex(2)
local barType = "vertical"
local symbol = " "
local symbolColor
local bgSymbol = "\127"
local maxValue = base.height
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 = {
getType = function(self)
return objectType
end;
setSymbol = function(self, _symbol)
symbol = _symbol:sub(1, 1)
self:updateDraw()
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("maxValue", data)~=nil)then maxValue = xmlValue("maxValue", data) end
if(xmlValue("backgroundSymbol", data)~=nil)then bgSymbol = xmlValue("backgroundSymbol", data):sub(1,1) end
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data):sub(1,1) end
if(xmlValue("barType", data)~=nil)then barType = xmlValue("barType", data):lower() end
if(xmlValue("symbolSize", data)~=nil)then self:setSymbolSize(xmlValue("symbolSize", data)) end
if(xmlValue("symbolColor", data)~=nil)then symbolColor = colors[xmlValue("symbolColor", data)] end
if(xmlValue("index", data)~=nil)then self:setIndex(xmlValue("index", data)) end
end,
setIndex = function(self, _index)
index = _index
if (index < 1) then
index = 1
end
local w,h = self:getSize()
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
self:updateDraw()
return self
end,
getIndex = function(self)
return index
end,
setSymbolSize = function(self, size)
symbolSize = tonumber(size) or 1
local w,h = self:getSize()
if (barType == "vertical") then
self:setValue(index - 1 * (maxValue / (h - (symbolSize - 1))) - (maxValue / (h - (symbolSize - 1))))
elseif (barType == "horizontal") then
self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1))))
end
self:updateDraw()
return self
end;
setMaxValue = function(self, val)
maxValue = val
self:updateDraw()
return self
end;
setBackgroundSymbol = function(self, _bgSymbol)
bgSymbol = string.sub(_bgSymbol, 1, 1)
self:updateDraw()
return self
end;
setSymbolColor = function(self, col)
symbolColor = col
self:updateDraw()
return self
end;
setBarType = function(self, _typ)
barType = _typ:lower()
self:updateDraw()
return self
end;
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
mouseEvent(self, button, x, y)
return true
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
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (barType == "horizontal") then
self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor)
self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor)
self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(w - (index + symbolSize - 1)), self.bgColor, self.fgColor)
end
if (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor)
end
else
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor)
end
end
end
end
end
end
end,
init = function(self)
self.bgColor = self.parent:getTheme("ScrollbarBG")
self.fgColor = self.parent:getTheme("ScrollbarText")
symbolColor = self.parent:getTheme("ScrollbarSymbolColor")
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
end,
}
return setmetatable(object, base)
end

186
Basalt/objects/Slider.lua Normal file
View File

@@ -0,0 +1,186 @@
local Object = require("Object")
local log = require("basaltLogs")
local xmlValue = require("utils").getValueFromXML
return function(name)
local base = Object(name)
local objectType = "Slider"
base.width = 8
base.height = 1
base:setValue(1)
local barType = "horizontal"
local symbol = " "
local symbolColor
local bgSymbol = "\140"
local maxValue = base.width
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 = {
getType = function(self)
return objectType
end;
setSymbol = function(self, _symbol)
symbol = _symbol:sub(1, 1)
self:updateDraw()
return self
end;
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("maxValue", data)~=nil)then maxValue = xmlValue("maxValue", data) end
if(xmlValue("backgroundSymbol", data)~=nil)then bgSymbol = xmlValue("backgroundSymbol", data):sub(1,1) end
if(xmlValue("barType", data)~=nil)then barType = xmlValue("barType", data):lower() end
if(xmlValue("symbol", data)~=nil)then symbol = xmlValue("symbol", data):sub(1,1) end
if(xmlValue("symbolSize", data)~=nil)then self:setSymbolSize(xmlValue("symbolSize", data)) end
if(xmlValue("symbolColor", data)~=nil)then symbolColor = colors[xmlValue("symbolColor", data)] end
if(xmlValue("index", data)~=nil)then self:setIndex(xmlValue("index", data)) end
end,
setIndex = function(self, _index)
index = _index
if (index < 1) then
index = 1
end
local w,h = self:getSize()
index = math.min(index, (barType == "vertical" and h or w) - (symbolSize - 1))
self:setValue(maxValue / (barType == "vertical" and h or w) * index)
self:updateDraw()
return self
end,
getIndex = function(self)
return index
end,
setSymbolSize = function(self, size)
symbolSize = tonumber(size) or 1
if (barType == "vertical") then
self:setValue(index - 1 * (maxValue / (h - (symbolSize - 1))) - (maxValue / (h - (symbolSize - 1))))
elseif (barType == "horizontal") then
self:setValue(index - 1 * (maxValue / (w - (symbolSize - 1))) - (maxValue / (w - (symbolSize - 1))))
end
self:updateDraw()
return self
end;
setMaxValue = function(self, val)
maxValue = val
return self
end;
setBackgroundSymbol = function(self, _bgSymbol)
bgSymbol = string.sub(_bgSymbol, 1, 1)
self:updateDraw()
return self
end;
setSymbolColor = function(self, col)
symbolColor = col
self:updateDraw()
return self
end;
setBarType = function(self, _typ)
barType = _typ:lower()
self:updateDraw()
return self
end;
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
mouseEvent(self, button, x, y)
return true
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
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (barType == "horizontal") then
self.parent:writeText(obx, oby, bgSymbol:rep(index - 1), self.bgColor, self.fgColor)
self.parent:writeText(obx + index - 1, oby, symbol:rep(symbolSize), symbolColor, symbolColor)
self.parent:writeText(obx + index + symbolSize - 1, oby, bgSymbol:rep(w - (index + symbolSize - 1)), self.bgColor, self.fgColor)
end
if (barType == "vertical") then
for n = 0, h - 1 do
if (index == n + 1) then
for curIndexOffset = 0, math.min(symbolSize - 1, h) do
self.parent:writeText(obx, oby + n + curIndexOffset, symbol, symbolColor, symbolColor)
end
else
if (n + 1 < index) or (n + 1 > index - 1 + symbolSize) then
self.parent:writeText(obx, oby + n, bgSymbol, self.bgColor, self.fgColor)
end
end
end
end
end
end
end,
init = function(self)
self.bgColor = self.parent:getTheme("SliderBG")
self.fgColor = self.parent:getTheme("SliderText")
symbolColor = self.parent:getTheme("SliderSymbolColor")
self.parent:addEvent("mouse_click", self)
self.parent:addEvent("mouse_drag", self)
self.parent:addEvent("mouse_scroll", self)
end,
}
return setmetatable(object, base)
end

View File

@@ -1,4 +1,7 @@
local function Switch(name)
local Object = require("Object")
local xmlValue = require("utils").getValueFromXML
return function(name)
local base = Object(name)
local objectType = "Switch"
@@ -20,28 +23,35 @@ local function Switch(name)
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;
mouseHandler = function(self, event, button, x, y)
if (base.mouseHandler(self, event, button, x, y)) then
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(xmlValue("inactiveBG", data)~=nil)then inactiveBG = colors[xmlValue("inactiveBG", data)] end
if(xmlValue("activeBG", data)~=nil)then activeBG = colors[xmlValue("activeBG", data)] end
if(xmlValue("symbolColor", data)~=nil)then bgSymbol = colors[xmlValue("symbolColor", data)] end
end,
mouseHandler = function(self, button, x, y)
if (base.mouseHandler(self, button, x, y)) then
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
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;
@@ -50,18 +60,27 @@ local function Switch(name)
if (base.draw(self)) then
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
self.parent:drawBackgroundBox(obx, oby, self.width, self.height, self.bgColor)
local w,h = self:getSize()
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
if(self:getValue())then
self.parent:drawBackgroundBox(obx, oby, 1, self.height, activeBG)
self.parent:drawBackgroundBox(obx+1, oby, 1, self.height, bgSymbol)
self.parent:drawBackgroundBox(obx, oby, 1, h, activeBG)
self.parent:drawBackgroundBox(obx+1, oby, 1, h, bgSymbol)
else
self.parent:drawBackgroundBox(obx, oby, 1, self.height, bgSymbol)
self.parent:drawBackgroundBox(obx+1, oby, 1, self.height, inactiveBG)
self.parent:drawBackgroundBox(obx, oby, 1, h, bgSymbol)
self.parent:drawBackgroundBox(obx+1, oby, 1, h, inactiveBG)
end
end
self:setVisualChanged(false)
end
end;
end,
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")
self.parent:addEvent("mouse_click", self)
end,
}
return setmetatable(object, base)

View File

@@ -0,0 +1,620 @@
local Object = require("Object")
local tHex = require("tHex")
local log = require("basaltLogs")
local xmlValue = require("utils").getValueFromXML
local rep = string.rep
return function(name)
local base = Object(name)
local objectType = "Textfield"
local hIndex, wIndex, textX, textY = 1, 1, 1, 1
local lines = { "" }
local bgLines = { "" }
local fgLines = { "" }
local keyWords = { }
local rules = { }
base.width = 30
base.height = 12
base:setZIndex(5)
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)
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())
str = startL..(":"):rep(w:len())..endL
end
end
end
return pos
end
local function updateColors(self, l)
l = l or textY
local fgLine = tHex[self.fgColor]:rep(fgLines[l]:len())
local bgLine = tHex[self.bgColor]:rep(bgLines[l]:len())
for k,v in pairs(rules)do
local pos = stringGetPositions(lines[l], v[1])
if(#pos>0)then
for x=1,#pos/2 do
local xP = x*2 - 1
if(v[2]~=nil)then
fgLine = fgLine:sub(1, pos[xP]-1)..tHex[v[2]]:rep(pos[xP+1]-(pos[xP]-1))..fgLine:sub(pos[xP+1]+1, fgLine:len())
end
if(v[3]~=nil)then
bgLine = bgLine:sub(1, pos[xP]-1)..tHex[v[3]]:rep(pos[xP+1]-(pos[xP]-1))..bgLine:sub(pos[xP+1]+1, bgLine:len())
end
end
end
end
for k,v in pairs(keyWords)do
for _,b in pairs(v)do
local pos = stringGetPositions(lines[l], b)
if(#pos>0)then
for x=1,#pos/2 do
local xP = x*2 - 1
fgLine = fgLine:sub(1, pos[xP]-1)..tHex[k]:rep(pos[xP+1]-(pos[xP]-1))..fgLine:sub(pos[xP+1]+1, fgLine:len())
end
end
end
end
fgLines[l] = fgLine
bgLines[l] = bgLine
self:updateDraw()
end
local function updateAllColors(self)
for n=1,#lines do
updateColors(self, n)
end
end
local object = {
getType = function(self)
return objectType
end;
setBackground = function(self, bg)
base.setBackground(self, bg)
updateAllColors(self)
return self
end,
setForeground = function(self, fg)
base.setForeground(self, fg)
updateAllColors(self)
return self
end,
setValuesByXMLData = function(self, data)
base.setValuesByXMLData(self, data)
if(data["lines"]~=nil)then
local l = data["lines"]["line"]
if(l.properties~=nil)then l = {l} end
for k,v in pairs(l)do
self:addLine(v:value())
end
end
if(data["keywords"]~=nil)then
for k,v in pairs(data["keywords"])do
if(colors[k]~=nil)then
local entry = v
if(entry.properties~=nil)then entry = {entry} end
local tab = {}
for a,b in pairs(entry)do
local keywordList = b["keyword"]
if(b["keyword"].properties~=nil)then keywordList = {b["keyword"]} end
for c,d in pairs(keywordList)do
table.insert(tab, d:value())
end
end
self:addKeywords(colors[k], tab)
end
end
end
if(data["rules"]~=nil)then
if(data["rules"]["rule"]~=nil)then
local tab = data["rules"]["rule"]
if(data["rules"]["rule"].properties~=nil)then tab = {data["rules"]["rule"]} end
for k,v in pairs(tab)do
if(xmlValue("pattern", v)~=nil)then
self:addRule(xmlValue("pattern", v), colors[xmlValue("fg", v)], colors[xmlValue("bg", v)])
end
end
end
end
end,
getLines = function(self)
return lines
end;
getLine = function(self, index)
return lines[index]
end;
editLine = function(self, index, text)
lines[index] = text or lines[index]
self:updateDraw()
return self
end;
clear = function(self)
lines = {""}
bgLines = {""}
fgLines = {""}
hIndex, wIndex, textX, textY = 1, 1, 1, 1
self:updateDraw()
return self
end,
addLine = function(self, text, index)
if(text~=nil)then
if(#lines==1)and(lines[1]=="")then
lines[1] = text
bgLines[1] = tHex[self.bgColor]:rep(text:len())
fgLines[1] = tHex[self.fgColor]:rep(text:len())
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()))
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
self:updateDraw()
return self
end;
addKeywords = function(self, color, tab)
if(keyWords[color]==nil)then
keyWords[color] = {}
end
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;
editRule = function(self, rule, fg, bg)
for k,v in pairs(rules)do
if(v[1]==rule)then
rules[k][2] = fg
rules[k][3] = bg
end
end
self:updateDraw()
return self
end;
removeRule = function(self, rule)
for k,v in pairs(rules)do
if(v[1]==rule)then
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, "")
end
self:updateDraw()
return self
end;
getTextCursor = function(self)
return textX, textY
end;
getFocusHandler = function(self)
base.getFocusHandler(self)
if (self.parent ~= nil) then
local obx, oby = self:getAnchorPosition()
if (self.parent ~= nil) then
self.parent:setCursor(true, obx + textX - wIndex, oby + textY - hIndex, self.fgColor)
end
end
end;
loseFocusHandler = function(self)
base.loseFocusHandler(self)
if (self.parent ~= nil) then
self.parent:setCursor(false)
end
end;
keyHandler = function(self, key)
if (base.keyHandler(self, event, key)) then
local obx, oby = self:getAnchorPosition()
local w,h = self:getSize()
if (key == keys.backspace) then
-- on backspace
if (lines[textY] == "") then
if (textY > 1) then
table.remove(lines, textY)
table.remove(fgLines, textY)
table.remove(bgLines, textY)
textX = lines[textY - 1]:len() + 1
wIndex = textX - w + 1
if (wIndex < 1) then
wIndex = 1
end
textY = textY - 1
end
elseif (textX <= 1) then
if (textY > 1) then
textX = lines[textY - 1]:len() + 1
wIndex = textX - w + 1
if (wIndex < 1) then
wIndex = 1
end
lines[textY - 1] = lines[textY - 1] .. lines[textY]
fgLines[textY - 1] = fgLines[textY - 1] .. fgLines[textY]
bgLines[textY - 1] = bgLines[textY - 1] .. bgLines[textY]
table.remove(lines, textY)
table.remove(fgLines, textY)
table.remove(bgLines, textY)
textY = textY - 1
end
else
lines[textY] = lines[textY]:sub(1, textX - 2) .. lines[textY]:sub(textX, lines[textY]:len())
fgLines[textY] = fgLines[textY]:sub(1, textX - 2) .. fgLines[textY]:sub(textX, fgLines[textY]:len())
bgLines[textY] = bgLines[textY]:sub(1, textX - 2) .. bgLines[textY]:sub(textX, bgLines[textY]:len())
if (textX > 1) then
textX = textX - 1
end
if (wIndex > 1) then
if (textX < wIndex) then
wIndex = wIndex - 1
end
end
end
if (textY < hIndex) then
hIndex = hIndex - 1
end
updateColors(self)
self:setValue("")
end
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
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
updateColors(self)
end
if (key == keys.enter) then
-- on enter
table.insert(lines, textY + 1, lines[textY]:sub(textX, lines[textY]:len()))
table.insert(fgLines, textY + 1, fgLines[textY]:sub(textX, fgLines[textY]:len()))
table.insert(bgLines, textY + 1, bgLines[textY]:sub(textX, bgLines[textY]:len()))
lines[textY] = lines[textY]:sub(1, textX - 1)
fgLines[textY] = fgLines[textY]:sub(1, textX - 1)
bgLines[textY] = bgLines[textY]:sub(1, textX - 1)
textY = textY + 1
textX = 1
wIndex = 1
if (textY - hIndex >= h) then
hIndex = hIndex + 1
end
self:setValue("")
end
if (key == keys.up) then
-- arrow up
if (textY > 1) then
textY = textY - 1
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 (hIndex > 1) then
if (textY < hIndex) then
hIndex = hIndex - 1
end
end
end
end
if (key == keys.down) then
-- arrow down
if (textY < #lines) then
textY = textY + 1
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
end
end
if (key == keys.right) then
-- arrow right
textX = textX + 1
if (textY < #lines) then
if (textX > lines[textY]:len() + 1) then
textX = 1
textY = textY + 1
end
elseif (textX > lines[textY]:len()) then
textX = lines[textY]:len() + 1
end
if (textX < 1) then
textX = 1
end
if (textX < wIndex) or (textX >= w + wIndex) then
wIndex = textX - w + 1
end
if (wIndex < 1) then
wIndex = 1
end
end
if (key == keys.left) then
-- arrow left
textX = textX - 1
if (textX >= 1) then
if (textX < wIndex) or (textX >= w + wIndex) then
wIndex = textX
end
end
if (textY > 1) then
if (textX < 1) then
textY = textY - 1
textX = lines[textY]:len() + 1
wIndex = textX - w + 1
end
end
if (textX < 1) then
textX = 1
end
if (wIndex < 1) then
wIndex = 1
end
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
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,
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("")
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
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,
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 (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
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
self:updateDraw()
end
end
return true
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 (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
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
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
end
if (self.parent ~= nil) then
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
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()
for n = 1, h do
local text = ""
local bg = ""
local fg = ""
if (lines[n + hIndex - 1] ~= nil) then
text = lines[n + hIndex - 1]
fg = fgLines[n + hIndex - 1]
bg = bgLines[n + hIndex - 1]
end
text = text:sub(wIndex, w + wIndex - 1)
bg = bg:sub(wIndex, w + wIndex - 1)
fg = fg:sub(wIndex, w + wIndex - 1)
local space = w - text:len()
if (space < 0) then
space = 0
end
text = text .. rep(self.bgSymbol, space)
bg = bg .. rep(tHex[self.bgColor], space)
fg = fg .. rep(tHex[self.fgColor], space)
self.parent:setText(obx, oby + n - 1, text)
self.parent:setBG(obx, oby + n - 1, bg)
self.parent:setFG(obx, oby + n - 1, fg)
end
if(self:isFocused())then
local anchx, anchy = self:getAnchorPosition()
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
end
end
end
end,
init = function(self)
self.bgColor = self.parent:getTheme("TextfieldBG")
self.fgColor = self.parent:getTheme("TextfieldText")
self.parent:addEvent("mouse_click", 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)
end,
}
return setmetatable(object, base)
end

View File

@@ -1,4 +1,6 @@
local function Thread(name)
local xmlValue = require("utils").getValueFromXML
return function(name)
local object
local objectType = "Thread"
@@ -6,6 +8,18 @@ local function Thread(name)
local cRoutine
local isActive = false
local generateXMLEventFunction = function(self, str)
if(str:sub(1,1)=="#")then
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
if(o~=nil)and(o.internalObjetCall~=nil)then
return (function()o:internalObjetCall()end)
end
else
return self:getBaseFrame():getVariable(str)
end
return self
end
object = {
name = name,
getType = function(self)
@@ -18,6 +32,20 @@ local function Thread(name)
return self.name
end;
getBaseFrame = function(self)
if(self.parent~=nil)then
return self.parent:getBaseFrame()
end
return self
end;
setValuesByXMLData = function(self, data)
local f
if(xmlValue("thread", data)~=nil)then f = generateXMLEventFunction(self, xmlValue("thread", data)) end
if(xmlValue("start", data)~=nil)then if(xmlValue("start", data))and(f~=nil)then self:start(f) end end
return self
end,
start = function(self, f)
if (f == nil) then
error("Function provided to thread is nil")
@@ -31,6 +59,7 @@ local function Thread(name)
error("Thread Error Occurred - " .. result)
end
end
self.parent:addEvent("other_event", self)
return self
end;
@@ -43,6 +72,7 @@ local function Thread(name)
stop = function(self, f)
isActive = false
self.parent:removeEvent("other_event", self)
return self
end;

View File

@@ -1,19 +1,58 @@
local function Timer(name)
local basaltEvent = require("basaltEvent")
local xmlValue = require("utils").getValueFromXML
return function(name)
local objectType = "Timer"
local timer = 0
local savedRepeats = 0
local repeats = 0
local timerObj
local eventSystem = BasaltEvents()
local eventSystem = basaltEvent()
local timerIsActive = false
local generateXMLEventFunction = function(self, func, val)
local createF = function(str)
if(str:sub(1,1)=="#")then
local o = self:getBaseFrame():getDeepObject(str:sub(2,str:len()))
if(o~=nil)and(o.internalObjetCall~=nil)then
func(self,function()o:internalObjetCall()end)
end
else
func(self,self:getBaseFrame():getVariable(str))
end
end
if(type(val)=="string")then
createF(val)
elseif(type(val)=="table")then
for k,v in pairs(val)do
createF(v)
end
end
return self
end
local object = {
name = name,
getType = function(self)
return objectType
end;
setValuesByXMLData = function(self, data)
if(xmlValue("time", data)~=nil)then timer = xmlValue("time", data) end
if(xmlValue("repeat", data)~=nil)then savedRepeats = xmlValue("repeat", data) end
if(xmlValue("start", data)~=nil)then if(xmlValue("start", data))then self:start() end end
if(xmlValue("onCall", data)~=nil)then generateXMLEventFunction(self, self.onCall, xmlValue("onCall", data)) end
return self
end,
getBaseFrame = function(self)
if(self.parent~=nil)then
return self.parent:getBaseFrame()
end
return self
end;
getZIndex = function(self)
return 1
end;
@@ -35,6 +74,7 @@ local function Timer(name)
repeats = savedRepeats
timerObj = os.startTimer(timer)
timerIsActive = true
self.parent:addEvent("other_event", self)
return self
end;
@@ -47,6 +87,7 @@ local function Timer(name)
os.cancelTimer(timerObj)
end
timerIsActive = false
self.parent:removeEvent("other_event", self)
return self
end;

45
Basalt/theme.lua Normal file
View File

@@ -0,0 +1,45 @@
return { -- The default main theme for basalt!
BasaltBG = colors.lightGray,
BasaltText = colors.black,
FrameBG = colors.gray,
FrameText = colors.black,
ButtonBG = colors.gray,
ButtonText = colors.black,
CheckboxBG = colors.gray,
CheckboxText = colors.black,
InputBG = colors.gray,
InputText = colors.black,
TextfieldBG = colors.gray,
TextfieldText = colors.black,
ListBG = colors.gray,
ListText = colors.black,
MenubarBG = colors.gray,
MenubarText = colors.black,
DropdownBG = colors.gray,
DropdownText = colors.black,
RadioBG = colors.gray,
RadioText = colors.black,
SelectionBG = colors.black,
SelectionText = colors.lightGray,
GraphicBG = colors.black,
ImageBG = colors.black,
PaneBG = colors.black,
ProgramBG = colors.black,
ProgressbarBG = colors.gray,
ProgressbarText = colors.black,
ProgressbarActiveBG = colors.black,
ScrollbarBG = colors.lightGray,
ScrollbarText = colors.gray,
ScrollbarSymbolColor = colors.black,
SliderBG = false,
SliderText = colors.gray,
SliderSymbolColor = colors.black,
SwitchBG = colors.lightGray,
SwitchText = colors.gray,
SwitchBGSymbol = colors.black,
SwitchInactive = colors.red,
SwitchActive = colors.green,
LabelBG = false,
LabelText = 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,11 +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)
## Important Notice
#### Basalt has moved! We are now located at [Pyroxenium](https://github.com/Pyroxenium), please make sure to update your previous GitHub links, as they are now out of date. We apologize for any inconvenience.
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!
Basalt is still under developement and you may find bugs!
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).
## 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)
## Demo
<img src="https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/basaltPreview2.gif" width="300">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1282
basaltPackageManager.lua Normal file

File diff suppressed because one or more lines are too long

507
basaltPackager.lua Normal file
View File

@@ -0,0 +1,507 @@
-- This file is able to minify and create a single file out of a project folder
-- only works for basalt
-- The minify part is fully made by stravant and can be found here: https://github.com/stravant/LuaMinify/blob/master/RobloxPlugin/Minify.lua
-- Thanks to him for his awesome work!
--
-- Minify.lua
--
-- A compilation of all of the neccesary code to Minify a source file, all into one single
-- script for usage on Roblox. Needed to deal with Roblox' lack of `require`.
--
--The minify part is also minified, if you're looking for the packaging part, check out the bottom!
function lookupify(cd)for dd,__a in pairs(cd)do cd[__a]=true end;return cd end
function CountTable(cd)local dd=0;for __a in pairs(cd)do dd=dd+1 end;return dd end
function PrintTable(cd,dd)if cd.Print then return cd.Print()end;dd=dd or 0
local __a=(CountTable(cd)>1)local a_a=string.rep(' ',dd+1)
local b_a="{".. (__a and'\n'or'')
for c_a,d_a in pairs(cd)do
if type(d_a)~='function'then
b_a=b_a.. (__a and a_a or'')
if type(c_a)=='number'then elseif type(c_a)=='string'and
c_a:match("^[A-Za-z_][A-Za-z0-9_]*$")then b_a=b_a..c_a.." = "elseif
type(c_a)=='string'then b_a=b_a.."[\""..c_a.."\"] = "else b_a=b_a.."["..
tostring(c_a).."] = "end
if type(d_a)=='string'then b_a=b_a.."\""..d_a.."\""elseif type(d_a)==
'number'then b_a=b_a..d_a elseif type(d_a)=='table'then b_a=b_a..
PrintTable(d_a,dd+ (__a and 1 or 0))else
b_a=b_a..tostring(d_a)end;if next(cd,c_a)then b_a=b_a..","end;if __a then b_a=b_a..'\n'end end end;b_a=b_a..
(__a and string.rep(' ',dd)or'').."}"return b_a end;local bb=lookupify{' ','\n','\t','\r'}
local cb={['\r']='\\r',['\n']='\\n',['\t']='\\t',['"']='\\"',["'"]="\\'"}
local db=lookupify{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
local _c=lookupify{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
local ac=lookupify{'0','1','2','3','4','5','6','7','8','9'}
local bc=lookupify{'0','1','2','3','4','5','6','7','8','9','A','a','B','b','C','c','D','d','E','e','F','f'}
local cc=lookupify{'+','-','*','/','^','%',',','{','}','[',']','(',')',';','#'}
local dc=lookupify{'and','break','do','else','elseif','end','false','for','function','goto','if','in','local','nil','not','or','repeat','return','then','true','until','while'}
function LexLua(cd)local dd={}
local __a,a_a=pcall(function()local _aa=1;local aaa=1;local baa=1
local function caa()local cba=cd:sub(_aa,_aa)if cba=='\n'then baa=1
aaa=aaa+1 else baa=baa+1 end;_aa=_aa+1;return cba end
local function daa(cba)cba=cba or 0;return cd:sub(_aa+cba,_aa+cba)end;local function _ba(cba)local dba=daa()
for i=1,#cba do if dba==cba:sub(i,i)then return caa()end end end;local function aba(cba)
return error(">> :"..aaa..":"..
baa..": "..cba,0)end
local function bba()local cba=_aa
if daa()=='['then local dba=0;while
daa(dba+1)=='='do dba=dba+1 end
if daa(dba+1)=='['then for _=0,dba+1 do caa()end
local _ca=_aa
while true do if daa()==''then
aba("Expected `]"..string.rep('=',dba).."]` near <eof>.",3)end;local cca=true;if daa()==']'then for i=1,dba do if daa(i)~='='then
cca=false end end
if daa(dba+1)~=']'then cca=false end else cca=false end;if cca then break else
caa()end end;local aca=cd:sub(_ca,_aa-1)for i=0,dba+1 do caa()end
local bca=cd:sub(cba,_aa-1)return aca,bca else return nil end else return nil end end
while true do local cba=''
while true do local dca=daa()
if bb[dca]then cba=cba..caa()elseif
dca=='-'and daa(1)=='-'then caa()caa()cba=cba..'--'local _da,ada=bba()
if ada then cba=cba..ada else while daa()~='\n'and
daa()~=''do cba=cba..caa()end end else break end end;local dba=aaa;local _ca=baa
local aca=":"..aaa..":"..baa..":> "local bca=daa()local cca=nil
if bca==''then cca={Type='Eof'}elseif
_c[bca]or db[bca]or bca=='_'then local dca=_aa;repeat caa()bca=daa()until not
(_c[bca]or db[bca]or ac[bca]or bca=='_')
local _da=cd:sub(dca,_aa-1)
if dc[_da]then cca={Type='Keyword',Data=_da}else cca={Type='Ident',Data=_da}end elseif ac[bca]or(daa()=='.'and ac[daa(1)])then local dca=_aa
if bca=='0'and
daa(1)=='x'then caa()caa()while bc[daa()]do caa()end;if _ba('Pp')then
_ba('+-')while ac[daa()]do caa()end end else
while ac[daa()]do caa()end;if _ba('.')then while ac[daa()]do caa()end end;if _ba('Ee')then
_ba('+-')while ac[daa()]do caa()end end end;cca={Type='Number',Data=cd:sub(dca,_aa-1)}elseif bca=='\''or bca==
'\"'then local dca=_aa;local _da=caa()local ada=_aa;while true do local dda=caa()
if dda=='\\'then caa()elseif
dda==_da then break elseif dda==''then aba("Unfinished string near <eof>")end end;local bda=cd:sub(ada,
_aa-2)local cda=cd:sub(dca,_aa-1)
cca={Type='String',Data=cda,Constant=bda}elseif bca=='['then local dca,_da=bba()
if _da then cca={Type='String',Data=_da,Constant=dca}else
caa()cca={Type='Symbol',Data='['}end elseif _ba('>=<')then if _ba('=')then cca={Type='Symbol',Data=bca..'='}else
cca={Type='Symbol',Data=bca}end elseif _ba('~')then
if _ba('=')then
cca={Type='Symbol',Data='~='}else aba("Unexpected symbol `~` in source.",2)end elseif _ba('.')then
if _ba('.')then if _ba('.')then cca={Type='Symbol',Data='...'}else
cca={Type='Symbol',Data='..'}end else cca={Type='Symbol',Data='.'}end elseif _ba(':')then if _ba(':')then cca={Type='Symbol',Data='::'}else
cca={Type='Symbol',Data=':'}end elseif cc[bca]then caa()
cca={Type='Symbol',Data=bca}else local dca,_da=bba()if dca then cca={Type='String',Data=_da,Constant=dca}else
aba("Unexpected Symbol `"..
bca.."` in source.",2)end end;cca.LeadingWhite=cba;cca.Line=dba;cca.Char=_ca
cca.Print=function()
return"<".. (cca.Type..string.rep(' ',7 -#
cca.Type))..
" ".. (cca.Data or'').." >"end;dd[#dd+1]=cca;if cca.Type=='Eof'then break end end end)if not __a then return false,a_a end;local b_a={}local c_a={}local d_a=1
function b_a:Peek(_aa)_aa=_aa or 0;return dd[math.min(
#dd,d_a+_aa)]end
function b_a:Get()local _aa=dd[d_a]d_a=math.min(d_a+1,#dd)return _aa end;function b_a:Is(_aa)return b_a:Peek().Type==_aa end;function b_a:Save()c_a[
#c_a+1]=d_a end
function b_a:Commit()c_a[#c_a]=nil end;function b_a:Restore()d_a=c_a[#c_a]c_a[#c_a]=nil end
function b_a:ConsumeSymbol(_aa)
local aaa=self:Peek()
if aaa.Type=='Symbol'then if _aa then
if aaa.Data==_aa then self:Get()return true else return nil end else self:Get()return aaa end else return
nil end end
function b_a:ConsumeKeyword(_aa)local aaa=self:Peek()if
aaa.Type=='Keyword'and aaa.Data==_aa then self:Get()return true else return nil end end;function b_a:IsKeyword(_aa)local aaa=b_a:Peek()return
aaa.Type=='Keyword'and aaa.Data==_aa end
function b_a:IsSymbol(_aa)
local aaa=b_a:Peek()return aaa.Type=='Symbol'and aaa.Data==_aa end
function b_a:IsEof()return b_a:Peek().Type=='Eof'end;return true,b_a end
function ParseLua(cd)local dd,__a=LexLua(cd)if not dd then return false,__a end
local function a_a(ada)local bda=">> :"..
__a:Peek().Line..":"..__a:Peek().Char..": "..ada.."\n"local cda=0
for dda in
cd:gmatch("[^\n]*\n?")do if dda:sub(-1,-1)=='\n'then dda=dda:sub(1,-2)end;cda=
cda+1
if cda==__a:Peek().Line then bda=bda..">> `"..
dda:gsub('\t',' ').."`\n"for i=1,__a:Peek().Char
do local __b=dda:sub(i,i)
if __b=='\t'then bda=bda..' 'else bda=bda..' 'end end
bda=bda.." ^---"break end end;return bda end;local b_a=0;local c_a={}local d_a={'_','a','b','c','d'}
local function _aa(ada)local bda={}bda.Parent=ada
bda.LocalList={}bda.LocalMap={}
function bda:RenameVars()
for cda,dda in pairs(bda.LocalList)do local __b;b_a=0
repeat b_a=b_a+1;local a_b=b_a
__b=''while a_b>0 do local b_b=a_b%#d_a;a_b=(a_b-b_b)/#d_a
__b=__b..d_a[b_b+1]end until
not c_a[__b]and
not ada:GetLocal(__b)and not bda.LocalMap[__b]dda.Name=__b;bda.LocalMap[__b]=dda end end
function bda:GetLocal(cda)local dda=bda.LocalMap[cda]if dda then return dda end;if bda.Parent then
local __b=bda.Parent:GetLocal(cda)if __b then return __b end end;return nil end
function bda:CreateLocal(cda)local dda={}dda.Scope=bda;dda.Name=cda;dda.CanRename=true;bda.LocalList[#
bda.LocalList+1]=dda
bda.LocalMap[cda]=dda;return dda end;bda.Print=function()return"<Scope>"end;return bda end;local aaa;local baa
local function caa(ada)local bda=_aa(ada)if not __a:ConsumeSymbol('(')then return false,
a_a("`(` expected.")end;local cda={}local dda=false
while not
__a:ConsumeSymbol(')')do
if __a:Is('Ident')then
local c_b=bda:CreateLocal(__a:Get().Data)cda[#cda+1]=c_b;if not __a:ConsumeSymbol(',')then
if
__a:ConsumeSymbol(')')then break else return false,a_a("`)` expected.")end end elseif
__a:ConsumeSymbol('...')then dda=true
if not __a:ConsumeSymbol(')')then return false,
a_a("`...` must be the last argument of a function.")end;break else return false,a_a("Argument name or `...` expected")end end;local __b,a_b=baa(bda)if not __b then return false,a_b end;if not
__a:ConsumeKeyword('end')then
return false,a_a("`end` expected after function body")end;local b_b={}
b_b.AstType='Function'b_b.Scope=bda;b_b.Arguments=cda;b_b.Body=a_b;b_b.VarArg=dda;return true,b_b end
local function daa(ada)
if __a:ConsumeSymbol('(')then local bda,cda=aaa(ada)
if not bda then return false,cda end
if not __a:ConsumeSymbol(')')then return false,a_a("`)` Expected.")end;cda.ParenCount=(cda.ParenCount or 0)+1;return true,cda elseif
__a:Is('Ident')then local bda=__a:Get()local cda=ada:GetLocal(bda.Data)if not cda then
c_a[bda.Data]=true end;local dda={}dda.AstType='VarExpr'dda.Name=bda.Data
dda.Local=cda;return true,dda else return false,a_a("primary expression expected")end end
local function _ba(ada,bda)local cda,dda=daa(ada)if not cda then return false,dda end
while true do
if __a:IsSymbol('.')or
__a:IsSymbol(':')then local __b=__a:Get().Data;if not __a:Is('Ident')then return false,
a_a("<Ident> expected.")end;local a_b=__a:Get()
local b_b={}b_b.AstType='MemberExpr'b_b.Base=dda;b_b.Indexer=__b;b_b.Ident=a_b;dda=b_b elseif not
bda and __a:ConsumeSymbol('[')then local __b,a_b=aaa(ada)if not __b then
return false,a_b end;if not __a:ConsumeSymbol(']')then
return false,a_a("`]` expected.")end;local b_b={}b_b.AstType='IndexExpr'
b_b.Base=dda;b_b.Index=a_b;dda=b_b elseif not bda and __a:ConsumeSymbol('(')then local __b={}
while not
__a:ConsumeSymbol(')')do local b_b,c_b=aaa(ada)if not b_b then return false,c_b end
__b[#__b+1]=c_b
if not __a:ConsumeSymbol(',')then if __a:ConsumeSymbol(')')then break else return false,
a_a("`)` Expected.")end end end;local a_b={}a_b.AstType='CallExpr'a_b.Base=dda;a_b.Arguments=__b;dda=a_b elseif not bda and
__a:Is('String')then local __b={}__b.AstType='StringCallExpr'__b.Base=dda
__b.Arguments={__a:Get()}dda=__b elseif not bda and __a:IsSymbol('{')then local __b,a_b=aaa(ada)if not __b then
return false,a_b end;local b_b={}b_b.AstType='TableCallExpr'b_b.Base=dda
b_b.Arguments={a_b}dda=b_b else break end end;return true,dda end
local function aba(ada)
if __a:Is('Number')then local bda={}bda.AstType='NumberExpr'bda.Value=__a:Get()return
true,bda elseif __a:Is('String')then local bda={}bda.AstType='StringExpr'
bda.Value=__a:Get()return true,bda elseif __a:ConsumeKeyword('nil')then local bda={}bda.AstType='NilExpr'
return true,bda elseif __a:IsKeyword('false')or __a:IsKeyword('true')then local bda={}
bda.AstType='BooleanExpr'bda.Value=(__a:Get().Data=='true')return true,bda elseif
__a:ConsumeSymbol('...')then local bda={}bda.AstType='DotsExpr'return true,bda elseif __a:ConsumeSymbol('{')then local bda={}
bda.AstType='ConstructorExpr'bda.EntryList={}
while true do
if __a:IsSymbol('[')then __a:Get()local cda,dda=aaa(ada)
if not cda then return
false,a_a("Key Expression Expected")end
if not __a:ConsumeSymbol(']')then return false,a_a("`]` Expected")end
if not __a:ConsumeSymbol('=')then return false,a_a("`=` Expected")end;local __b,a_b=aaa(ada)if not __b then
return false,a_a("Value Expression Expected")end
bda.EntryList[#bda.EntryList+1]={Type='Key',Key=dda,Value=a_b}elseif __a:Is('Ident')then local cda=__a:Peek(1)
if
cda.Type=='Symbol'and cda.Data=='='then local dda=__a:Get()if not __a:ConsumeSymbol('=')then
return false,a_a("`=` Expected")end;local __b,a_b=aaa(ada)if not __b then return false,
a_a("Value Expression Expected")end
bda.EntryList[
#bda.EntryList+1]={Type='KeyString',Key=dda.Data,Value=a_b}else local dda,__b=aaa(ada)
if not dda then return false,a_a("Value Exected")end
bda.EntryList[#bda.EntryList+1]={Type='Value',Value=__b}end elseif __a:ConsumeSymbol('}')then break else local cda,dda=aaa(ada)
bda.EntryList[#bda.EntryList+1]={Type='Value',Value=dda}if not cda then return false,a_a("Value Expected")end end
if __a:ConsumeSymbol(';')or __a:ConsumeSymbol(',')then elseif
__a:ConsumeSymbol('}')then break else return false,a_a("`}` or table entry Expected")end end;return true,bda elseif __a:ConsumeKeyword('function')then local bda,cda=caa(ada)if not bda then
return false,cda end;cda.IsLocal=true;return true,cda else return _ba(ada)end end;local bba=lookupify{'-','not','#'}local cba=8
local dba={['+']={6,6},['-']={6,6},['%']={7,7},['/']={7,7},['*']={7,7},['^']={10,9},['..']={5,4},['==']={3,3},['<']={3,3},['<=']={3,3},['~=']={3,3},['>']={3,3},['>=']={3,3},['and']={2,2},['or']={1,1}}
local function _ca(ada,bda)local cda,dda
if bba[__a:Peek().Data]then local __b=__a:Get().Data
cda,dda=_ca(ada,cba)if not cda then return false,dda end;local a_b={}a_b.AstType='UnopExpr'
a_b.Rhs=dda;a_b.Op=__b;dda=a_b else cda,dda=aba(ada)if not cda then return false,dda end end
while true do local __b=dba[__a:Peek().Data]
if __b and __b[1]>bda then
local a_b=__a:Get().Data;local b_b,c_b=_ca(ada,__b[2])if not b_b then return false,c_b end;local d_b={}
d_b.AstType='BinopExpr'd_b.Lhs=dda;d_b.Op=a_b;d_b.Rhs=c_b;dda=d_b else break end end;return true,dda end;aaa=function(ada)return _ca(ada,0)end
local function aca(ada)local bda=nil
if
__a:ConsumeKeyword('if')then local cda={}cda.AstType='IfStatement'cda.Clauses={}
repeat local dda,__b=aaa(ada)if not dda then
return false,__b end;if not __a:ConsumeKeyword('then')then return false,
a_a("`then` expected.")end
local a_b,b_b=baa(ada)if not a_b then return false,b_b end
cda.Clauses[#cda.Clauses+1]={Condition=__b,Body=b_b}until not __a:ConsumeKeyword('elseif')
if __a:ConsumeKeyword('else')then local dda,__b=baa(ada)
if not dda then return false,__b end;cda.Clauses[#cda.Clauses+1]={Body=__b}end;if not __a:ConsumeKeyword('end')then
return false,a_a("`end` expected.")end;bda=cda elseif __a:ConsumeKeyword('while')then
local cda={}cda.AstType='WhileStatement'local dda,__b=aaa(ada)
if not dda then return false,__b end;if not __a:ConsumeKeyword('do')then
return false,a_a("`do` expected.")end;local a_b,b_b=baa(ada)
if not a_b then return false,b_b end;if not __a:ConsumeKeyword('end')then
return false,a_a("`end` expected.")end;cda.Condition=__b;cda.Body=b_b;bda=cda elseif
__a:ConsumeKeyword('do')then local cda,dda=baa(ada)if not cda then return false,dda end
if not
__a:ConsumeKeyword('end')then return false,a_a("`end` expected.")end;local __b={}__b.AstType='DoStatement'__b.Body=dda;bda=__b elseif
__a:ConsumeKeyword('for')then
if not __a:Is('Ident')then return false,a_a("<ident> expected.")end;local cda=__a:Get()
if __a:ConsumeSymbol('=')then local dda=_aa(ada)
local __b=dda:CreateLocal(cda.Data)local a_b,b_b=aaa(ada)if not a_b then return false,b_b end
if not
__a:ConsumeSymbol(',')then return false,a_a("`,` Expected")end;local c_b,d_b=aaa(ada)if not c_b then return false,d_b end;local _ab,aab
if
__a:ConsumeSymbol(',')then _ab,aab=aaa(ada)if not _ab then return false,aab end end;if not __a:ConsumeKeyword('do')then
return false,a_a("`do` expected")end;local bab,cab=baa(dda)
if not bab then return false,cab end;if not __a:ConsumeKeyword('end')then
return false,a_a("`end` expected")end;local dab={}
dab.AstType='NumericForStatement'dab.Scope=dda;dab.Variable=__b;dab.Start=b_b;dab.End=d_b;dab.Step=aab
dab.Body=cab;bda=dab else local dda=_aa(ada)
local __b={dda:CreateLocal(cda.Data)}
while __a:ConsumeSymbol(',')do if not __a:Is('Ident')then return false,
a_a("for variable expected.")end
__b[#__b+1]=dda:CreateLocal(__a:Get().Data)end;if not __a:ConsumeKeyword('in')then
return false,a_a("`in` expected.")end;local a_b={}local b_b,c_b=aaa(ada)if not b_b then
return false,c_b end;a_b[#a_b+1]=c_b
while __a:ConsumeSymbol(',')do
local bab,cab=aaa(ada)if not bab then return false,cab end;a_b[#a_b+1]=cab end;if not __a:ConsumeKeyword('do')then
return false,a_a("`do` expected.")end;local d_b,_ab=baa(dda)
if not d_b then return false,_ab end;if not __a:ConsumeKeyword('end')then
return false,a_a("`end` expected.")end;local aab={}
aab.AstType='GenericForStatement'aab.Scope=dda;aab.VariableList=__b;aab.Generators=a_b;aab.Body=_ab;bda=aab end elseif __a:ConsumeKeyword('repeat')then local cda,dda=baa(ada)
if not cda then return false,dda end;if not __a:ConsumeKeyword('until')then
return false,a_a("`until` expected.")end;local __b,a_b=aaa(ada)
if not __b then return false,a_b end;local b_b={}b_b.AstType='RepeatStatement'b_b.Condition=a_b;b_b.Body=dda;bda=b_b elseif
__a:ConsumeKeyword('function')then if not __a:Is('Ident')then
return false,a_a("Function name expected")end;local cda,dda=_ba(ada,true)if not cda then
return false,dda end;local __b,a_b=caa(ada)if not __b then return false,a_b end
a_b.IsLocal=false;a_b.Name=dda;bda=a_b elseif __a:ConsumeKeyword('local')then
if __a:Is('Ident')then
local cda={__a:Get().Data}while __a:ConsumeSymbol(',')do if not __a:Is('Ident')then return false,
a_a("local var name expected")end
cda[#cda+1]=__a:Get().Data end;local dda={}if
__a:ConsumeSymbol('=')then
repeat local a_b,b_b=aaa(ada)if not a_b then return false,b_b end
dda[#dda+1]=b_b until not __a:ConsumeSymbol(',')end;for a_b,b_b in
pairs(cda)do cda[a_b]=ada:CreateLocal(b_b)end
local __b={}__b.AstType='LocalStatement'__b.LocalList=cda;__b.InitList=dda;bda=__b elseif
__a:ConsumeKeyword('function')then if not __a:Is('Ident')then
return false,a_a("Function name expected")end;local cda=__a:Get().Data
local dda=ada:CreateLocal(cda)local __b,a_b=caa(ada)if not __b then return false,a_b end;a_b.Name=dda
a_b.IsLocal=true;bda=a_b else
return false,a_a("local var or function def expected")end elseif __a:ConsumeSymbol('::')then if not __a:Is('Ident')then return false,
a_a('Label name expected')end
local cda=__a:Get().Data
if not __a:ConsumeSymbol('::')then return false,a_a("`::` expected")end;local dda={}dda.AstType='LabelStatement'dda.Label=cda;bda=dda elseif
__a:ConsumeKeyword('return')then local cda={}
if not __a:IsKeyword('end')then local __b,a_b=aaa(ada)
if __b then cda[1]=a_b;while
__a:ConsumeSymbol(',')do local b_b,c_b=aaa(ada)if not b_b then return false,c_b end
cda[#cda+1]=c_b end end end;local dda={}dda.AstType='ReturnStatement'dda.Arguments=cda;bda=dda elseif
__a:ConsumeKeyword('break')then local cda={}cda.AstType='BreakStatement'bda=cda elseif __a:IsKeyword('goto')then
if not
__a:Is('Ident')then return false,a_a("Label expected")end;local cda=__a:Get().Data;local dda={}dda.AstType='GotoStatement'
dda.Label=cda;bda=dda else local cda,dda=_ba(ada)if not cda then return false,dda end
if
__a:IsSymbol(',')or __a:IsSymbol('=')then
if(dda.ParenCount or 0)>0 then return false,
a_a("Can not assign to parenthesized expression, is not an lvalue")end;local __b={dda}
while __a:ConsumeSymbol(',')do local _ab,aab=_ba(ada)
if not _ab then return false,aab end;__b[#__b+1]=aab end
if not __a:ConsumeSymbol('=')then return false,a_a("`=` Expected.")end;local a_b={}local b_b,c_b=aaa(ada)if not b_b then return false,c_b end;a_b[1]=c_b;while
__a:ConsumeSymbol(',')do local _ab,aab=aaa(ada)if not _ab then return false,aab end
a_b[#a_b+1]=aab end;local d_b={}
d_b.AstType='AssignmentStatement'd_b.Lhs=__b;d_b.Rhs=a_b;bda=d_b elseif
dda.AstType=='CallExpr'or
dda.AstType=='TableCallExpr'or dda.AstType=='StringCallExpr'then local __b={}__b.AstType='CallStatement'__b.Expression=dda;bda=__b else return false,
a_a("Assignment Statement Expected")end end;bda.HasSemicolon=__a:ConsumeSymbol(';')return true,bda end
local bca=lookupify{'end','else','elseif','until'}
baa=function(ada)local bda={}bda.Scope=_aa(ada)bda.AstType='Statlist'local cda={}
while not
bca[__a:Peek().Data]and not __a:IsEof()do
local dda,__b=aca(bda.Scope)if not dda then return false,__b end;cda[#cda+1]=__b end;bda.Body=cda;return true,bda end;local function cca()local ada=_aa()return baa(ada)end;local dca,_da=cca()
return dca,_da end
local _d=lookupify{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}
local ad=lookupify{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
local bd=lookupify{'0','1','2','3','4','5','6','7','8','9'}
function Format_Mini(cd)local dd,__a;local a_a=0
local function b_a(d_a,_aa,aaa)
if a_a>150 then a_a=0;return d_a.."\n".._aa end;aaa=aaa or' 'local baa,caa=d_a:sub(-1,-1),_aa:sub(1,1)
if
ad[baa]or _d[baa]or baa=='_'then
if not
(ad[caa]or _d[caa]or caa=='_'or bd[caa])then return d_a.._aa elseif caa=='('then
return d_a..aaa.._aa else return d_a..aaa.._aa end elseif bd[baa]then
if caa=='('then return d_a.._aa else return d_a..aaa.._aa end elseif baa==''then return d_a.._aa else
if caa=='('then return d_a..aaa.._aa else return d_a.._aa end end end
__a=function(d_a)local _aa=string.rep('(',d_a.ParenCount or 0)
if
d_a.AstType=='VarExpr'then if d_a.Local then _aa=_aa..d_a.Local.Name else
_aa=_aa..d_a.Name end elseif d_a.AstType=='NumberExpr'then _aa=_aa..
d_a.Value.Data elseif d_a.AstType=='StringExpr'then
_aa=_aa..d_a.Value.Data elseif d_a.AstType=='BooleanExpr'then _aa=_aa..tostring(d_a.Value)elseif
d_a.AstType=='NilExpr'then _aa=b_a(_aa,"nil")elseif d_a.AstType=='BinopExpr'then
_aa=b_a(_aa,__a(d_a.Lhs))_aa=b_a(_aa,d_a.Op)_aa=b_a(_aa,__a(d_a.Rhs))elseif d_a.AstType==
'UnopExpr'then _aa=b_a(_aa,d_a.Op)
_aa=b_a(_aa,__a(d_a.Rhs))elseif d_a.AstType=='DotsExpr'then _aa=_aa.."..."elseif d_a.AstType=='CallExpr'then _aa=_aa..
__a(d_a.Base)_aa=_aa.."("for i=1,#d_a.Arguments do _aa=_aa..
__a(d_a.Arguments[i])
if i~=#d_a.Arguments then _aa=_aa..","end end;_aa=_aa..")"elseif d_a.AstType==
'TableCallExpr'then _aa=_aa..__a(d_a.Base)_aa=_aa..
__a(d_a.Arguments[1])elseif d_a.AstType=='StringCallExpr'then
_aa=_aa..__a(d_a.Base)_aa=_aa..d_a.Arguments[1].Data elseif
d_a.AstType=='IndexExpr'then
_aa=_aa..__a(d_a.Base).."["..__a(d_a.Index).."]"elseif d_a.AstType=='MemberExpr'then _aa=_aa..__a(d_a.Base)..
d_a.Indexer..d_a.Ident.Data elseif
d_a.AstType=='Function'then d_a.Scope:RenameVars()
_aa=_aa.."function("
if#d_a.Arguments>0 then for i=1,#d_a.Arguments do
_aa=_aa..d_a.Arguments[i].Name
if i~=#d_a.Arguments then _aa=_aa..","elseif d_a.VarArg then _aa=_aa..",..."end end elseif
d_a.VarArg then _aa=_aa.."..."end;_aa=_aa..")"_aa=b_a(_aa,dd(d_a.Body))
_aa=b_a(_aa,"end")elseif d_a.AstType=='ConstructorExpr'then _aa=_aa.."{"
for i=1,#d_a.EntryList do
local aaa=d_a.EntryList[i]
if aaa.Type=='Key'then _aa=_aa.."["..
__a(aaa.Key).."]="..__a(aaa.Value)elseif aaa.Type==
'Value'then _aa=_aa..__a(aaa.Value)elseif aaa.Type=='KeyString'then
_aa=_aa..
aaa.Key.."="..__a(aaa.Value)end;if i~=#d_a.EntryList then _aa=_aa..","end end;_aa=_aa.."}"end
_aa=_aa..string.rep(')',d_a.ParenCount or 0)a_a=a_a+#_aa;return _aa end
local c_a=function(d_a)local _aa=''
if d_a.AstType=='AssignmentStatement'then
for i=1,#d_a.Lhs do
_aa=_aa..__a(d_a.Lhs[i])if i~=#d_a.Lhs then _aa=_aa..","end end;if#d_a.Rhs>0 then _aa=_aa.."="
for i=1,#d_a.Rhs do
_aa=_aa..__a(d_a.Rhs[i])if i~=#d_a.Rhs then _aa=_aa..","end end end elseif
d_a.AstType=='CallStatement'then _aa=__a(d_a.Expression)elseif d_a.AstType=='LocalStatement'then
_aa=_aa.."local "
for i=1,#d_a.LocalList do _aa=_aa..d_a.LocalList[i].Name;if i~=#
d_a.LocalList then _aa=_aa..","end end
if#d_a.InitList>0 then _aa=_aa.."="for i=1,#d_a.InitList do _aa=_aa..
__a(d_a.InitList[i])
if i~=#d_a.InitList then _aa=_aa..","end end end elseif d_a.AstType=='IfStatement'then
_aa=b_a("if",__a(d_a.Clauses[1].Condition))_aa=b_a(_aa,"then")
_aa=b_a(_aa,dd(d_a.Clauses[1].Body))
for i=2,#d_a.Clauses do local aaa=d_a.Clauses[i]
if aaa.Condition then
_aa=b_a(_aa,"elseif")_aa=b_a(_aa,__a(aaa.Condition))
_aa=b_a(_aa,"then")else _aa=b_a(_aa,"else")end;_aa=b_a(_aa,dd(aaa.Body))end;_aa=b_a(_aa,"end")elseif d_a.AstType=='WhileStatement'then
_aa=b_a("while",__a(d_a.Condition))_aa=b_a(_aa,"do")_aa=b_a(_aa,dd(d_a.Body))
_aa=b_a(_aa,"end")elseif d_a.AstType=='DoStatement'then _aa=b_a(_aa,"do")
_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"end")elseif d_a.AstType=='ReturnStatement'then _aa="return"
for i=1,#d_a.Arguments
do _aa=b_a(_aa,__a(d_a.Arguments[i]))if i~=
#d_a.Arguments then _aa=_aa..","end end elseif d_a.AstType=='BreakStatement'then _aa="break"elseif d_a.AstType=='RepeatStatement'then
_aa="repeat"_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"until")
_aa=b_a(_aa,__a(d_a.Condition))elseif d_a.AstType=='Function'then d_a.Scope:RenameVars()if d_a.IsLocal then
_aa="local"end;_aa=b_a(_aa,"function ")if d_a.IsLocal then
_aa=_aa..d_a.Name.Name else _aa=_aa..__a(d_a.Name)end;_aa=
_aa.."("
if#d_a.Arguments>0 then
for i=1,#d_a.Arguments do _aa=_aa..
d_a.Arguments[i].Name;if i~=#d_a.Arguments then _aa=_aa..","elseif d_a.VarArg then
_aa=_aa..",..."end end elseif d_a.VarArg then _aa=_aa.."..."end;_aa=_aa..")"_aa=b_a(_aa,dd(d_a.Body))
_aa=b_a(_aa,"end")elseif d_a.AstType=='GenericForStatement'then d_a.Scope:RenameVars()
_aa="for "
for i=1,#d_a.VariableList do
_aa=_aa..d_a.VariableList[i].Name;if i~=#d_a.VariableList then _aa=_aa..","end end;_aa=_aa.." in"
for i=1,#d_a.Generators do
_aa=b_a(_aa,__a(d_a.Generators[i]))if i~=#d_a.Generators then _aa=b_a(_aa,',')end end;_aa=b_a(_aa,"do")_aa=b_a(_aa,dd(d_a.Body))
_aa=b_a(_aa,"end")elseif d_a.AstType=='NumericForStatement'then _aa="for "_aa=_aa..
d_a.Variable.Name.."="_aa=_aa..
__a(d_a.Start)..","..__a(d_a.End)if d_a.Step then
_aa=_aa..","..__a(d_a.Step)end;_aa=b_a(_aa,"do")
_aa=b_a(_aa,dd(d_a.Body))_aa=b_a(_aa,"end")end;a_a=a_a+#_aa;return _aa end
dd=function(d_a)local _aa=''d_a.Scope:RenameVars()for aaa,baa in pairs(d_a.Body)do
_aa=b_a(_aa,c_a(baa),';')end;return _aa end;cd.Scope:RenameVars()return dd(cd)end
local minify = function(cd)local dd,__a=ParseLua(cd)if not dd then return false,__a end
return true,Format_Mini(__a)end
-- Packaging part:
local args = table.pack(...)
local projectPath = args[1] or "Basalt"
local minifyProject = args[2]=="true" and true or false
local outputFileName = args[3] or "basalt.lua"
assert(fs.isDir(projectPath), "Unable to find directory: "..projectPath)
local projectFiles = {
"objects",
"libraries",
"Frame.lua",
"loadObjects.lua",
"Object.lua",
"theme.lua",
}
local subDirs = {
"objects", "libraries"
}
local mainFile = "main.lua"
local outputFile = io.open(outputFileName, "w")
if(outputFile==nil)then
error("Can't open file "..outputFileName)
end
outputFile:write([[
local project = {}
local packaged = true
local baseRequire = require
local require = function(path)
for _,v in pairs(project)do
for name,b in pairs(v)do
if(name==path)then
return b()
end
end
end
return baseRequire(path);
end
local getProject = function(subDir)
if(subDir~=nil)then
return project[subDir]
end
return project
end
]])
for k,v in pairs(subDirs)do
outputFile:write("project['"..v.."'] = {}")
end
outputFile:write("project['default'] = {}")
local function writeNewPackage(subdir, name, path)
if not(fs.isDir(path))then
outputFile:write("project['"..subdir.."']['"..name.."'] = ".."function(...)")
local file = io.open(path, "r")
local fileData = file:read("*all")
if(minifyProject)then
local success, data = minify(fileData)
if(success)then
outputFile:write(data:gsub("]]", "] ]"):gsub("]]", "] ]").."\n")
else
print("Error: Can't minify "..path)
end
else
outputFile:write(fileData:gsub("]]", "] ]"):gsub("]]", "] ]").."\n")
end
file:close()
outputFile:write("end; \n")
end
end
for _,v in pairs(projectFiles)do
if(fs.isDir(fs.combine(projectPath, v)))then
for _,b in pairs(fs.list(fs.combine(projectPath, v)))do
writeNewPackage(v, b:gsub(".lua", ""), fs.combine(fs.combine(projectPath, v), b))
end
else
writeNewPackage("default", v:gsub(".lua", ""), fs.combine(projectPath, v))
end
end
local main = io.open(fs.combine(projectPath, mainFile), "r")
local mainData = main:read("*all")
if(minifyProject)then
local success,data = minify(mainData)
if(success)then
outputFile:write(data)
else
print("Error: Can't minify "..fs.combine(projectPath, mainFile).." "..data)
end
else
outputFile:write(mainData)
end
main:close()
outputFile:close()

View File

@@ -9,7 +9,7 @@ Here you can find information about how to use Basalt as well as examples of fun
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).
## Quick Demo
![Preview](https://media0.giphy.com/media/fvmNPshXKeU7FFA9iA/giphy.gif)
<img src="https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/basaltPreview2.gif" width="600">
## Questions & Bugs
@@ -21,4 +21,4 @@ Additionally, if you have questions about Basalt or how to make use of it, feel
Feel free to join our [discord](https://discord.gg/yNNnmBVBpE)!
<br><br>
<br><br>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

View File

@@ -3,33 +3,29 @@
- [Quick Start](home/Quick-Start.md)
- [Installer](home/installer)
- 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)
- [Text Field](objects/Textfield)
- [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)
- [Timer](objects/Timer)
- Events
- [Mouse Events](events/mouseEvents.md)
- [Keyboard Events](events/keyEvents.md)
- [Other Events](events/otherEvents.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)

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 = dofile("basalt.lua")
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 = dofile("basalt.lua")
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 manipulate them. There are 2 possible mouse events you can add to almost every visual object.
# onClick
`onClick(self, 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 = dofile("basalt.lua")
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, 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 = dofile("basalt.lua")
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, 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 = dofile("basalt.lua")
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, 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 = dofile("basalt.lua")
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,75 +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 = dofile("basalt.lua")
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 = dofile("basalt.lua")
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 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 mainFrame = basalt.createFrame("myFirstFrame"):show()
local aButton = mainFrame:addButton("exampleButton"):setPosition(3,3):onGetFocus(
function(self)
basalt.debug("Welcome back!")
end
):show()
```

View File

@@ -1,30 +1,52 @@
Basalt aims to be a relatively small, easy to use framework.
## HowTo Use
Accordingly, we have provided an installation script.
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`.
Just use the following command in any CC:Tweaked shell:
## 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 `basalt.lua` to your local directory
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.
To load the framework, make use of the following snippet
```lua
--> For those who are unfamiliar with lua, dofile executes the code in the referenced file
local basalt = dofile("basalt.lua")
```
### 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 = dofile("basalt.lua") --> Load the Basalt framework
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
@@ -53,7 +75,7 @@ basalt.autoUpdate() --> Basalt#autoUpdate starts the event listener to detect us
```
If you're like us and strive for succinct and beautiful code, here is a cleaner implementation of the code above:
```lua
local basalt = dofile("basalt.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"
@@ -67,4 +89,4 @@ local button = mainFrame --> Basalt returns an instance of the object on most me
:show()
basalt.autoUpdate()
```
```

View File

@@ -6,11 +6,11 @@ This is just a script which helps you to setup your program to automatically ins
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.lua
local filePath = "basalt.lua" --here you can change the file path default: basalt
if not(fs.exists(filePath))then
shell.run("pastebin run ESs1mg7P "..filePath) -- this is an alternative to the wget command
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
end
local basalt = dofile(filePath) -- here you can change the variablename in any variablename you want default: basalt
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
```
## Advanced Installer
@@ -18,7 +18,7 @@ This is a visual version, it asks the user if he wants to install basalt.lua (if
![](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.lua
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()
@@ -51,7 +51,7 @@ if not(fs.exists(filePath))then
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 "..filePath)
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", ""))
_installerWindow.setVisible(false)
term.clear()
break
@@ -69,6 +69,6 @@ if not(fs.exists(filePath))then
term.clear()
end
local basalt = dofile(filePath) -- here you can change the variablename in any variablename you want default: basalt
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
------------------------------
```

View File

@@ -1,73 +1,21 @@
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.<br>
Right now animation is a class which makes use of the timer event.<br>
You can find more information below:
| | |
|---|---|
|[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
|[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
## add
Adds a new function to an animation
#### Parameters:
1. `function` The function containing animation logic
# Events
#### 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("myFirstFrame"):show()
local testButton = mainFrame:addButton("myTestButton"):show()
local aAnimation = mainFrame:addAnimation("anim1"):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("myFirstFrame"):show()
local testButton = mainFrame:addButton("myTestButton"):show()
local aAnimation = mainFrame:addAnimation("anim1"):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("myFirstFrame"):show()
local testButton = mainFrame:addButton("myTestButton"):show()
local aAnimation = mainFrame:addAnimation("anim1"):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("myFirstFrame"):show()
local testButton = mainFrame:addButton("myTestButton"):show()
local aAnimation = mainFrame:addAnimation("anim1"):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()
```
| | |
|---|---|
|[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,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. `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>
```

View File

@@ -0,0 +1,28 @@
## 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>
```

View File

@@ -0,0 +1,28 @@
## 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>
```

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 @@
## 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,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,128 +1,37 @@
To start using Basalt you have to do the following line of code:
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 = dofile("basalt.lua")`
`local basalt = require("basalt")`
remember you need the basalt.lua file on your computer!
require loads the UI Framework into your project.
Now you are able to use the following functions:
Now you are able to access the following list of methods:
## basalt.createFrame
Create a base-frame (main frame)
#### Parameters:
1. `string` name
| | |
|---|---|
|[createFrame](objects/Basalt/createFrame.md)|Creates a new base frame
|[removeFrame](objects/Basalt/removeFrame.md)|Removes a previously created base frame
|[getFrame](objects/Basalt/getFrame.md)|Returns a frame object by it's id
|[getActiveFrame](objects/Basalt/getActiveFrame.md)|Returns the currently active base frame
|[autoUpdate](objects/Basalt/autoUpdate.md)|Starts the event and draw listener
|[update](objects/Basalt/update.md)|Starts the event and draw listener once
|[stopUpdate](objects/Basalt/stopUpdate.md)|Stops the currently active event and draw listener
|[isKeyDown](objects/Basalt/isKeyDown.md)|Returns if the key is held down
|[debug](objects/Basalt/debug.md)|Writes something into the debug console
|[log](objects/Basalt/log.md)|Writes something into the log file
|[setTheme](objects/Basalt/setTheme.md)|Changes the base theme of basalt
|[setVariable](objects/Basalt/setVariable.md)|Sets a variable which you can access via XML
|[schedule](objects/Basalt/schedule.md)|Schedules a new task
#### Returns:
1. `frame` object
# Examples
#### Usage:
* Create and show a frame with id "myFirstFrame"
Here is a lua example on how to create a empty base frame and start basalt's listener.
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
```
local basalt = require("basalt") -- we load the UI Framework into our project
## basalt.removeFrame
Removes a base frame
local main = basalt.createFrame() -- we create a base frame - on that frame we are able to add object's
#### Parameters:
1. `string` name
#### Usage:
* Removes the previously created frame with id "myFirstFrame"
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
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")
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("myFirstFrame"):show()
basalt.debug(basalt.getActiveFrame():getName()) -- returns myFirstFrame
```
## 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("myFirstFrame"):show()
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("myFirstFrame"):show()
local aButton = mainFrame:addButton("myButton"):setPosition(2,2):show()
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 updates and clears the terminal
```lua
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aButton = mainFrame:addButton("myButton"):setPosition(2,2):setText("Stop Basalt!"):show()
aButton:onClick(function()
basalt.stopUpdate()
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)<br>
#### Usage:
* Prints "Hello! ^-^" to the debug console
```lua
basalt.debug("Hello! ", "^-^")
```
-- here we would add additional object's
basalt.autoUpdate() -- we start listening to incoming events and draw stuff on the screen
```

View File

@@ -0,0 +1,12 @@
## 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.
#### Usage:
* Enable the basalt listeners, otherwise the screen will not continue to update
```lua
local main = basalt.createFrame()
basalt.autoUpdate()
```

View File

@@ -0,0 +1,27 @@
## 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")
```

View File

@@ -0,0 +1,22 @@
## 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.
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! ", "^-^")
```
* Changes the debug label's anchor
```lua
basalt.debugLabel:setAnchor("topLeft") -- default anchor is bottomLeft
basalt.debug("Hello!")
```

View File

@@ -0,0 +1,12 @@
## 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,23 @@
## basalt.getFrame
Returns a base frame by the given id
#### Parameters:
1. `string` id
#### Returns:
1. `frame` object
#### 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)
```

View File

@@ -0,0 +1,21 @@
## 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 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,15 @@
## 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!")
```

View File

@@ -0,0 +1,17 @@
## basalt.removeFrame
Removes the base frame by it's id. This only works for base-frames.
#### Parameters:
1. `string` id
#### Usage:
* Removes the previously created frame with id "myFirstFrame"
```lua
local main = basalt.createFrame("firstBaseFrame")
local main2 = basalt.createFrame("secondBaseFrame")
main:addButton()
:setText("Remove")
:onClick(function()
basalt.removeFrame(main2:getName()) -- you can use main2:getName() to find out the id or just use "secondBaseFrame"
end)
```

View File

@@ -0,0 +1,28 @@
## 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))
```

View File

@@ -0,0 +1,15 @@
## 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,
...,
})
```

View File

@@ -0,0 +1,17 @@
## 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" />
```

View File

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

View File

@@ -0,0 +1,18 @@
## 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()
local aButton = mainFrame:addButton():setPosition(2,2)
while true do
local ev = table.pack(os.pullEventRaw())
basalt.update(table.unpack(ev))
end
```

View File

@@ -1,24 +1,37 @@
Buttons are objects, which execute function by clicking on them
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.
The following list is only available to buttons: <br>
Remember button also inherits from [Object](objects/Object.md)
[Object](objects/Object.md) methods also apply for buttons.
## setText
Sets the displayed button text
| | |
|---|---|
|[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
# Example
This is a example on how you would create a fully working button:
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aButton = mainFrame:addButton("myFirstButton"):setText("Click"):show() -- you could also use :setValue() instead of :setText() - no difference
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
basalt.debug("Left mousebutton got clicked!")
end
end)
```
#### Parameters: string text<br>
#### Returns: self<br>
# Examples
Add a onClick event:
and this would be the xml way:
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aButton = mainFrame:addButton("myFirstButton"):setText("Click"):onClick(function(self,event,button,x,y)
if(event=="mouse_click")and(button==1)then
basalt.debug("Left mousebutton got clicked!")
end
end):show()
local main = 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)
```
```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,13 +1,36 @@
With checkbox, 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.
Here are all possible functions available for checkbox:<be>
Remember button 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
Create a onChange event:
# Example
This is how you would create a event which gets fired as soon as the value gets changed:
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aCheckbox = mainFrame:addCheckbox("myFirstCheckbox"):onChange(function(self) basalt.debug("The value got changed into "..self:getValue()) end):show()
local main = basalt.createFrame()
local aCheckbox = main:addCheckbox()
local function checkboxChange(self)
local checked = self:getValue()
basalt.debug("The value got changed into ", checked)
end
aCheckbox:onChange(checkboxChange)
```
also possible via xml:
```lua
local main = basalt.createFrame():addLayout("example.xml")
basalt.setVariable("checkboxChange", function(self)
local checked = self:getValue()
basalt.debug("The value got changed into ", checked)
end)
```
```xml
<checkbox onChange="checkboxChange" />
```

View File

View File

@@ -1,178 +1,31 @@
Dropdowns are objects where you can create endless entrys the user can click on a button and it opens a "list" where the user can choose a entry
Dropdowns are objects where the user can click on a button, this will open a list where the user can choose from.
Here is a example of how to create a standard dropdown:
[Object](objects/Object.md) methods also apply for dropdowns.
| | |
|---|---|
|[addItem](objects/Dropdown/addItem.md)|Adds a new item into the list
|[removeItem](objects/Dropdown/removeItem.md)|Removes a item from the list
|[editItem](objects/Dropdown/editItem.md)|Changes a already existing item in the list
|[getItem](objects/Dropdown/getItem.md)|Returns a item by its index
|[getItemCount](objects/Dropdown/getItemCount.md)|Returns the item count
|[getAll](objects/Dropdown/getAll.md)|Returns the entire list as a table
|[selectItem](objects/Dropdown/selectItem.md)|Selects a item
|[clear](objects/Dropdown/clear.md)|Makes the entire list empty
|[getItemIndex](objects/Dropdown/getItemIndex.md)|Returns the currently active item index
|[setSelectedItem](objects/Dropdown/setSelectedItem.md)|Changes the default bg and fg, when the user selects a item
|[setOffset](objects/Dropdown/setOffset.md)|Changes the list offset
|[getOffset](objects/Dropdown/getOffset.md)|Returns the current offset
|[setDropdownSize](objects/Dropdown/setDropdownSize.md)|Changes the dropdown size
A item-table in dropdowns looks like the following example:
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
```
Here are all possible functions available for dropdowns: <br>
Remember Dropdown also inherits from [Object](objects/Object.md)
## addItem
Adds a item to the dropdown
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
```
#### Parameters: string text, number bgcolor, number fgcolor, any ... - (text is the displayed text, bgcolor and fgcolors the colors of background/text and args (...) is something dynamic, you wont see them but if you require some more information per item you can use that)<br>
#### Returns: self<br>
## removeItem
Removes a item from the dropdown
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:removeItem(2)
```
#### Parameters: number index<br>
#### Returns: self<br>
## editItem
Edits a item on the dropdown
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:editItem(3,"3. Edited Entry",colors.yellow,colors.green)
```
#### Parameters: number index, string text, number bgcolor, number fgcolor, any ...<br>
#### Returns: self<br>
## setScrollable
Makes the dropdown scrollable
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:setScrollable(true)
```
#### Parameters: boolean isScrollable<br>
#### Returns: self<br>
## selectItem
selects a item in the dropdown (same as a player would click on a item)
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:selectItem(1)
```
#### Parameters: number index<br>
#### Returns: self<br>
## clear
clears the entire list (dropdown)
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:clear()
```
#### Parameters: -<br>
#### Returns: self<br>
## getItemIndex
returns the item index of the currently selected item
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:getItemIndex()
```
#### Parameters: -<br>
#### Returns: number index<br>
## setSelectedItem
Sets the background of the item which is currently selected
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:setSelectedItem(colors.green, colors.blue)
```
#### Parameters: number bgcolor, number fgcolor, boolean isActive (isActive means if different colors for selected item should be used)<br>
#### Returns: self<br>
## setOffset
sets the dropdown offset (will automatically change if scrolling is active)
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:setOffset(3)
```
#### Parameters: number offsetValue<br>
#### Returns: self<br>
## getOffset
returns the current offset
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:getOffset()
```
#### Parameters: -<br>
#### Returns: number offsetValue<br>
## getOffset
returns the current offset
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:getOffset()
```
#### Parameters: -<br>
#### Returns: number offsetValue<br>
## setDropdownSize
sets the dropdown size (if you click on the button)
```lua
local mainFrame = basalt.createFrame("myFirstFrame"):show()
local aDropdown = mainFrame:addDropdown("myFirstDropdown"):show()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:setDropdownSize(12, 4)
```
#### Parameters: number width, number height<br>
#### Returns: self<br>
item = {
text="1. Entry", -- the text its showing
bgCol=colors.black, -- the background color
fgCol=colors.white -- the foreground color
args = {} -- custom args you want to pass, which you will be able to access in for example onChange events
}
```

View File

@@ -0,0 +1,28 @@
## addItem
Adds a item into the dropdown
#### Parameters:
1. `string` The entry name
2. `number|color` unique default background color - optional
3. `number|color` unique default text color - optional
4. `any` any value - you could access this later in a :onChange() event (you need to use :getValue()) - optional
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a default dropdown with 3 entries
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
```
```xml
<dropdown>
<item><text>1. Entry</text></item>
<item><text>2. Entry</text><bg>yellow</bg></item>
<item><text>3. Entry</text><bg>yellow</bg><fg>green</fg></item>
</dropdown>
```

View File

@@ -0,0 +1,16 @@
## clear
Removes all items.
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a default dropdown with 3 entries and removes them immediatley. Which makes no sense.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:clear()
```

View File

@@ -0,0 +1,23 @@
## editItem
Edits a item from the dropdown
#### Parameters:
1. `number` The index which should be edited
2. `string` The new item name
3. `number` the new item background color - optional
4. `number` The new item text color - optional
5. `any` New additional information - optional
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a default dropdown with 3 entries and edits the second one.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:editItem(2, "Still 2. Entry", colors.red)
```

View File

@@ -0,0 +1,16 @@
## getAll
Returns all items as table
#### Returns:
1. `table` All items
#### Usage:
* Creates a default menubar with 3 entries and prints a table.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
basalt.debug(aDropdown:getAll())
```

View File

@@ -0,0 +1,19 @@
## getItem
Returns a item by index
#### Parameters:
1. `number` The index which should be returned
#### Returns:
1. `table` The item table example: {text="1. Entry", bgCol=colors.black, fgCol=colors.white}
#### Usage:
* Creates a default dropdown with 3 entries and edits the second one.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
basalt.debug(aDropdown:getItem(2).text)
```

View File

@@ -0,0 +1,16 @@
## getItemCount
Returns the current item count
#### Returns:
1. `number` The item list count
#### Usage:
* Creates a default dropdown with 3 entries and prints the current item count.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
basalt.debug(aDropdown:getItemCount())
```

View File

@@ -0,0 +1,17 @@
## getItemIndex
returns the item index of the currently selected item
#### Returns:
1. `number` The current index
#### Usage:
* Creates a default dropdown with 3 entries selects the second entry and prints the currently selected index.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:selectItem(2)
basalt.debug(aDropdown:getItemIndex())
```

View File

@@ -0,0 +1,20 @@
## getOffset
Returns the current index offset
#### Returns:
1. `number` offset value
#### Usage:
* Creates a default dropdown with 6 entries and sets the offset to 3, also prints the current offset.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
:addItem("1. Entry")
:addItem("2. Entry")
:addItem("3. Entry")
:addItem("4. Entry")
:addItem("5. Entry")
:addItem("6. Entry")
:setOffset(3)
basalt.debug(aDropdown:getOffset())
```

View File

@@ -0,0 +1,19 @@
## removeItem
Removes a item from the dropdown
#### Parameters:
1. `number` The index which should get removed
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a default dropdown with 3 entries and removes the second one.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:removeItem(2)
```

View File

@@ -0,0 +1,19 @@
## selectItem
selects a item in the dropdown (same as a player would click on a item)
#### Parameters:
1. `number` The index which should get selected
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a default dropdown with 3 entries and selects the second entry.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry",colors.yellow)
aDropdown:addItem("3. Entry",colors.yellow,colors.green)
aDropdown:selectItem(2)
```

View File

@@ -0,0 +1,26 @@
## setDropdownSize
Sets the size of the opened dropdown
#### Parameters:
1. `number` The width value
2. `number` The height value
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a default dropdown, adds 3 entries and sets the dropdown size to 15w, 8h
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown():setDropdownSize(15,8)
aDropdown:addItem("1. Entry")
aDropdown:addItem("2. Entry")
aDropdown:addItem("3. Entry")
```
```xml
<dropdown dropdownWidth="15" dropdownHeight="8">
<item><text>1. Entry</text></item>
<item><text>2. Entry</text></item>
<item><text>3. Entry</text></item>
</dropdown>
```

View File

@@ -0,0 +1,32 @@
## setOffset
Sets the offset of the dropdown (the same as you would scroll) - default is 0
#### Parameters:
1. `number` The offset value
#### Returns:
1. `object` The object in use
#### Usage:
* Creates a default dropdown with 6 entries and sets the offset to 3.
```lua
local mainFrame = basalt.createFrame()
local aDropdown = mainFrame:addDropdown()
:addItem("1. Entry")
:addItem("2. Entry")
:addItem("3. Entry")
:addItem("4. Entry")
:addItem("5. Entry")
:addItem("6. Entry")
:setOffset(3)
```
```xml
<dropdown offset="3">
<item><text>1. Entry</text></item>
<item><text>2. Entry</text></item>
<item><text>3. Entry</text></item>
<item><text>4. Entry</text></item>
<item><text>5. Entry</text></item>
<item><text>6. Entry</text></item>
</dropdown>
```

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