Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0fab23cef | ||
|
|
7609708507 | ||
|
|
e2f2a2871d | ||
|
|
37dde881ad | ||
|
|
8f2e191fe3 | ||
|
|
15d8cb3781 | ||
|
|
8acb673f74 | ||
|
|
cfdca639db | ||
|
|
b34cdd8383 | ||
|
|
a74b8a3d9f | ||
|
|
ef480c3998 | ||
|
|
c3e97ae516 | ||
|
|
d78bb4d141 | ||
|
|
ab72f244ed | ||
|
|
4352d36831 | ||
|
|
04ad97ccbe | ||
|
|
6b2433e0a1 | ||
|
|
bf1b008084 | ||
|
|
681d54b406 | ||
|
|
eab8794d38 | ||
|
|
1d3e2018ef | ||
|
|
44402b1d26 | ||
|
|
56d89ad6f0 | ||
|
|
4af3df72ab | ||
|
|
f404e0ad8f | ||
|
|
45bb23476b | ||
|
|
bd61da9593 | ||
|
|
9acf7d5345 | ||
|
|
1efca45639 | ||
|
|
2dfe69fe43 | ||
|
|
40b24ccf46 | ||
|
|
1ebeda0375 | ||
|
|
9a514e6f7c | ||
|
|
4f1baee771 | ||
|
|
6ed31dd44c | ||
|
|
19bc07e350 | ||
|
|
27321380ae | ||
|
|
bf9f01aae7 | ||
|
|
651690d8ab | ||
|
|
7bcbafe30b | ||
|
|
72f2c527b9 | ||
|
|
77eeb1ce81 | ||
|
|
04d5919a82 | ||
|
|
6fa519be86 | ||
|
|
00fff1c2f0 | ||
|
|
140f1b0014 | ||
|
|
153f2b9146 | ||
|
|
21467fe4f4 | ||
|
|
6f372fa070 | ||
|
|
3ca6ac5af0 | ||
|
|
ab767e16dd | ||
|
|
93a0c738fa | ||
|
|
04d85b633c | ||
|
|
4d83697537 | ||
|
|
ff12c040df | ||
|
|
897b7018a1 |
212
Basalt/Frame.lua
212
Basalt/Frame.lua
@@ -1,9 +1,10 @@
|
||||
local module = require("module")
|
||||
local Object = require("Object")
|
||||
local _OBJECTS = require("loadObjects")
|
||||
local BasaltDraw = require("basaltDraw")
|
||||
local utils = require("utils")
|
||||
local layout = require("layout")
|
||||
local basaltMon = require("basaltMon")
|
||||
local layout = module("layout")
|
||||
local basaltMon = module("basaltMon")
|
||||
local uuid = utils.uuid
|
||||
local rpairs = utils.rpairs
|
||||
local xmlValue = utils.getValueFromXML
|
||||
@@ -48,6 +49,8 @@ return function(name, parent, pTerm, basalt)
|
||||
|
||||
local activeEvents = {}
|
||||
|
||||
local colorTheme = {}
|
||||
|
||||
base:setZIndex(10)
|
||||
|
||||
local basaltDraw = BasaltDraw(termObject)
|
||||
@@ -80,6 +83,7 @@ return function(name, parent, pTerm, basalt)
|
||||
end
|
||||
|
||||
local function getObject(name)
|
||||
if(type(name)~="string")then name = name.name end
|
||||
for _, value in pairs(objects) do
|
||||
for _, b in pairs(value) do
|
||||
if (b:getName() == name) then
|
||||
@@ -239,11 +243,11 @@ return function(name, parent, pTerm, basalt)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local math = math
|
||||
local function stringToNumber(str)
|
||||
local ok, err = pcall(load("return " .. str))
|
||||
local ok, result = pcall(load("return " .. str, "", nil, {math=math}))
|
||||
if not(ok)then error(str.." is not a valid dynamic code") end
|
||||
return load("return " .. str)()
|
||||
return result
|
||||
end
|
||||
|
||||
local function newDynamicValue(_, obj, str)
|
||||
@@ -326,8 +330,13 @@ return function(name, parent, pTerm, basalt)
|
||||
for _, index in pairs(objZIndex) do
|
||||
if (objects[index] ~= nil) then
|
||||
for _, value in pairs(objects[index]) do
|
||||
if (value.eventHandler ~= nil) then
|
||||
value:eventHandler("dynamicValueEvent", self)
|
||||
if(basalt.getDynamicValueEventSetting())then
|
||||
if (value.eventHandler ~= nil) then
|
||||
value:eventHandler("basalt_dynamicvalue", self)
|
||||
end
|
||||
end
|
||||
if (value.customEventHandler ~= nil) then
|
||||
value:customEventHandler("basalt_resize", self)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -339,29 +348,48 @@ return function(name, parent, pTerm, basalt)
|
||||
return dynamicValues[id][1]
|
||||
end
|
||||
|
||||
local function calculateMaxScroll(self)
|
||||
local function getVerticalScrollAmount(self)
|
||||
local amount = 0
|
||||
for _, value in pairs(objects) do
|
||||
for _, b in pairs(value) do
|
||||
if(b.getHeight~=nil)and(b.getY~=nil)then
|
||||
local h, y = b:getHeight(), b:getY()
|
||||
if (h + y - self:getHeight() > scrollAmount) then
|
||||
scrollAmount = max(h + y - self:getHeight(), 0)
|
||||
if(b:getType()=="Dropdown")then
|
||||
local h, y = b:getHeight(), b:getY()
|
||||
local wD, hD = b:getDropdownSize()
|
||||
h = h + hD - 1
|
||||
if (h + y - self:getHeight() >= amount) then
|
||||
amount = max(h + y - self:getHeight(), 0)
|
||||
end
|
||||
else
|
||||
local h, y = b:getHeight(), b:getY()
|
||||
if (h + y - self:getHeight() >= amount) then
|
||||
amount = max(h + y - self:getHeight(), 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return amount
|
||||
end
|
||||
|
||||
local function getHorizontalScrollAmount(self)
|
||||
local amount = 0
|
||||
for _, value in pairs(objects) do
|
||||
for _, b in pairs(value) do
|
||||
if(b.getWidth~=nil)and(b.getX~=nil)then
|
||||
local h, y = b:getWidth(), b:getX()
|
||||
if (h + y - self:getWidth() >= amount) then
|
||||
amount = max(h + y - self:getWidth(), 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return amount
|
||||
end
|
||||
|
||||
local function focusSystem(self)
|
||||
if(focusedObject~=focusedObjectCache)then
|
||||
if(focusedObject~=nil)then
|
||||
focusedObject:loseFocusHandler()
|
||||
end
|
||||
if(focusedObjectCache~=nil)then
|
||||
focusedObjectCache:getFocusHandler()
|
||||
end
|
||||
focusedObject = focusedObjectCache
|
||||
local function calculateMaxScroll(self)
|
||||
if(autoScroll)then
|
||||
scrollAmount = getVerticalScrollAmount(self)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -385,9 +413,30 @@ return function(name, parent, pTerm, basalt)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setZIndex = function(self, newIndex)
|
||||
base.setZIndex(self, newIndex)
|
||||
for k,v in pairs(activeEvents)do
|
||||
if(v)then
|
||||
self.parent:addEvent(k, self)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setFocusedObject = function(self, obj)
|
||||
focusedObjectCache = obj
|
||||
focusSystem(self)
|
||||
if(focusedObject~=obj)then
|
||||
if(focusedObject~=nil)then
|
||||
if(getObject(focusedObject)~=nil)then
|
||||
focusedObject:loseFocusHandler()
|
||||
end
|
||||
end
|
||||
if(obj~=nil)then
|
||||
if(getObject(obj)~=nil)then
|
||||
obj:getFocusHandler()
|
||||
end
|
||||
end
|
||||
focusedObject = obj
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
@@ -403,8 +452,8 @@ return function(name, parent, pTerm, basalt)
|
||||
for _, index in pairs(objZIndex) do
|
||||
if (objects[index] ~= nil) then
|
||||
for _, value in pairs(objects[index]) do
|
||||
if (value.eventHandler ~= nil) then
|
||||
value:eventHandler("basalt_resize", value, self)
|
||||
if (value.customEventHandler ~= nil) then
|
||||
value:customEventHandler("basalt_resize", self)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -428,17 +477,34 @@ return function(name, parent, pTerm, basalt)
|
||||
return theme[name] or (self.parent~=nil and self.parent:getTheme(name) or basalt.getTheme(name))
|
||||
end,
|
||||
|
||||
setPosition = function(self, x, y, rel)
|
||||
base.setPosition(self, x, y, rel)
|
||||
for _, index in pairs(objZIndex) do
|
||||
if (objects[index] ~= nil) then
|
||||
for _, value in pairs(objects[index]) do
|
||||
if (value.eventHandler ~= nil) then
|
||||
value:eventHandler("basalt_reposition", value, self)
|
||||
getThemeColor = function(self, col)
|
||||
return col~=nil and colorTheme[col] or colorTheme
|
||||
end,
|
||||
|
||||
setThemeColor = function(self, col, ...)
|
||||
if(self.parent==nil)then
|
||||
if(self==basalt.getActiveFrame())then
|
||||
if(type(col)=="string")then
|
||||
colorTheme[col] = ...
|
||||
termObject.setPaletteColor(type(col)=="number" and col or colors[col], ...)
|
||||
elseif(type(col)=="table")then
|
||||
for k,v in pairs(col)do
|
||||
colorTheme[k] = v
|
||||
if(type(v)=="number")then
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
|
||||
else
|
||||
local r,g,b = table.unpack(v)
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
setPosition = function(self, x, y, rel)
|
||||
base.setPosition(self, x, y, rel)
|
||||
self:recalculateDynamicValues()
|
||||
return self
|
||||
end;
|
||||
@@ -463,8 +529,12 @@ return function(name, parent, pTerm, basalt)
|
||||
end;
|
||||
|
||||
removeFocusedObject = function(self)
|
||||
focusedObjectCache = nil
|
||||
focusSystem(self)
|
||||
if(focusedObject~=nil)then
|
||||
if(getObject(focusedObject)~=nil)then
|
||||
focusedObject:loseFocusHandler()
|
||||
end
|
||||
end
|
||||
focusedObject = nil
|
||||
return self
|
||||
end;
|
||||
|
||||
@@ -527,13 +597,29 @@ return function(name, parent, pTerm, basalt)
|
||||
|
||||
|
||||
getScrollAmount = function(self)
|
||||
return autoScroll and scrollAmount or calculateMaxScroll(self)
|
||||
return autoScroll and calculateMaxScroll(self) or scrollAmount
|
||||
end,
|
||||
|
||||
getCalculatedVerticalScroll = getVerticalScrollAmount,
|
||||
getCalculatedHorizontalScroll = getHorizontalScrollAmount,
|
||||
|
||||
show = function(self)
|
||||
base.show(self)
|
||||
if(self.parent==nil)then
|
||||
basalt.setActiveFrame(self)
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
termObject.setPaletteColor(v, colors.packRGB(term.nativePaletteColor((v))))
|
||||
end
|
||||
end
|
||||
for k,v in pairs(colorTheme)do
|
||||
if(type(v)=="number")then
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], v)
|
||||
else
|
||||
local r,g,b = table.unpack(v)
|
||||
termObject.setPaletteColor(type(k)=="number" and k or colors[k], r,g,b)
|
||||
end
|
||||
end
|
||||
if(isMonitor)and not(isGroupedMonitor)then
|
||||
basalt.setMonitorFrame(monSide, self)
|
||||
elseif(isGroupedMonitor)then
|
||||
@@ -548,7 +634,7 @@ return function(name, parent, pTerm, basalt)
|
||||
hide = function (self)
|
||||
base.hide(self)
|
||||
if(self.parent==nil)then
|
||||
if(activeFrame == self)then activeFrame = nil end -- bug activeFrame always nil
|
||||
if(activeFrame == self)then activeFrame = nil end
|
||||
if(isMonitor)and not(isGroupedMonitor)then
|
||||
if(basalt.getMonitorFrame(monSide) == self)then
|
||||
basalt.setActiveFrame(nil)
|
||||
@@ -732,14 +818,14 @@ return function(name, parent, pTerm, basalt)
|
||||
if(focusedObject~=nil)then focusedObject:getFocusHandler() end
|
||||
end;
|
||||
|
||||
eventHandler = function(self, event, p1, p2, p3, p4)
|
||||
base.eventHandler(self, event, p1, p2, p3, p4)
|
||||
eventHandler = function(self, event, ...)
|
||||
base.eventHandler(self, event, ...)
|
||||
if(events["other_event"]~=nil)then
|
||||
for _, index in ipairs(eventZIndex["other_event"]) do
|
||||
if (events["other_event"][index] ~= nil) then
|
||||
for _, value in rpairs(events["other_event"][index]) do
|
||||
if (value.eventHandler ~= nil) then
|
||||
if (value:eventHandler(event, p1, p2, p3, p4)) then
|
||||
if (value:eventHandler(event, ...)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -797,9 +883,6 @@ return function(name, parent, pTerm, basalt)
|
||||
self:mouseHandler(1, p2, p3, true)
|
||||
end
|
||||
end
|
||||
if (event == "terminate")and(self.parent==nil)then
|
||||
basalt.stop()
|
||||
end
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y, _, side)
|
||||
@@ -816,7 +899,7 @@ return function(name, parent, pTerm, basalt)
|
||||
for _, value in rpairs(events["mouse_click"][index]) do
|
||||
if (value.mouseHandler ~= nil) then
|
||||
if (value:mouseHandler(button, x, y)) then
|
||||
focusSystem(self)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -849,7 +932,6 @@ return function(name, parent, pTerm, basalt)
|
||||
for _, value in rpairs(events["mouse_up"][index]) do
|
||||
if (value.mouseUpHandler ~= nil) then
|
||||
if (value:mouseUpHandler(button, x, y)) then
|
||||
focusSystem(self)
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -857,7 +939,6 @@ return function(name, parent, pTerm, basalt)
|
||||
end
|
||||
end
|
||||
end
|
||||
focusSystem(self)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
@@ -871,7 +952,6 @@ return function(name, parent, pTerm, basalt)
|
||||
for _, value in rpairs(events["mouse_scroll"][index]) do
|
||||
if (value.scrollHandler ~= nil) then
|
||||
if (value:scrollHandler(dir, x, y)) then
|
||||
focusSystem(self)
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -887,13 +967,32 @@ return function(name, parent, pTerm, basalt)
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
self:removeFocusedObject()
|
||||
if(yOffset==cache)then return false end
|
||||
self:removeFocusedObject()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
hoverHandler = function(self, x, y, stopped)
|
||||
if(base.hoverHandler(self, x, y, stopped))then
|
||||
if(events["mouse_move"]~=nil)then
|
||||
for _, index in pairs(eventZIndex["mouse_move"]) do
|
||||
if (events["mouse_move"][index] ~= nil) then
|
||||
for _, value in rpairs(events["mouse_move"][index]) do
|
||||
if (value.hoverHandler ~= nil) then
|
||||
if (value:hoverHandler(x, y, stopped)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
dragHandler = function(self, button, x, y)
|
||||
if (isDragging) then
|
||||
local xO, yO = self.parent:getOffsetInternal()
|
||||
@@ -915,7 +1014,6 @@ return function(name, parent, pTerm, basalt)
|
||||
for _, value in rpairs(events["mouse_drag"][index]) do
|
||||
if (value.dragHandler ~= nil) then
|
||||
if (value:dragHandler(button, x, y)) then
|
||||
focusSystem(self)
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -924,7 +1022,7 @@ return function(name, parent, pTerm, basalt)
|
||||
end
|
||||
end
|
||||
end
|
||||
focusSystem(self)
|
||||
|
||||
base.dragHandler(self, button, x, y)
|
||||
return false
|
||||
end,
|
||||
@@ -1036,6 +1134,24 @@ return function(name, parent, pTerm, basalt)
|
||||
end
|
||||
end;
|
||||
|
||||
blit = function (self, x, y, t, f, b)
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
if (y >= 1) and (y <= self:getHeight()) then
|
||||
local w = self:getWidth()
|
||||
if (self.parent ~= nil) then
|
||||
t = sub(t, max(1 - x + 1, 1), w - x + 1)
|
||||
f = sub(f, max(1 - x + 1, 1), w - x + 1)
|
||||
b = sub(b, max(1 - x + 1, 1), w - x + 1)
|
||||
self.parent:blit(max(x + (obx - 1), obx), oby + y - 1, t, f, b)
|
||||
else
|
||||
t = sub(t, max(1 - x + 1, 1), max(w - x + 1,1))
|
||||
f = sub(f, max(1 - x + 1, 1), max(w - x + 1,1))
|
||||
b = sub(b, max(1 - x + 1, 1), max(w - x + 1,1))
|
||||
basaltDraw.blit(max(x + (obx - 1), obx), oby + y - 1, t, f, b)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
drawBackgroundBox = function(self, x, y, width, height, bgCol)
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
local basaltEvent = require("basaltEvent")
|
||||
local utils = require("utils")
|
||||
local module = require("module")
|
||||
local images = module("images")
|
||||
local split = utils.splitString
|
||||
local numberFromString = utils.numberFromString
|
||||
local xmlValue = utils.getValueFromXML
|
||||
|
||||
local unpack,sub = table.unpack,string.sub
|
||||
|
||||
return function(name)
|
||||
-- Base object
|
||||
local objectType = "Object" -- not changeable
|
||||
@@ -14,6 +18,8 @@ return function(name)
|
||||
local ignOffset = false
|
||||
local isVisible = true
|
||||
local initialized = false
|
||||
local isHovered = false
|
||||
local isClicked = false
|
||||
|
||||
local shadow = false
|
||||
local borderColors = {
|
||||
@@ -28,6 +34,13 @@ return function(name)
|
||||
local isDragging = false
|
||||
local dragStartX, dragStartY, dragXOffset, dragYOffset = 0, 0, 0, 0
|
||||
|
||||
local bimg
|
||||
local texture
|
||||
local textureId = 1
|
||||
local textureTimerId
|
||||
local textureMode
|
||||
local infinitePlay = true
|
||||
|
||||
local draw = true
|
||||
local activeEvents = {}
|
||||
|
||||
@@ -95,8 +108,8 @@ return function(name)
|
||||
|
||||
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("x", data)~=nil)then self:setPosition(xmlValue("x", data), self:getY()) end
|
||||
if(xmlValue("y", data)~=nil)then self:setPosition(self:getX(), 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
|
||||
@@ -118,6 +131,8 @@ return function(name)
|
||||
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("onHover", data)~=nil)then self:generateXMLEventFunction(self.onHover, xmlValue("onHover", data)) end
|
||||
if(xmlValue("onLeave", data)~=nil)then self:generateXMLEventFunction(self.onLeave, xmlValue("onLeave", 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
|
||||
@@ -191,11 +206,13 @@ return function(name)
|
||||
return self
|
||||
end;
|
||||
|
||||
setValue = function(self, _value)
|
||||
setValue = function(self, _value, valueChangedHandler)
|
||||
if (value ~= _value) then
|
||||
value = _value
|
||||
self:updateDraw()
|
||||
self:valueChangedHandler()
|
||||
if(valueChangedHandler~=false)then
|
||||
self:valueChangedHandler()
|
||||
end
|
||||
end
|
||||
return self
|
||||
end;
|
||||
@@ -241,7 +258,7 @@ return function(name)
|
||||
end
|
||||
self.parent:recalculateDynamicValues()
|
||||
end
|
||||
eventSystem:sendEvent("basalt_reposition", self)
|
||||
self:customEventHandler("basalt_reposition")
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -270,10 +287,10 @@ return function(name)
|
||||
|
||||
setSize = function(self, width, height, rel)
|
||||
if(type(width)=="number")then
|
||||
self.width = rel and self.width+width or width
|
||||
self.width = rel and self:getWidth()+width or width
|
||||
end
|
||||
if(type(height)=="number")then
|
||||
self.height = rel and self.height+height or height
|
||||
self.height = rel and self:getHeight()+height or height
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
if(type(width)=="string")then
|
||||
@@ -284,24 +301,27 @@ return function(name)
|
||||
end
|
||||
self.parent:recalculateDynamicValues()
|
||||
end
|
||||
eventSystem:sendEvent("basalt_resize", self)
|
||||
if(bimg~=nil)and(textureMode=="stretch")then
|
||||
texture = images.resizeBIMG(bimg, self:getSize())[textureId]
|
||||
end
|
||||
self:customEventHandler("basalt_resize")
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
getHeight = function(self)
|
||||
return type(self.height) == "number" and self.height or math.floor(self.height[1]+0.5)
|
||||
end;
|
||||
end,
|
||||
|
||||
getWidth = function(self)
|
||||
return type(self.width) == "number" and self.width or math.floor(self.width[1]+0.5)
|
||||
end;
|
||||
end,
|
||||
|
||||
getSize = function(self)
|
||||
return self:getWidth(), self:getHeight()
|
||||
end;
|
||||
end,
|
||||
|
||||
calculateDynamicValues = function(self)
|
||||
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
|
||||
@@ -316,12 +336,38 @@ return function(name)
|
||||
self.bgSymbolColor = symbolCol or self.bgSymbolColor
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
setTexture = function(self, tex, mode, infPlay)
|
||||
if(type(tex)=="string")then
|
||||
bimg = images.loadImageAsBimg(tex)
|
||||
elseif(type(tex)=="table")then
|
||||
bimg = tex
|
||||
end
|
||||
if(bimg.animated)then
|
||||
local t = bimg[textureId].duration or bimg.secondsPerFrame or 0.2
|
||||
textureTimerId = os.startTimer(t)
|
||||
self.parent:addEvent("other_event", self)
|
||||
activeEvents["other_event"] = true
|
||||
end
|
||||
infinitePlay = infPlay==false and false or true
|
||||
textureId = 1
|
||||
textureMode = mode or "normal"
|
||||
if(textureMode=="stretch")then
|
||||
texture = images.resizeBIMG(bimg, self:getSize())[1]
|
||||
else
|
||||
texture = bimg[1]
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setTransparent = function(self, color)
|
||||
self.transparentColor = color or false
|
||||
self.bgSymbol = false
|
||||
self.bgSymbolColor = false
|
||||
if(color~=false)then
|
||||
self.bgSymbol = false
|
||||
self.bgSymbolColor = false
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -399,64 +445,97 @@ return function(name)
|
||||
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)
|
||||
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(texture~=nil)then
|
||||
if(textureMode=="center")then
|
||||
local tW,tH = #texture[1][1],#texture
|
||||
local xO = tW < w and math.floor((w-tW)/2) or 0
|
||||
local yO = tH < h and math.floor((h-tH)/2) or 0
|
||||
local sL = tW<w and 1 or math.floor((tW-w)/2)
|
||||
local eL = tW<w and w or w - math.floor((w-tW)/2+0.5)-1
|
||||
local sH = tH<h and 1 or math.floor((tH-h)/2)
|
||||
local eH = tH<h and h or h - math.floor((h-tH)/2+0.5)-1
|
||||
local yTex = 1
|
||||
for k=sH,#texture do
|
||||
if(texture[k]~=nil)then
|
||||
local t, f, b = unpack(texture[k])
|
||||
t = sub(t, sL,eL)
|
||||
f = sub(f, sL,eL)
|
||||
b = sub(b, sL,eL)
|
||||
self.parent:blit(x+xO, y+yTex-1+yO, t, f, b)
|
||||
end
|
||||
yTex = yTex + 1
|
||||
if(k==eH)then break end
|
||||
end
|
||||
else
|
||||
for k,v in pairs(texture)do
|
||||
local t, f, b = unpack(v)
|
||||
t = sub(t, 1,w)
|
||||
f = sub(f, 1,w)
|
||||
b = sub(b, 1,w)
|
||||
self.parent:blit(x, y+k-1, t, f, b)
|
||||
if(k==h)then break end
|
||||
end
|
||||
end
|
||||
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
|
||||
|
||||
local bgCol = self.bgColor
|
||||
if(borderColors["left"]~=false)then
|
||||
self.parent:drawTextBox(x-1, y, 1, h, "\149")
|
||||
self.parent:drawBackgroundBox(x-1, y, 1, h, self.bgColor)
|
||||
self.parent:drawForegroundBox(x-1, y, 1, h, borderColors["left"])
|
||||
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, self.bgColor)
|
||||
self.parent:drawForegroundBox(x-1, y-1, 1, 1, borderColors["left"])
|
||||
self.parent:drawTextBox(x, y, 1, h, "\149")
|
||||
if(bgCol~=false)then self.parent:drawBackgroundBox(x, y, 1, h, bgCol) end
|
||||
self.parent:drawForegroundBox(x, y, 1, h, borderColors["left"])
|
||||
end
|
||||
if(borderColors["top"]~=false)then
|
||||
|
||||
self.parent:drawTextBox(x, y-1, w, 1, "\131")
|
||||
self.parent:drawBackgroundBox(x, y-1, w, 1, self.bgColor)
|
||||
self.parent:drawForegroundBox(x, y-1, w, 1, borderColors["top"])
|
||||
self.parent:drawTextBox(x, y, w, 1, "\131")
|
||||
if(bgCol~=false)then self.parent:drawBackgroundBox(x, y, w, 1, self.bgColor) end
|
||||
self.parent:drawForegroundBox(x, y, w, 1, borderColors["top"])
|
||||
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, self.bgColor)
|
||||
self.parent:drawBackgroundBox(x+w, y-1, 1, 1, borderColors["right"])
|
||||
if(borderColors["left"]~=false)and(borderColors["top"]~=false)then
|
||||
self.parent:drawTextBox(x, y, 1, 1, "\151")
|
||||
if(bgCol~=false)then self.parent:drawBackgroundBox(x, y, 1, 1, self.bgColor) end
|
||||
self.parent:drawForegroundBox(x, y, 1, 1, borderColors["left"])
|
||||
end
|
||||
if(borderColors["right"]~=false)then
|
||||
self.parent:drawTextBox(x+w, y, 1, h, "\149")
|
||||
self.parent:drawForegroundBox(x+w, y, 1, h, self.bgColor)
|
||||
self.parent:drawBackgroundBox(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, "\133")
|
||||
self.parent:drawForegroundBox(x+w, y+h, 1, 1, self.bgColor)
|
||||
self.parent:drawBackgroundBox(x+w, y+h, 1, 1, borderColors["right"])
|
||||
self.parent:drawTextBox(x+w-1, y, 1, h, "\149")
|
||||
if(bgCol~=false)then self.parent:drawForegroundBox(x+w-1, y, 1, h, self.bgColor) end
|
||||
self.parent:drawBackgroundBox(x+w-1, y, 1, h, borderColors["right"])
|
||||
end
|
||||
if(borderColors["bottom"]~=false)then
|
||||
self.parent:drawTextBox(x, y+h, w, 1, "\143")
|
||||
self.parent:drawForegroundBox(x, y+h, w, 1, self.bgColor)
|
||||
self.parent:drawBackgroundBox(x, y+h, w, 1, borderColors["bottom"])
|
||||
self.parent:drawTextBox(x, y+h-1, w, 1, "\143")
|
||||
if(bgCol~=false)then self.parent:drawForegroundBox(x, y+h-1, w, 1, self.bgColor) end
|
||||
self.parent:drawBackgroundBox(x, y+h-1, w, 1, borderColors["bottom"])
|
||||
end
|
||||
if(borderColors["top"]~=false)and(borderColors["right"]~=false)then
|
||||
self.parent:drawTextBox(x+w-1, y, 1, 1, "\148")
|
||||
if(bgCol~=false)then self.parent:drawForegroundBox(x+w-1, y, 1, 1, self.bgColor) end
|
||||
self.parent:drawBackgroundBox(x+w-1, y, 1, 1, borderColors["right"])
|
||||
end
|
||||
if(borderColors["right"]~=false)and(borderColors["bottom"]~=false)then
|
||||
self.parent:drawTextBox(x+w-1, y+h-1, 1, 1, "\133")
|
||||
if(bgCol~=false)then self.parent:drawForegroundBox(x+w-1, y+h-1, 1, 1, self.bgColor) end
|
||||
self.parent:drawBackgroundBox(x+w-1, y+h-1, 1, 1, borderColors["right"])
|
||||
end
|
||||
if(borderColors["bottom"]~=false)and(borderColors["left"]~=false)then
|
||||
self.parent:drawTextBox(x-1, y+h, 1, 1, "\138")
|
||||
self.parent:drawForegroundBox(x-1, y+h, 1, 1, self.bgColor)
|
||||
self.parent:drawBackgroundBox(x-1, y+h, 1, 1, borderColors["left"])
|
||||
self.parent:drawTextBox(x, y+h-1, 1, 1, "\138")
|
||||
if(bgCol~=false)then self.parent:drawForegroundBox(x-1, y+h-1, 1, 1, self.bgColor) end
|
||||
self.parent:drawBackgroundBox(x, y+h-1, 1, 1, borderColors["left"])
|
||||
end
|
||||
end
|
||||
draw = false
|
||||
@@ -560,6 +639,8 @@ return function(name)
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
activeEvents["mouse_click"] = true
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
activeEvents["mouse_up"] = true
|
||||
end
|
||||
return self
|
||||
end;
|
||||
@@ -571,26 +652,68 @@ return function(name)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
activeEvents["mouse_click"] = true
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
activeEvents["mouse_up"] = true
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
|
||||
onScroll = function(self, ...)
|
||||
onRelease = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_scroll", v)
|
||||
self:registerEvent("mouse_release", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
activeEvents["mouse_scroll"] = 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;
|
||||
|
||||
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;
|
||||
|
||||
onHover = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_hover", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("mouse_move", self)
|
||||
activeEvents["mouse_move"] = true
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
onLeave = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("mouse_leave", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("mouse_move", self)
|
||||
activeEvents["mouse_move"] = true
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
onDrag = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
@@ -626,13 +749,25 @@ return function(name)
|
||||
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
|
||||
end
|
||||
end
|
||||
return self
|
||||
end;
|
||||
|
||||
onChar = function(self, ...)
|
||||
if(isEnabled)then
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("char", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("char", self)
|
||||
activeEvents["char"] = true
|
||||
end
|
||||
end
|
||||
@@ -717,7 +852,8 @@ return function(name)
|
||||
|
||||
isCoordsInObject = function(self, x, y)
|
||||
if(isVisible)and(isEnabled)then
|
||||
local objX, objY = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
if(x==nil)or(y==nil)then return false end
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local w, h = self:getSize()
|
||||
if (objX <= x) and (objX + w > x) and (objY <= y) and (objY + h > y) then
|
||||
return true
|
||||
@@ -728,11 +864,13 @@ return function(name)
|
||||
|
||||
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)
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = eventSystem:sendEvent("mouse_click", self, "mouse_click", button, x - (objX-1), y - (objY-1), x, y, isMon)
|
||||
if(val==false)then return false end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:setFocusedObject(self)
|
||||
end
|
||||
isClicked = true
|
||||
isDragging = true
|
||||
dragStartX, dragStartY = x, y
|
||||
return true
|
||||
@@ -742,8 +880,14 @@ return function(name)
|
||||
|
||||
mouseUpHandler = function(self, button, x, y)
|
||||
isDragging = false
|
||||
if(isClicked)then
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = eventSystem:sendEvent("mouse_release", self, "mouse_release", button, x - (objX-1), y - (objY-1), x, y)
|
||||
isClicked = false
|
||||
end
|
||||
if(self:isCoordsInObject(x, y))then
|
||||
local val = eventSystem:sendEvent("mouse_up", self, "mouse_up", button, x, y)
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = eventSystem:sendEvent("mouse_up", self, "mouse_up", button, x - (objX-1), y - (objY-1), x, y)
|
||||
if(val==false)then return false end
|
||||
return true
|
||||
end
|
||||
@@ -752,16 +896,8 @@ return function(name)
|
||||
|
||||
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())
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = eventSystem:sendEvent("mouse_drag", self, "mouse_drag", button, x - (objX-1), y - (objY-1), dragStartX-x, dragStartY-y, x, y)
|
||||
dragStartX, dragStartY = x, y
|
||||
if(val~=nil)then return val end
|
||||
if(self.parent~=nil)then
|
||||
@@ -780,7 +916,8 @@ return function(name)
|
||||
|
||||
scrollHandler = function(self, dir, x, y)
|
||||
if(self:isCoordsInObject(x, y))then
|
||||
local val = eventSystem:sendEvent("mouse_scroll", self, "mouse_scroll", dir, x, y)
|
||||
local objX, objY = self:getAbsolutePosition()
|
||||
local val = eventSystem:sendEvent("mouse_scroll", self, "mouse_scroll", dir, x - (objX-1), y - (objY-1))
|
||||
if(val==false)then return false end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:setFocusedObject(self)
|
||||
@@ -790,6 +927,21 @@ return function(name)
|
||||
return false
|
||||
end,
|
||||
|
||||
hoverHandler = function(self, x, y, stopped)
|
||||
if(self:isCoordsInObject(x, y))then
|
||||
local val = eventSystem:sendEvent("mouse_hover", self, "mouse_hover", x, y, stopped)
|
||||
if(val==false)then return false end
|
||||
isHovered = true
|
||||
return true
|
||||
end
|
||||
if(isHovered)then
|
||||
local val = eventSystem:sendEvent("mouse_leave", self, "mouse_leave", x, y, stopped)
|
||||
if(val==false)then return false end
|
||||
isHovered = false
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
keyHandler = function(self, key, isHolding)
|
||||
if(isEnabled)and(isVisible)then
|
||||
if (self:isFocused()) then
|
||||
@@ -815,7 +967,7 @@ return function(name)
|
||||
charHandler = function(self, char)
|
||||
if(isEnabled)and(isVisible)then
|
||||
if (self:isFocused()) then
|
||||
local val = eventSystem:sendEvent("char", self, "char", char)
|
||||
local val = eventSystem:sendEvent("char", self, "char", char)
|
||||
if(val==false)then return false end
|
||||
return true
|
||||
end
|
||||
@@ -827,8 +979,42 @@ return function(name)
|
||||
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)
|
||||
eventHandler = function(self, event, ...)
|
||||
local args = {...}
|
||||
if(event=="timer")and(args[1]==textureTimerId)then
|
||||
if(bimg[textureId+1]~=nil)then
|
||||
textureId = textureId + 1
|
||||
if(textureMode=="stretch")then
|
||||
texture = images.resizeBIMG(bimg, self:getSize())[textureId]
|
||||
else
|
||||
texture = bimg[textureId]
|
||||
end
|
||||
local t = bimg[textureId].duration or bimg.secondsPerFrame or 0.2
|
||||
textureTimerId = os.startTimer(t)
|
||||
else
|
||||
if(infinitePlay)then
|
||||
textureId = 1
|
||||
if(textureMode=="stretch")then
|
||||
texture = images.resizeBIMG(bimg, self:getSize())[1]
|
||||
else
|
||||
texture = bimg[1]
|
||||
end
|
||||
local t = bimg[1].duration or bimg.secondsPerFrame or 0.2
|
||||
textureTimerId = os.startTimer(t)
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
local val = eventSystem:sendEvent("other_event", self, event, ...)
|
||||
if(val~=nil)then return val end
|
||||
end;
|
||||
|
||||
customEventHandler = function(self, event, ...)
|
||||
if(bimg~=nil)and(textureMode=="stretch")and(event=="basalt_resize")then
|
||||
texture = images.resizeBIMG(bimg, self:getSize())[textureId]
|
||||
self:updateDraw()
|
||||
end
|
||||
local val = eventSystem:sendEvent("custom_event", self, event, ...)
|
||||
if(val~=nil)then return val end
|
||||
return true
|
||||
end;
|
||||
@@ -858,6 +1044,7 @@ return function(name)
|
||||
initialized = true
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
local curDir = fs.getDir(table.pack(...)[2]) or ""
|
||||
|
||||
local defaultPath = package.path
|
||||
local format = "%s;/%s/?.lua;/%s/?/init.lua"
|
||||
package.path = string.format(format, package.path, curDir,curDir)..string.format(format, package.path, curDir.."/libraries",curDir.."/libraries")..string.format(format, package.path, curDir.."/objects",curDir.."/objects")
|
||||
if not(packed)then
|
||||
local defaultPath = package.path
|
||||
local format = "path;/path/?.lua;/path/?/init.lua;"
|
||||
|
||||
local main = format:gsub("path", curDir)
|
||||
local objFolder = format:gsub("path", curDir.."/objects")
|
||||
local libFolder = format:gsub("path", curDir.."/libraries")
|
||||
|
||||
|
||||
package.path = main..objFolder..libFolder..defaultPath
|
||||
end
|
||||
local Basalt = require("main")
|
||||
package.path = defaultPath
|
||||
|
||||
|
||||
@@ -126,6 +126,52 @@ return function(drawTerm)
|
||||
end
|
||||
end
|
||||
|
||||
local function blit(x, y, t, fg, bg)
|
||||
if(#t == #fg)or(#t == #bg)then
|
||||
if (y >= 1) and (y <= height) then
|
||||
if (x + t:len() > 0) and (x <= width) then
|
||||
local oldCacheT = cacheT[y]
|
||||
local oldCacheFG = cacheFG[y]
|
||||
local oldCacheBG = cacheBG[y]
|
||||
local newCacheT, newCacheFG, newCacheBG
|
||||
local nEnd = x + #t - 1
|
||||
|
||||
if (x < 1) then
|
||||
local startN = 1 - x + 1
|
||||
local endN = width - x + 1
|
||||
t = sub(t, startN, endN)
|
||||
fg = sub(fg, startN, endN)
|
||||
bg = sub(bg, startN, endN)
|
||||
elseif (nEnd > width) then
|
||||
local endN = width - x + 1
|
||||
t = sub(t, 1, endN)
|
||||
fg = sub(fg, 1, endN)
|
||||
bg = sub(bg, 1, endN)
|
||||
end
|
||||
|
||||
if (x > 1) then
|
||||
local endN = x - 1
|
||||
newCacheT = sub(oldCacheT, 1, endN) .. t
|
||||
newCacheFG = sub(oldCacheFG, 1, endN) .. fg
|
||||
newCacheBG = sub(oldCacheBG, 1, endN) .. bg
|
||||
else
|
||||
newCacheT = t
|
||||
newCacheFG = fg
|
||||
newCacheBG = bg
|
||||
end
|
||||
if nEnd < width then
|
||||
newCacheT = newCacheT .. sub(oldCacheT, nEnd + 1, width)
|
||||
newCacheFG = newCacheFG .. sub(oldCacheFG, nEnd + 1, width)
|
||||
newCacheBG = newCacheBG .. sub(oldCacheBG, nEnd + 1, width)
|
||||
end
|
||||
cacheT[y] = newCacheT
|
||||
cacheFG[y] = newCacheFG
|
||||
cacheBG[y] = newCacheBG
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local drawHelper = {
|
||||
setSize = function(w, h)
|
||||
width, height = w, h
|
||||
@@ -147,6 +193,10 @@ return function(drawTerm)
|
||||
setFG(x, y, colorStr)
|
||||
end;
|
||||
|
||||
blit = function(x, y, t, fg, bg)
|
||||
blit(x, y, t, fg, bg)
|
||||
end,
|
||||
|
||||
drawBackgroundBox = function(x, y, width, height, bgCol)
|
||||
for n = 1, height do
|
||||
setBG(x, y + (n - 1), rep(tHex[bgCol], width))
|
||||
|
||||
381
Basalt/libraries/bimg.lua
Normal file
381
Basalt/libraries/bimg.lua
Normal file
@@ -0,0 +1,381 @@
|
||||
local sub,rep = string.sub,string.rep
|
||||
|
||||
local function frame(base, manager)
|
||||
local w, h = 0, 0
|
||||
local t,fg,bg = {}, {}, {}
|
||||
local x, y = 1,1
|
||||
|
||||
local data = {}
|
||||
|
||||
local function recalculateSize()
|
||||
for y=1,h do
|
||||
if(t[y]==nil)then
|
||||
t[y] = rep(" ", w)
|
||||
else
|
||||
t[y] = t[y]..rep(" ", w-#t[y])
|
||||
end
|
||||
if(fg[y]==nil)then
|
||||
fg[y] = rep("0", w)
|
||||
else
|
||||
fg[y] = fg[y]..rep("0", w-#fg[y])
|
||||
end
|
||||
if(bg[y]==nil)then
|
||||
bg[y] = rep("f", w)
|
||||
else
|
||||
bg[y] = bg[y]..rep("f", w-#bg[y])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local addText = function(text, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
if(t[y]==nil)then
|
||||
t[y] = rep(" ", x-1)..text..rep(" ", w-(#text+x))
|
||||
else
|
||||
t[y] = sub(t[y], 1, x-1)..rep(" ", x-#t[y])..text..sub(t[y], x+#text, w)
|
||||
end
|
||||
if(#t[y]>w)then w = #t[y] end
|
||||
if(y > h)then h = y end
|
||||
manager.updateSize(w, h)
|
||||
end
|
||||
|
||||
local addBg = function(b, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
if(bg[y]==nil)then
|
||||
bg[y] = rep("f", x-1)..b..rep("f", w-(#b+x))
|
||||
else
|
||||
bg[y] = sub(bg[y], 1, x-1)..rep("f", x-#bg[y])..b..sub(bg[y], x+#b, w)
|
||||
end
|
||||
if(#bg[y]>w)then w = #bg[y] end
|
||||
if(y > h)then h = y end
|
||||
manager.updateSize(w, h)
|
||||
end
|
||||
|
||||
local addFg = function(f, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
if(fg[y]==nil)then
|
||||
fg[y] = rep("0", x-1)..f..rep("0", w-(#f+x))
|
||||
else
|
||||
fg[y] = sub(fg[y], 1, x-1)..rep("0", x-#fg[y])..f..sub(fg[y], x+#f, w)
|
||||
end
|
||||
if(#fg[y]>w)then w = #fg[y] end
|
||||
if(y > h)then h = y end
|
||||
manager.updateSize(w, h)
|
||||
end
|
||||
|
||||
local function setFrame(frm)
|
||||
data = {}
|
||||
t, fg, bg = {}, {}, {}
|
||||
for k,v in pairs(base)do
|
||||
if(type(k)=="string")then
|
||||
data[k] = v
|
||||
else
|
||||
t[k], fg[k], bg[k] = v[1], v[2], v[3]
|
||||
end
|
||||
end
|
||||
manager.updateSize(w, h)
|
||||
end
|
||||
|
||||
if(base~=nil)then
|
||||
w = #base[1][1]
|
||||
h = #base
|
||||
setFrame(base)
|
||||
end
|
||||
|
||||
return {
|
||||
recalculateSize = recalculateSize,
|
||||
setFrame = setFrame,
|
||||
|
||||
getFrame = function()
|
||||
local f = {}
|
||||
|
||||
for k,v in pairs(t)do
|
||||
table.insert(f, {v, fg[k], bg[k]})
|
||||
end
|
||||
|
||||
for k,v in pairs(data)do
|
||||
f[k] = v
|
||||
end
|
||||
|
||||
return f, w, h
|
||||
end,
|
||||
|
||||
getImage = function()
|
||||
local i = {}
|
||||
for k,v in pairs(t)do
|
||||
table.insert(i, {v, fg[k], bg[k]})
|
||||
end
|
||||
return i
|
||||
end,
|
||||
|
||||
setFrameData = function(key, value)
|
||||
if(value~=nil)then
|
||||
data[key] = value
|
||||
else
|
||||
if(type(key)=="table")then
|
||||
data = key
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
setFrameImage = function(imgData)
|
||||
for k,v in pairs(imgData.t)do
|
||||
t[k] = imgData.t[k]
|
||||
fg[k] = imgData.fg[k]
|
||||
bg[k] = imgData.bg[k]
|
||||
end
|
||||
end,
|
||||
|
||||
getFrameImage = function()
|
||||
return {t = t, fg = fg, bg = bg}
|
||||
end,
|
||||
|
||||
getFrameData = function(key)
|
||||
return (key~= nil and data[key] or data)
|
||||
end,
|
||||
|
||||
blit = function(text, fgCol, bgCol, x, y)
|
||||
addText(text, x, y)
|
||||
addFg(fgCol, x, y)
|
||||
addBg(bgCol, x, y)
|
||||
end,
|
||||
|
||||
text = addText,
|
||||
fg = addFg,
|
||||
bg = addBg,
|
||||
|
||||
getSize = function()
|
||||
return w, h
|
||||
end,
|
||||
|
||||
setSize = function(_w, _h)
|
||||
local nt,nfg,nbg = {}, {}, {}
|
||||
for _y=1,_h do
|
||||
if(t[_y]~=nil)then
|
||||
nt[_y] = sub(t[_y], 1, _w)..rep(" ", _w - w)
|
||||
else
|
||||
nt[_y] = rep(" ", _w)
|
||||
end
|
||||
if(fg[_y]~=nil)then
|
||||
nfg[_y] = sub(fg[_y], 1, _w)..rep("0", _w - w)
|
||||
else
|
||||
nfg[_y] = rep("0", _w)
|
||||
end
|
||||
if(bg[_y]~=nil)then
|
||||
nbg[_y] = sub(bg[_y], 1, _w)..rep("f", _w - w)
|
||||
else
|
||||
nbg[_y] = rep("f", _w)
|
||||
end
|
||||
end
|
||||
t, fg, bg = nt, nfg, nbg
|
||||
w, h = _w, _h
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
return function(img)
|
||||
local frames = {}
|
||||
local metadata = {creator="Bimg Library by NyoriE", date=os.date("!%Y-%m-%dT%TZ")}
|
||||
local width,height = 0, 0
|
||||
|
||||
local manager = {}
|
||||
|
||||
local function addFrame(id, data)
|
||||
id = id or #frames+1
|
||||
table.insert(frames, id, frame(data, manager))
|
||||
if(data==nil)then
|
||||
frames[id].setSize(width, height)
|
||||
end
|
||||
end
|
||||
|
||||
local function removeFrame(id)
|
||||
table.remove(frames, id or #frames)
|
||||
end
|
||||
|
||||
local function moveFrame(id, dir)
|
||||
local f = frames[id]
|
||||
if(f~=nil)then
|
||||
local newId = id+dir
|
||||
if(newId>=1)and(newId<=#frames)then
|
||||
table.remove(frames, id)
|
||||
table.insert(frames, newId, f)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
manager = {
|
||||
updateSize = function(w, h, force)
|
||||
local changed = force==true and true or false
|
||||
if(w > width)then changed = true width = w end
|
||||
if(h > height)then changed = true height = h end
|
||||
if(changed)then
|
||||
for k,v in pairs(frames)do
|
||||
v.setSize(width, height)
|
||||
v.recalculateSize()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
text = function(frame, text, x, y)
|
||||
local f = frames[frame]
|
||||
if(f==nil)then
|
||||
f = addFrame(frame)
|
||||
end
|
||||
f.text(text, x, y)
|
||||
end,
|
||||
|
||||
fg = function(frame, fg, x, y)
|
||||
local f = frames[frame]
|
||||
if(f==nil)then
|
||||
f = addFrame(frame)
|
||||
end
|
||||
f.fg(fg, x, y)
|
||||
end,
|
||||
|
||||
bg = function(frame, bg, x, y)
|
||||
local f = frames[frame]
|
||||
if(f==nil)then
|
||||
f = addFrame(frame)
|
||||
end
|
||||
f.bg(bg, x, y)
|
||||
end,
|
||||
|
||||
blit = function(frame, text, fg, bg, x, y)
|
||||
local f = frames[frame]
|
||||
if(f==nil)then
|
||||
f = addFrame(frame)
|
||||
end
|
||||
f.blit(text, fg, bg, x, y)
|
||||
end,
|
||||
|
||||
setSize = function(w, h)
|
||||
width = w
|
||||
height = h
|
||||
for k,v in pairs(frames)do
|
||||
v.setSize(w, h)
|
||||
end
|
||||
end,
|
||||
|
||||
getFrame = function(id)
|
||||
if(frames[id]~=nil)then
|
||||
return frames[id].getFrame()
|
||||
end
|
||||
end,
|
||||
|
||||
getFrameObjects = function()
|
||||
return frames
|
||||
end,
|
||||
|
||||
getFrames = function()
|
||||
local f = {}
|
||||
for k,v in pairs(frames)do
|
||||
local frame = v.getFrame()
|
||||
table.insert(f, frame)
|
||||
end
|
||||
return f
|
||||
end,
|
||||
|
||||
getFrameObject = function(id)
|
||||
return frames[id]
|
||||
end,
|
||||
|
||||
addFrame = function(id)
|
||||
local f = frame()
|
||||
if(#frames<=1)then
|
||||
if(metadata.animated==nil)then
|
||||
metadata.animated = true
|
||||
end
|
||||
if(metadata.secondsPerFrame==nil)then
|
||||
metadata.secondsPerFrame = 0.2
|
||||
end
|
||||
end
|
||||
addFrame(id)
|
||||
return f
|
||||
end,
|
||||
|
||||
removeFrame = function(id)
|
||||
removeFrame(id)
|
||||
if(#frames<=1)then
|
||||
if(metadata.animated==nil)then
|
||||
metadata.animated = true
|
||||
end
|
||||
if(metadata.secondsPerFrame==nil)then
|
||||
metadata.secondsPerFrame = 0.2
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
moveFrame = moveFrame,
|
||||
|
||||
setFrameData = function(id, key, value)
|
||||
if(frames[id]~=nil)then
|
||||
frames[id].setFrameData(key, value)
|
||||
end
|
||||
end,
|
||||
|
||||
getFrameData = function(id, key)
|
||||
return frames[id]~=nil and frames[id].getFrameData(key)
|
||||
end,
|
||||
|
||||
getSize = function()
|
||||
return width, height
|
||||
end,
|
||||
|
||||
setAnimation = function(anim)
|
||||
metadata.animation = anim
|
||||
end,
|
||||
|
||||
setMetadata = function(key, val)
|
||||
if(val~=nil)then
|
||||
metadata[key] = val
|
||||
else
|
||||
if(type(key)=="table")then
|
||||
metadata = key
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
getMetadata = function(key)
|
||||
return key~=nil and metadata[key] or metadata
|
||||
end,
|
||||
|
||||
createBimg = function()
|
||||
local bimg = {}
|
||||
for k,v in pairs(frames)do
|
||||
local f = v.getFrame()
|
||||
table.insert(bimg, f)
|
||||
end
|
||||
for k,v in pairs(metadata)do
|
||||
bimg[k] = v
|
||||
end
|
||||
bimg.width = width
|
||||
bimg.height = height
|
||||
return bimg
|
||||
end,
|
||||
}
|
||||
|
||||
if(img~=nil)then
|
||||
for k,v in pairs(img)do
|
||||
if(type(k)=="string")then
|
||||
metadata[k] = v
|
||||
else
|
||||
addFrame(k, v)
|
||||
end
|
||||
end
|
||||
if(metadata.width==nil)or(metadata.height==nil)then
|
||||
for k,v in pairs(frames)do
|
||||
local w, h = v.getSize()
|
||||
if(w>width)then w = width end
|
||||
if(h>height)then h = height end
|
||||
end
|
||||
manager.updateSize(width, height, true)
|
||||
end
|
||||
else
|
||||
addFrame(1)
|
||||
end
|
||||
|
||||
return manager
|
||||
end
|
||||
@@ -1,197 +0,0 @@
|
||||
local function line(x1,y1,x2,y2)
|
||||
local points = {}
|
||||
if x1 == x2 and y1 == y2 then return {x=x1,y=x2} end
|
||||
local minX = math.min(x1, x2)
|
||||
local maxX, minY, maxY
|
||||
if minX == x1 then minY,maxX,maxY = y1,x2,y2
|
||||
else minY,maxX,maxY = y2,x1,y1 end
|
||||
local xDiff,yDiff = maxX - minX,maxY - minY
|
||||
if xDiff > math.abs(yDiff) then
|
||||
local y = minY
|
||||
local dy = yDiff / xDiff
|
||||
for x = minX, maxX do
|
||||
table.insert(points,{x=x,y=math.floor(y + 0.5)})
|
||||
y = y + dy
|
||||
end
|
||||
else
|
||||
local x,dx = minX,xDiff / yDiff
|
||||
if maxY >= minY then
|
||||
for y = minY, maxY do
|
||||
table.insert(points,{x=math.floor(x + 0.5),y=y})
|
||||
x = x + dx
|
||||
end
|
||||
else
|
||||
for y = minY, maxY, -1 do
|
||||
table.insert(points,{x=math.floor(x + 0.5),y=y})
|
||||
x = x - dx
|
||||
end
|
||||
end
|
||||
end
|
||||
return points
|
||||
end
|
||||
|
||||
local function filledCircle(xC, yC, r)
|
||||
local points = {}
|
||||
for x=-r, r+1 do
|
||||
local dy = math.floor(math.sqrt(r*r - x*x))
|
||||
for y=-dy, dy+1 do
|
||||
table.insert(points, {x=xC+x, y=yC+y})
|
||||
end
|
||||
end
|
||||
return points
|
||||
end
|
||||
|
||||
local function ellipse(xC, yC, r1, r2, filled)
|
||||
local rx,ry = math.ceil(math.floor(r1-0.5)/2),math.ceil(math.floor(r2-0.5)/2)
|
||||
local x,y=0,ry
|
||||
local d1 = ((ry * ry) - (rx * rx * ry) + (0.25 * rx * rx))
|
||||
local dx = 2*ry^2*x
|
||||
local dy = 2*rx^2*y
|
||||
local points = {}
|
||||
while dx < dy do
|
||||
table.insert(points,{x=x+xC,y=y+yC})
|
||||
table.insert(points,{x=-x+xC,y=y+yC})
|
||||
table.insert(points,{x=x+xC,y=-y+yC})
|
||||
table.insert(points,{x=-x+xC,y=-y+yC})
|
||||
if filled then
|
||||
for y=-y+yC+1,y+yC-1 do
|
||||
table.insert(points,{x=x+xC,y=y})
|
||||
table.insert(points,{x=-x+xC,y=y})
|
||||
end
|
||||
end
|
||||
if d1 < 0 then
|
||||
x = x + 1
|
||||
dx = dx + 2*ry^2
|
||||
d1 = d1 + dx + ry^2
|
||||
else
|
||||
x,y = x+1,y-1
|
||||
dx = dx + 2*ry^2
|
||||
dy = dy - 2*rx^2
|
||||
d1 = d1 + dx - dy + ry^2
|
||||
end
|
||||
end
|
||||
local d2 = (((ry * ry) * ((x + 0.5) * (x + 0.5))) + ((rx * rx) * ((y - 1) * (y - 1))) - (rx * rx * ry * ry))
|
||||
while y >= 0 do
|
||||
table.insert(points,{x=x+xC,y=y+yC})
|
||||
table.insert(points,{x=-x+xC,y=y+yC})
|
||||
table.insert(points,{x=x+xC,y=-y+yC})
|
||||
table.insert(points,{x=-x+xC,y=-y+yC})
|
||||
if filled then
|
||||
for y=-y+yC,y+yC do
|
||||
table.insert(points,{x=x+xC,y=y})
|
||||
table.insert(points,{x=-x+xC,y=y})
|
||||
end
|
||||
end
|
||||
if d2 > 0 then
|
||||
y = y - 1
|
||||
dy = dy - 2*rx^2
|
||||
d2 = d2 + rx^2 - dy
|
||||
else
|
||||
y = y - 1
|
||||
x = x + 1
|
||||
dy = dy - 2*rx^2
|
||||
dx = dx + 2*ry^2
|
||||
d2 = d2 + dx - dy + rx^2
|
||||
end
|
||||
end
|
||||
return points
|
||||
end
|
||||
|
||||
local function circle(xC, yC, r, filled)
|
||||
return ellipse(xC, yC, r, r, filled)
|
||||
end
|
||||
|
||||
return {
|
||||
circle = function(x, y, radius, filled)
|
||||
return circle(x, y, radius, filled)
|
||||
end,
|
||||
|
||||
rectangle = function(x1, y1, x2, y2, filled)
|
||||
local points = {}
|
||||
if(filled)then
|
||||
for y=y1,y2 do
|
||||
for x=x1,x2 do
|
||||
table.insert(points, {x=x,y=y})
|
||||
end
|
||||
end
|
||||
else
|
||||
for y=y1,y2 do
|
||||
for x=x1,x2 do
|
||||
if(x==x1)or(x==x2)or(y==y1)or(y==y2)then
|
||||
table.insert(points, {x=x,y=y})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return points
|
||||
end,
|
||||
|
||||
triangle = function(x1, y1, x2, y2, x3, y3, filled)
|
||||
local function drawFlatTopTriangle(points,x1,y1,x2,y2,x3,y3)
|
||||
local m1 = (x3 - x1) / (y3 - y1)
|
||||
local m2 = (x3 - x2) / (y3 - y2)
|
||||
local yStart = math.ceil(y1 - 0.5)
|
||||
local yEnd = math.ceil(y3 - 0.5)-1
|
||||
for y = yStart, yEnd do
|
||||
local px1 = m1 * (y + 0.5 - y1) + x1
|
||||
local px2 = m2 * (y + 0.5 - y2) + x2
|
||||
local xStart = math.ceil(px1 - 0.5)
|
||||
local xEnd = math.ceil(px2 - 0.5)
|
||||
for x=xStart,xEnd do
|
||||
table.insert(points,{x=x,y=y})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function drawFlatBottomTriangle(points,x1,y1,x2,y2,x3,y3)
|
||||
local m1 = (x2 - x1) / (y2 - y1)
|
||||
local m2 = (x3 - x1) / (y3 - y1)
|
||||
local yStart = math.ceil(y1-0.5)
|
||||
local yEnd = math.ceil(y3-0.5)-1
|
||||
for y = yStart, yEnd do
|
||||
local px1 = m1 * (y + 0.5 - y1) + x1
|
||||
local px2 = m2 * (y + 0.5 - y1) + x1
|
||||
local xStart = math.ceil(px1 - 0.5)
|
||||
local xEnd = math.ceil(px2 - 0.5)
|
||||
for x=xStart,xEnd do
|
||||
table.insert(points,{x=x,y=y})
|
||||
end
|
||||
end
|
||||
end
|
||||
local points = {}
|
||||
if(filled)then
|
||||
if y2 < y1 then x1,y1,x2,y2 = x2,y2,x1,y1 end
|
||||
if y3 < y2 then x2,y2,x3,y3 = x3,y3,x2,y2 end
|
||||
if y2 < y2 then x1,y1,x2,y2 = x2,y2,x1,y1 end
|
||||
if y1 == y2 then
|
||||
if x2 < x1 then x1,y1,x2,y2 = x2,y2,x1,y1 end
|
||||
drawFlatTopTriangle(points,x1,y1,x2,y2,x3,y3)
|
||||
elseif y2 == y3 then
|
||||
if x3 < x2 then x3,y3,x2,y2 = x2,y2,x3,y3 end
|
||||
drawFlatBottomTriangle(points,x1,y1,x2,y2,x3,y3)
|
||||
else
|
||||
local alphaSplit = (y2-y1)/(y3-y1)
|
||||
local x = x1 + ((x3 - x1) * alphaSplit)
|
||||
local y = y1 + ((y3 - y1) * alphaSplit)
|
||||
if x2 < x then
|
||||
drawFlatBottomTriangle(points,x1,y1,x2,y2,x, y)
|
||||
drawFlatTopTriangle(points,x2,y2,x,y,x3,y3)
|
||||
else
|
||||
drawFlatBottomTriangle(points,x1,y1,x,y,x1,y1)
|
||||
drawFlatTopTriangle(points,x,y,x2,y2,x3,y3)
|
||||
end
|
||||
end
|
||||
else
|
||||
points = line(x1,y1,x2,y2)
|
||||
for k,v in pairs(line(x2,y2,x3,y3))do table.insert(points, v) end
|
||||
for k,v in pairs(line(x3,y3,x1,y1))do table.insert(points, v) end
|
||||
end
|
||||
return points
|
||||
end,
|
||||
|
||||
line = line,
|
||||
|
||||
ellipse = function(xCenter, yCenter, radius1, radius2, filled)
|
||||
return ellipse(xCenter, yCenter, radius1, radius2, filled)
|
||||
end
|
||||
}
|
||||
89
Basalt/libraries/images.lua
Normal file
89
Basalt/libraries/images.lua
Normal file
@@ -0,0 +1,89 @@
|
||||
local sub,floor = string.sub,math.floor
|
||||
|
||||
local function loadNFPAsBimg(path)
|
||||
return {[1]={{}, {}, paintutils.loadImage(path)}}, "bimg"
|
||||
end
|
||||
|
||||
local function loadNFP(path)
|
||||
return paintutils.loadImage(path), "nfp"
|
||||
end
|
||||
|
||||
local function loadBIMG(path)
|
||||
local f = fs.open(path, "rb")
|
||||
local content = textutils.unserialize(f.readAll())
|
||||
f.close()
|
||||
if(content~=nil)then
|
||||
return content, "bimg"
|
||||
end
|
||||
end
|
||||
|
||||
local function loadBBF(path)
|
||||
|
||||
end
|
||||
|
||||
local function loadBBFAsBimg(path)
|
||||
|
||||
end
|
||||
|
||||
local function loadImage(path, f)
|
||||
if(f==nil)then
|
||||
if(path:find(".bimg"))then
|
||||
return loadBIMG(path)
|
||||
elseif(path:find(".bbf"))then
|
||||
return loadBBF(path)
|
||||
else
|
||||
return loadNFP(path)
|
||||
end
|
||||
end
|
||||
-- ...
|
||||
end
|
||||
|
||||
local function loadImageAsBimg(path, f)
|
||||
if(f==nil)then
|
||||
if(path:find(".bimg"))then
|
||||
return loadBIMG(path)
|
||||
elseif(path:find(".bbf"))then
|
||||
return loadBBFAsBimg(path)
|
||||
else
|
||||
return loadNFPAsBimg(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function resizeBIMG(source, w, h)
|
||||
local oW, oH = source.width or #source[1][1][1], source.height or #source[1]
|
||||
local newImg = {}
|
||||
for k,v in pairs(source)do
|
||||
if(type(k)=="number")then
|
||||
local frame = {}
|
||||
for y=1, h do
|
||||
local xT,xFG,xBG = "","",""
|
||||
local yR = floor(y / h * oH + 0.5)
|
||||
if(v[yR]~=nil)then
|
||||
for x=1, w do
|
||||
local xR = floor(x / w * oW + 0.5)
|
||||
xT = xT..sub(v[yR][1], xR,xR)
|
||||
xFG = xFG..sub(v[yR][2], xR,xR)
|
||||
xBG = xBG..sub(v[yR][3], xR,xR)
|
||||
end
|
||||
table.insert(frame, {xT, xFG, xBG})
|
||||
end
|
||||
end
|
||||
table.insert(newImg, k, frame)
|
||||
else
|
||||
newImg[k] = v
|
||||
end
|
||||
end
|
||||
newImg.width = w
|
||||
newImg.height = h
|
||||
return newImg
|
||||
end
|
||||
|
||||
return {
|
||||
loadNFP = loadNFP,
|
||||
loadBIMG = loadBIMG,
|
||||
loadImage = loadImage,
|
||||
resizeBIMG = resizeBIMG,
|
||||
loadImageAsBimg = loadImageAsBimg,
|
||||
|
||||
}
|
||||
4
Basalt/libraries/module.lua
Normal file
4
Basalt/libraries/module.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
return function(path)
|
||||
local exists, content = pcall(require, path)
|
||||
return exists and content or nil
|
||||
end
|
||||
@@ -2,14 +2,32 @@ local processes = {}
|
||||
local process = {}
|
||||
local processId = 0
|
||||
|
||||
function process:new(path, window, ...)
|
||||
local newPackage = dofile("rom/modules/main/cc/require.lua").make
|
||||
|
||||
function process:new(path, window, newEnv, ...)
|
||||
local args = {...}
|
||||
local newP = setmetatable({ path = path }, { __index = self })
|
||||
newP.window = window
|
||||
window.current = term.current
|
||||
window.redirect = term.redirect
|
||||
newP.processId = processId
|
||||
if(type(path)=="string")then
|
||||
newP.coroutine = coroutine.create(function()
|
||||
shell.execute(path, table.unpack(args))
|
||||
local pPath = shell.resolveProgram(path)
|
||||
local env = setmetatable(newEnv, {__index=_ENV})
|
||||
env.shell = shell
|
||||
env.basaltProgram=true
|
||||
env.arg = {[0]=path, table.unpack(args)}
|
||||
env.require, env.package = newPackage(env, fs.getDir(pPath))
|
||||
if(fs.exists(pPath))then
|
||||
local file = fs.open(pPath, "r")
|
||||
local content = file.readAll()
|
||||
file.close()
|
||||
local program = load(content, path, "bt", env)
|
||||
if(program~=nil)then
|
||||
return program()
|
||||
end
|
||||
end
|
||||
end)
|
||||
elseif(type(path)=="function")then
|
||||
newP.coroutine = coroutine.create(function()
|
||||
@@ -24,17 +42,21 @@ function process:new(path, window, ...)
|
||||
end
|
||||
|
||||
function process:resume(event, ...)
|
||||
local cur = term.current()
|
||||
term.redirect(self.window)
|
||||
if(self.filter~=nil)then
|
||||
if(event~=self.filter)then return end
|
||||
self.filter=nil
|
||||
end
|
||||
local ok, result = coroutine.resume(self.coroutine, event, ...)
|
||||
|
||||
if ok then
|
||||
self.filter = result
|
||||
else
|
||||
error(result)
|
||||
printError(result)
|
||||
end
|
||||
term.redirect(cur)
|
||||
return ok, result
|
||||
end
|
||||
|
||||
function process:isDead()
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
local sub = string.sub
|
||||
|
||||
local splitString = function(str, sep)
|
||||
if sep == nil then
|
||||
sep = "%s"
|
||||
@@ -9,6 +11,74 @@ local splitString = function(str, sep)
|
||||
return t
|
||||
end
|
||||
|
||||
local relations = {[0] = {8, 4, 3, 6, 5}, {4, 14, 8, 7}, {6, 10, 8, 7}, {9, 11, 8, 0}, {1, 14, 8, 0}, {13, 12, 8, 0}, {2, 10, 8, 0}, {15, 8, 10, 11, 12, 14},
|
||||
{0, 7, 1, 9, 2, 13}, {3, 11, 8, 7}, {2, 6, 7, 15}, {9, 3, 7, 15}, {13, 5, 7, 15}, {5, 12, 8, 7}, {1, 4, 7, 15}, {7, 10, 11, 12, 14}}
|
||||
|
||||
local colourNum, exponents, colourChar = {}, {}, {}
|
||||
for i = 0, 15 do exponents[2^i] = i end
|
||||
do
|
||||
local hex = "0123456789abcdef"
|
||||
for i = 1, 16 do
|
||||
colourNum[hex:sub(i, i)] = i - 1
|
||||
colourNum[i - 1] = hex:sub(i, i)
|
||||
colourChar[hex:sub(i, i)] = 2 ^ (i - 1)
|
||||
colourChar[2 ^ (i - 1)] = hex:sub(i, i)
|
||||
|
||||
local thisRel = relations[i - 1]
|
||||
for i = 1, #thisRel do thisRel[i] = 2 ^ thisRel[i] end
|
||||
end
|
||||
end
|
||||
|
||||
local function getBestColourMatch(usage)
|
||||
local lastCol = relations[exponents[usage[#usage][1]]]
|
||||
|
||||
for j = 1, #lastCol do
|
||||
local thisRelation = lastCol[j]
|
||||
for i = 1, #usage - 1 do if usage[i][1] == thisRelation then return i end end
|
||||
end
|
||||
|
||||
return 1
|
||||
end
|
||||
|
||||
local function colsToChar(pattern, totals)
|
||||
if not totals then
|
||||
local newPattern = {}
|
||||
totals = {}
|
||||
for i = 1, 6 do
|
||||
local thisVal = pattern[i]
|
||||
local thisTot = totals[thisVal]
|
||||
totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal
|
||||
end
|
||||
pattern = newPattern
|
||||
end
|
||||
|
||||
local usage = {}
|
||||
for key, value in pairs(totals) do usage[#usage + 1] = {key, value} end
|
||||
|
||||
if #usage > 1 then
|
||||
-- Reduce the chunk to two colours:
|
||||
while #usage > 2 do
|
||||
table.sort(usage, function (a, b) return a[2] > b[2] end)
|
||||
local matchToInd, usageLen = getBestColourMatch(usage), #usage
|
||||
local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1]
|
||||
for i = 1, 6 do if pattern[i] == matchFrom then
|
||||
pattern[i] = matchTo
|
||||
usage[matchToInd][2] = usage[matchToInd][2] + 1
|
||||
end end
|
||||
usage[usageLen] = nil
|
||||
end
|
||||
|
||||
-- Convert to character. Adapted from oli414's function:
|
||||
-- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/
|
||||
local data = 128
|
||||
for i = 1, #pattern - 1 do if pattern[i] ~= pattern[6] then data = data + 2^(i-1) end end
|
||||
return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]]
|
||||
else
|
||||
-- Solid colour character:
|
||||
return "\128", colourChar[pattern[1]], colourChar[pattern[1]]
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
getTextHorizontalAlign = function(text, width, textAlign, replaceChar)
|
||||
text = string.sub(text, 1, width)
|
||||
@@ -117,4 +187,36 @@ uuid = function()
|
||||
end
|
||||
return uuid()
|
||||
end,
|
||||
|
||||
array = function(arraysize, hashsize)
|
||||
return load("return {" .. ("nil,"):rep(arraysize) .. ("[0]=nil,"):rep(hashsize) .. "}")()
|
||||
end,
|
||||
|
||||
shrink = function(image, bgCol)
|
||||
local results, width, height, bgCol = {{}, {}, {}}, 0, #image + #image % 3, bgCol or colours.black
|
||||
for i = 1, #image do if #image[i] > width then width = #image[i] end end
|
||||
|
||||
for y = 0, height - 1, 3 do
|
||||
local cRow, tRow, bRow, counter = {}, {}, {}, 1
|
||||
|
||||
for x = 0, width - 1, 2 do
|
||||
-- Grab a 2x3 chunk:
|
||||
local pattern, totals = {}, {}
|
||||
|
||||
for yy = 1, 3 do for xx = 1, 2 do
|
||||
pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol
|
||||
totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1
|
||||
end end
|
||||
|
||||
cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals)
|
||||
counter = counter + 1
|
||||
end
|
||||
|
||||
results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow)
|
||||
end
|
||||
|
||||
results.width, results.height = #results[1][1], #results[1]
|
||||
|
||||
return results
|
||||
end,
|
||||
}
|
||||
243
Basalt/main.lua
243
Basalt/main.lua
@@ -6,11 +6,11 @@ local log = require("basaltLogs")
|
||||
local uuid = utils.uuid
|
||||
local createText = utils.createText
|
||||
local count = utils.tableCount
|
||||
|
||||
local moveThrottle = 300
|
||||
local dragThrottle = 50
|
||||
|
||||
local baseTerm = term.current()
|
||||
local version = "1.6.2"
|
||||
local debugger = true
|
||||
local version = "1.6.4"
|
||||
|
||||
local projectDirectory = fs.getDir(table.pack(...)[2] or "")
|
||||
|
||||
@@ -23,10 +23,56 @@ if not term.isColor or not term.isColor() then
|
||||
error('Basalt requires an advanced (golden) computer to run.', 0)
|
||||
end
|
||||
|
||||
local defaultColors = {}
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
defaultColors[k] = {baseTerm.getPaletteColor(v)}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function stop()
|
||||
updaterActive = false
|
||||
baseTerm.clear()
|
||||
baseTerm.setCursorPos(1, 1)
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
baseTerm.setPaletteColor(v, colors.packRGB(table.unpack(defaultColors[k])))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function basaltError(errMsg)
|
||||
baseTerm.clear()
|
||||
baseTerm.setBackgroundColor(colors.black)
|
||||
baseTerm.setTextColor(colors.red)
|
||||
local w,h = baseTerm.getSize()
|
||||
if(basalt.logging)then
|
||||
log(errMsg, "Error")
|
||||
end
|
||||
|
||||
local text = createText("Basalt error: "..errMsg, w)
|
||||
local yPos = 1
|
||||
for k,v in pairs(text)do
|
||||
baseTerm.setCursorPos(1,yPos)
|
||||
baseTerm.write(v)
|
||||
yPos = yPos + 1
|
||||
end
|
||||
baseTerm.setCursorPos(1,yPos+1)
|
||||
updaterActive = false
|
||||
end
|
||||
|
||||
local function schedule(f)
|
||||
assert(f~="function", "Schedule needs a function in order to work!")
|
||||
return function(...)
|
||||
local co = coroutine.create(f)
|
||||
local ok, result = coroutine.resume(co, ...)
|
||||
if(ok)then
|
||||
table.insert(schedules, co)
|
||||
else
|
||||
basaltError(result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local setVariable = function(name, var)
|
||||
@@ -46,6 +92,10 @@ local getTheme = function(name)
|
||||
end
|
||||
|
||||
local bInstance = {
|
||||
getDynamicValueEventSetting = function()
|
||||
return basalt.dynamicValueEvents
|
||||
end,
|
||||
|
||||
getMainFrame = function()
|
||||
return mainFrame
|
||||
end,
|
||||
@@ -94,6 +144,8 @@ local bInstance = {
|
||||
return baseTerm
|
||||
end,
|
||||
|
||||
schedule = schedule,
|
||||
|
||||
stop = stop,
|
||||
newFrame = Frame,
|
||||
|
||||
@@ -102,26 +154,6 @@ local bInstance = {
|
||||
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 = {}
|
||||
@@ -159,71 +191,109 @@ local function drawFrames()
|
||||
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
|
||||
local stopped, moveX, moveY = nil, nil, nil
|
||||
local moveTimer = nil
|
||||
local function mouseMoveEvent(_, stp, x, y)
|
||||
stopped, moveX, moveY = stp, x, y
|
||||
if(moveTimer==nil)then
|
||||
moveTimer = os.startTimer(moveThrottle/1000)
|
||||
end
|
||||
end
|
||||
|
||||
local function moveHandlerTimer()
|
||||
moveTimer = nil
|
||||
mainFrame:hoverHandler(moveX, moveY, stopped)
|
||||
activeFrame = mainFrame
|
||||
end
|
||||
|
||||
local btn, dragX, dragY = nil, nil, nil
|
||||
local dragTimer = nil
|
||||
local function dragHandlerTimer()
|
||||
dragTimer = nil
|
||||
mainFrame:dragHandler(btn, dragX, dragY)
|
||||
activeFrame = mainFrame
|
||||
end
|
||||
|
||||
local function mouseDragEvent(_, b, x, y)
|
||||
btn, dragX, dragY = b, x, y
|
||||
if(dragThrottle<50)then
|
||||
dragHandlerTimer()
|
||||
else
|
||||
if(dragTimer==nil)then
|
||||
dragTimer = os.startTimer(dragThrottle/1000)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function basaltUpdateEvent(event, ...)
|
||||
local a = {...}
|
||||
if(basaltEvent:sendEvent("basaltEventCycle", event, ...)==false)then return end
|
||||
if(event=="terminate")then basalt.stop() end
|
||||
if(mainFrame~=nil)then
|
||||
local mouseEvents = {
|
||||
mouse_click = mainFrame.mouseHandler,
|
||||
mouse_up = mainFrame.mouseUpHandler,
|
||||
mouse_scroll = mainFrame.scrollHandler,
|
||||
mouse_drag = mouseDragEvent,
|
||||
mouse_move = mouseMoveEvent,
|
||||
}
|
||||
local mouseEvent = mouseEvents[event]
|
||||
if(mouseEvent~=nil)then
|
||||
mouseEvent(mainFrame, ...)
|
||||
drawFrames()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if(event == "monitor_touch") then
|
||||
if(monFrames[p1]~=nil)then
|
||||
monFrames[p1]:mouseHandler(1, p2, p3, true)
|
||||
monFrames[p1]:mouseHandler(1, a[2], a[3], true)
|
||||
activeFrame = monFrames[p1]
|
||||
end
|
||||
if(count(monGroups)>0)then
|
||||
for k,v in pairs(monGroups)do
|
||||
v[1]:mouseHandler(1, p2, p3, true, p1)
|
||||
v[1]:mouseHandler(1, a[2], a[3], true, a[1])
|
||||
end
|
||||
end
|
||||
drawFrames()
|
||||
return
|
||||
end
|
||||
|
||||
if(activeFrame~=nil)then
|
||||
local keyEvents = {
|
||||
char = activeFrame.charHandler,
|
||||
key = activeFrame.keyHandler,
|
||||
key_up = activeFrame.keyUpHandler,
|
||||
}
|
||||
local keyEvent = keyEvents[event]
|
||||
if(keyEvent~=nil)then
|
||||
if(event == "key")then
|
||||
activeKey[a[1]] = true
|
||||
elseif(event == "key_up")then
|
||||
activeKey[a[1]] = false
|
||||
end
|
||||
keyEvent(activeFrame, ...)
|
||||
drawFrames()
|
||||
return
|
||||
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
|
||||
if(event=="timer")and(a[1]==moveTimer)then
|
||||
moveHandlerTimer()
|
||||
elseif(event=="timer")and(a[1]==dragTimer)then
|
||||
dragHandlerTimer()
|
||||
else
|
||||
for k, v in pairs(frames) do
|
||||
v:eventHandler(event, p1, p2, p3, p4)
|
||||
v:eventHandler(event, ...)
|
||||
end
|
||||
end
|
||||
handleSchedules(event, p1, p2, p3, p4)
|
||||
handleSchedules(event, ...)
|
||||
drawFrames()
|
||||
end
|
||||
|
||||
basalt = {
|
||||
logging = false,
|
||||
dynamicValueEvents = false,
|
||||
setTheme = setTheme,
|
||||
getTheme = getTheme,
|
||||
drawFrames = drawFrames,
|
||||
@@ -242,6 +312,28 @@ basalt = {
|
||||
log(...)
|
||||
end,
|
||||
|
||||
setMouseMoveThrottle = function(amount)
|
||||
if(_HOST:find("CraftOS%-PC"))then
|
||||
if(config.get("mouse_move_throttle")~=10)then config.set("mouse_move_throttle", 10) end
|
||||
if(amount<100)then
|
||||
moveThrottle = 100
|
||||
else
|
||||
moveThrottle = amount
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
setMouseDragThrottle = function(amount)
|
||||
if(amount<=0)then
|
||||
dragThrottle = 0
|
||||
else
|
||||
dragTimer = nil
|
||||
dragThrottle = amount
|
||||
end
|
||||
end,
|
||||
|
||||
autoUpdate = function(isActive)
|
||||
updaterActive = isActive
|
||||
if(isActive==nil)then updaterActive = true end
|
||||
@@ -258,9 +350,9 @@ basalt = {
|
||||
end
|
||||
end,
|
||||
|
||||
update = function(event, p1, p2, p3, p4)
|
||||
update = function(event, ...)
|
||||
if (event ~= nil) then
|
||||
local ok, err = xpcall(basaltUpdateEvent, debug.traceback, event, p1, p2, p3, p4)
|
||||
local ok, err = xpcall(basaltUpdateEvent, debug.traceback, event, ...)
|
||||
if not(ok)then
|
||||
basaltError(err)
|
||||
return
|
||||
@@ -304,18 +396,7 @@ basalt = {
|
||||
end
|
||||
end,
|
||||
|
||||
schedule = function(f)
|
||||
assert(f~="function", "Schedule needs a function in order to work!")
|
||||
return function(...)
|
||||
local co = coroutine.create(f)
|
||||
local ok, result = coroutine.resume(co, ...)
|
||||
if(ok)then
|
||||
table.insert(schedules, co)
|
||||
else
|
||||
basaltError(result)
|
||||
end
|
||||
end
|
||||
end,
|
||||
schedule = schedule,
|
||||
|
||||
createFrame = function(name)
|
||||
name = name or uuid()
|
||||
|
||||
4
Basalt/module.lua
Normal file
4
Basalt/module.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
return function(path)
|
||||
local exists, content = pcall(require, path)
|
||||
return exists and content or nil
|
||||
end
|
||||
@@ -1,7 +1,9 @@
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local basaltEvent = require("basaltEvent")
|
||||
|
||||
local floor,sin,cos,pi = math.floor,math.sin,math.cos,math.pi
|
||||
local floor,sin,cos,pi,sqrt,pow = math.floor,math.sin,math.cos,math.pi,math.sqrt,math.pow
|
||||
|
||||
-- You can find the easing curves here https://easings.net
|
||||
|
||||
local lerp = function(s, e, pct)
|
||||
return s + (e - s) * pct
|
||||
@@ -39,16 +41,183 @@ local easeInOutSine = function(t)
|
||||
return -(cos(pi * x) - 1) / 2
|
||||
end
|
||||
|
||||
local easeInBack = function(t)
|
||||
local c1 = 1.70158;
|
||||
local c3 = c1 + 1
|
||||
return c3*t^3-c1*t^2
|
||||
end
|
||||
|
||||
local easeInCubic = function(t)
|
||||
return t^3
|
||||
end
|
||||
|
||||
local easeInElastic = function(t)
|
||||
local c4 = (2*pi)/3;
|
||||
return t == 0 and 0 or (t == 1 and 1 or (
|
||||
-2^(10*t-10)*sin((t*10-10.75)*c4)
|
||||
))
|
||||
end
|
||||
|
||||
local function easeInExpo(t)
|
||||
return t == 0 and 0 or 2^(10*t-10)
|
||||
end
|
||||
|
||||
local function easeInExpo(t)
|
||||
return t == 0 and 0 or 2^(10*t-10)
|
||||
end
|
||||
|
||||
local function easeInOutBack(t)
|
||||
local c1 = 1.70158;
|
||||
local c2 = c1 * 1.525;
|
||||
return t < 0.5 and ((2*t)^2*((c2+1)*2*t-c2))/2 or ((2*t-2)^2*((c2+1)*(t*2-2)+c2)+2)/2
|
||||
end
|
||||
|
||||
local function easeInOutCubic(t)
|
||||
return t < 0.5 and 4 * t^3 or 1-(-2*t+2)^3 / 2
|
||||
end
|
||||
|
||||
local function easeInOutElastic(t)
|
||||
local c5 = (2*pi) / 4.5
|
||||
return t==0 and 0 or (t == 1 and 1 or (t < 0.5 and -(2^(20*t-10) * sin((20*t - 11.125) * c5))/2 or (2^(-20*t+10) * sin((20*t - 11.125) * c5))/2 + 1))
|
||||
end
|
||||
|
||||
local function easeInOutExpo(t)
|
||||
return t == 0 and 0 or (t == 1 and 1 or (t < 0.5 and 2^(20*t-10)/2 or (2-2^(-20*t+10)) /2))
|
||||
end
|
||||
|
||||
local function easeInOutQuad(t)
|
||||
return t < 0.5 and 2*t^2 or 1-(-2*t+2)^2/2
|
||||
end
|
||||
|
||||
local function easeInOutQuart(t)
|
||||
return t < 0.5 and 8*t^4 or 1 - (-2*t+2)^4 / 2
|
||||
end
|
||||
|
||||
local function easeInOutQuint(t)
|
||||
return t < 0.5 and 16*t^5 or 1-(-2*t+2)^5 / 2
|
||||
end
|
||||
|
||||
local function easeInQuad(t)
|
||||
return t^2
|
||||
end
|
||||
|
||||
local function easeInQuart(t)
|
||||
return t^4
|
||||
end
|
||||
|
||||
local function easeInQuint(t)
|
||||
return t^5
|
||||
end
|
||||
|
||||
local function easeOutBack(t)
|
||||
local c1 = 1.70158;
|
||||
local c3 = c1 + 1
|
||||
return 1+c3*(t-1)^3+c1*(t-1)^2
|
||||
end
|
||||
|
||||
local function easeOutCubic(t)
|
||||
return 1 - (1-t)^3
|
||||
end
|
||||
|
||||
local function easeOutElastic(t)
|
||||
local c4 = (2*pi)/3;
|
||||
|
||||
return t == 0 and 0 or (t == 1 and 1 or (2^(-10*t)*sin((t*10-0.75)*c4)+1))
|
||||
end
|
||||
|
||||
local function easeOutExpo(t)
|
||||
return t == 1 and 1 or 1-2^(-10*t)
|
||||
end
|
||||
|
||||
local function easeOutQuad(t)
|
||||
return 1 - (1 - t) * (1 - t)
|
||||
end
|
||||
|
||||
local function easeOutQuart(t)
|
||||
return 1 - (1-t)^4
|
||||
end
|
||||
|
||||
local function easeOutQuint(t)
|
||||
return 1 - (1 - t)^5
|
||||
end
|
||||
|
||||
local function easeInCirc(t)
|
||||
return 1 - sqrt(1 - pow(t, 2))
|
||||
end
|
||||
|
||||
local function easeOutCirc(t)
|
||||
return sqrt(1 - pow(t - 1, 2))
|
||||
end
|
||||
|
||||
local function easeInOutCirc(t)
|
||||
return t < 0.5 and (1 - sqrt(1 - pow(2 * t, 2))) / 2 or (sqrt(1 - pow(-2 * t + 2, 2)) + 1) / 2;
|
||||
end
|
||||
|
||||
local function easeOutBounce(t)
|
||||
local n1 = 7.5625;
|
||||
local d1 = 2.75;
|
||||
|
||||
if (t < 1 / d1)then
|
||||
return n1 * t * t
|
||||
elseif (t < 2 / d1)then
|
||||
local a = t - 1.5 / d1
|
||||
return n1 * a * a + 0.75;
|
||||
elseif (t < 2.5 / d1)then
|
||||
local a = t - 2.25 / d1
|
||||
return n1 * a * a + 0.9375;
|
||||
else
|
||||
local a = t - 2.625 / d1
|
||||
return n1 * a * a + 0.984375;
|
||||
end
|
||||
end
|
||||
|
||||
local function easeInBounce(t)
|
||||
return 1 - easeOutBounce(1 - t)
|
||||
end
|
||||
|
||||
local function easeInOutBounce(t)
|
||||
return x < 0.5 and (1 - easeOutBounce(1 - 2 * t)) / 2 or (1 + easeOutBounce(2 * t - 1)) / 2;
|
||||
end
|
||||
|
||||
|
||||
|
||||
local lerp = {
|
||||
linear = linear,
|
||||
lerp = lerp,
|
||||
flip=flip,
|
||||
easeIn=easeIn,
|
||||
easeOut=easeOut,
|
||||
easeInOut=easeInOut,
|
||||
easeOutSine = easeOutSine,
|
||||
easeInSine = easeInSine,
|
||||
easeInBack=easeInBack,
|
||||
easeInCubic=easeInCubic,
|
||||
easeInElastic=easeInElastic,
|
||||
easeInExpo=easeInExpo,
|
||||
easeInQuad=easeInQuad,
|
||||
easeInQuart=easeInQuart,
|
||||
easeInQuint=easeInQuint,
|
||||
easeInCirc=easeInCirc,
|
||||
easeInBounce=easeInBounce,
|
||||
easeOut=easeOut,
|
||||
easeOutSine = easeOutSine,
|
||||
easeOutBack=easeOutBack,
|
||||
easeOutCubic=easeOutCubic,
|
||||
easeOutElastic=easeOutElastic,
|
||||
easeOutExpo=easeOutExpo,
|
||||
easeOutQuad=easeOutQuad,
|
||||
easeOutQuart=easeOutQuart,
|
||||
easeOutQuint=easeOutQuint,
|
||||
easeOutCirc=easeOutCirc,
|
||||
easeOutBounce=easeOutBounce,
|
||||
easeInOut=easeInOut,
|
||||
easeInOutSine = easeInOutSine,
|
||||
easeInOutBack=easeInOutBack,
|
||||
easeInOutCubic=easeInOutCubic,
|
||||
easeInOutElastic=easeInOutElastic,
|
||||
easeInOutExpo=easeInOutExpo,
|
||||
easeInOutQuad=easeInOutQuad,
|
||||
easeInOutQuart=easeInOutQuart,
|
||||
easeInOutQuint=easeInOutQuint,
|
||||
easeInOutCirc=easeInOutCirc,
|
||||
easeInOutBounce=easeInOutBounce,
|
||||
}
|
||||
|
||||
local activeAnimations = {}
|
||||
@@ -185,6 +354,11 @@ return function(name)
|
||||
return self
|
||||
end,
|
||||
|
||||
addMode = function(self, modeId, modeF)
|
||||
lerp[modeId] = modeF
|
||||
return self
|
||||
end,
|
||||
|
||||
generateXMLEventFunction = function(self, func, val)
|
||||
local createF = function(str)
|
||||
if(str:sub(1,1)=="#")then
|
||||
@@ -362,9 +536,9 @@ return function(name)
|
||||
return self
|
||||
end,
|
||||
|
||||
add = function(self, func, wait)
|
||||
add = function(self, func, timer)
|
||||
lastFunc = func
|
||||
addAnimationPart((wait or nextWaitTimer) + (animations[#animations]~=nil and animations[#animations].t or 0), func)
|
||||
addAnimationPart((timer or nextWaitTimer) + (animations[#animations]~=nil and animations[#animations].t or 0), func)
|
||||
return self
|
||||
end;
|
||||
|
||||
|
||||
@@ -17,8 +17,10 @@ return function(name)
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
self.bgColor = self.parent:getTheme("ButtonBG")
|
||||
self.fgColor = self.parent:getTheme("ButtonText")
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ButtonBG")
|
||||
self.fgColor = self.parent:getTheme("ButtonText")
|
||||
end
|
||||
end,
|
||||
getType = function(self)
|
||||
return objectType
|
||||
@@ -58,8 +60,9 @@ return function(name)
|
||||
|
||||
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))
|
||||
local val = self:getValue()
|
||||
self.parent:setText(obx + (w/2-val:len()/2), oby + (n - 1), utils.getTextHorizontalAlign(val, val:len(), textHorizontalAlign))
|
||||
self.parent:setFG(obx + (w/2-val:len()/2), oby + (n - 1), utils.getTextHorizontalAlign(tHex[self.fgColor]:rep(val:len()), val:len(), textHorizontalAlign))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -72,10 +72,12 @@ return function(name)
|
||||
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)
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("CheckboxBG")
|
||||
self.fgColor = self.parent:getTheme("CheckboxText")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ return function(name)
|
||||
|
||||
clear = function(self)
|
||||
list = {}
|
||||
self:setValue({})
|
||||
self:setValue({}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -101,7 +101,7 @@ return function(name)
|
||||
end;
|
||||
|
||||
selectItem = function(self, index)
|
||||
self:setValue(list[index] or {})
|
||||
self:setValue(list[index] or {}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -109,7 +109,7 @@ return function(name)
|
||||
setSelectedItem = function(self, bgCol, fgCol, active)
|
||||
itemSelectedBG = bgCol or self.bgColor
|
||||
itemSelectedFG = fgCol or self.fgColor
|
||||
selectionColorActive = active
|
||||
selectionColorActive = active~=nil and active
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -120,6 +120,10 @@ return function(name)
|
||||
return self
|
||||
end,
|
||||
|
||||
getDropdownSize = function(self)
|
||||
return dropdownW, dropdownH
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, button, x, y)
|
||||
if (isOpened) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
@@ -225,14 +229,14 @@ return function(name)
|
||||
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)
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("DropdownBG")
|
||||
self.fgColor = self.parent:getTheme("DropdownText")
|
||||
itemSelectedBG = self.parent:getTheme("SelectionBG")
|
||||
itemSelectedFG = self.parent:getTheme("SelectionText")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
local Object = require("Object")
|
||||
local geometric = require("geometricPoints")
|
||||
local tHex = require("tHex")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local bimgLib = require("bimg")
|
||||
local images = require("images")
|
||||
|
||||
local sub,len,max,min = string.sub,string.len,math.max,math.min
|
||||
|
||||
@@ -9,420 +10,181 @@ return function(name)
|
||||
-- Graphic
|
||||
local base = Object(name)
|
||||
local objectType = "Graphic"
|
||||
base:setZIndex(2)
|
||||
local imgData = bimgLib()
|
||||
local bimgFrame = imgData.getFrameObject(1)
|
||||
local bimg
|
||||
local selectedFrame = 1
|
||||
base:setZIndex(5)
|
||||
|
||||
local graphicObjects = {}
|
||||
local graphic = {}
|
||||
local shrinkedGraphic = {}
|
||||
local isGraphicShrinked = false
|
||||
local xOffset, yOffset = 0, 0
|
||||
local dragable = false
|
||||
local xMouse,yMouse
|
||||
local w, h = 40, 15
|
||||
local canvasSizeChanged = false
|
||||
|
||||
local tColourLookup = {}
|
||||
for n=1,16 do
|
||||
tColourLookup[ string.byte( "0123456789abcdef",n,n ) ] = 2^(n-1)
|
||||
end
|
||||
|
||||
local function stringToTable(str)
|
||||
local t = {}
|
||||
for i = 1, #str do
|
||||
t[i] = str:sub(i, i)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local function setBG(x, y, width, height, colorStr)
|
||||
if (y >= 1) and (y <= height) then
|
||||
if (x + len(colorStr) > 0) and (x <= width) then
|
||||
local oldCache = graphic[y]
|
||||
local newCache
|
||||
local nEnd = x + #colorStr - 1
|
||||
|
||||
if (x < 1) then
|
||||
colorStr = sub(colorStr, 1 - x + 1, width - x + 1)
|
||||
elseif (nEnd > width) then
|
||||
colorStr = sub(colorStr, 1, width - x + 1)
|
||||
end
|
||||
|
||||
if (x > 1) then
|
||||
newCache = sub(oldCache, 1, x - 1) .. colorStr
|
||||
else
|
||||
newCache = colorStr
|
||||
end
|
||||
if nEnd < width then
|
||||
newCache = newCache .. sub(oldCache, nEnd + 1, width)
|
||||
end
|
||||
graphic[y] = newCache
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function redrawCanvasSize()
|
||||
local w,h = w,h
|
||||
if(isGraphicShrinked)then w = w*2 h = h*3 end
|
||||
for y=1,h do
|
||||
if(graphic[y]~=nil)then
|
||||
if(w>graphic[y]:len())then
|
||||
graphic[y] = graphic[y]..(tHex[base.bgColor]):rep(w-graphic[y]:len())
|
||||
else
|
||||
graphic[y] = graphic[y]:sub(1,w)
|
||||
end
|
||||
else
|
||||
graphic[y] = (tHex[base.bgColor]):rep(w)
|
||||
end
|
||||
end
|
||||
end
|
||||
redrawCanvasSize()
|
||||
|
||||
|
||||
local function shrink()
|
||||
local function parseLine( tImageArg, sLine )
|
||||
local tLine = {}
|
||||
for x=1,sLine:len() do
|
||||
tLine[x] = tColourLookup[ string.byte(sLine,x,x) ] or 0
|
||||
end
|
||||
table.insert( tImageArg, tLine )
|
||||
end
|
||||
function parseImage( sRawData )
|
||||
if type( sRawData ) ~= "string" then
|
||||
error( "bad argument #1 (expected string, got " .. type( sRawData ) .. ")" )
|
||||
end
|
||||
local tImage = {}
|
||||
for sLine in ( sRawData .. "\n" ):gmatch( "(.-)\n" ) do
|
||||
parseLine( tImage, sLine )
|
||||
end
|
||||
return tImage
|
||||
end
|
||||
|
||||
local rawImg = ""
|
||||
for y=1,#graphic do
|
||||
if(y==#graphic)then
|
||||
rawImg = rawImg..graphic[y]
|
||||
else
|
||||
rawImg = rawImg..graphic[y].."\n"
|
||||
end
|
||||
end
|
||||
local img = parseImage(rawImg)
|
||||
-- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
|
||||
local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 },
|
||||
{ 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } }
|
||||
|
||||
local colourNum, exponents, colourChar = {}, {}, {}
|
||||
for i = 0, 15 do
|
||||
exponents[2 ^ i] = i
|
||||
end
|
||||
do
|
||||
local hex = "0123456789abcdef"
|
||||
for i = 1, 16 do
|
||||
colourNum[hex:sub(i, i)] = i - 1
|
||||
colourNum[i - 1] = hex:sub(i, i)
|
||||
colourChar[hex:sub(i, i)] = 2 ^ (i - 1)
|
||||
colourChar[2 ^ (i - 1)] = hex:sub(i, i)
|
||||
|
||||
local thisRel = relations[i - 1]
|
||||
for i = 1, #thisRel do
|
||||
thisRel[i] = 2 ^ thisRel[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function getBestColourMatch(usage)
|
||||
local lastCol = relations[exponents[usage[#usage][1]]]
|
||||
|
||||
for j = 1, #lastCol do
|
||||
local thisRelation = lastCol[j]
|
||||
for i = 1, #usage - 1 do
|
||||
if usage[i][1] == thisRelation then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return 1
|
||||
end
|
||||
|
||||
local function colsToChar(pattern, totals)
|
||||
if not totals then
|
||||
local newPattern = {}
|
||||
totals = {}
|
||||
for i = 1, 6 do
|
||||
local thisVal = pattern[i]
|
||||
local thisTot = totals[thisVal]
|
||||
totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal
|
||||
end
|
||||
pattern = newPattern
|
||||
end
|
||||
|
||||
local usage = {}
|
||||
for key, value in pairs(totals) do
|
||||
usage[#usage + 1] = { key, value }
|
||||
end
|
||||
|
||||
if #usage > 1 then
|
||||
-- Reduce the chunk to two colours:
|
||||
while #usage > 2 do
|
||||
table.sort(usage, function(a, b)
|
||||
return a[2] > b[2]
|
||||
end)
|
||||
local matchToInd, usageLen = getBestColourMatch(usage), #usage
|
||||
local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1]
|
||||
for i = 1, 6 do
|
||||
if pattern[i] == matchFrom then
|
||||
pattern[i] = matchTo
|
||||
usage[matchToInd][2] = usage[matchToInd][2] + 1
|
||||
end
|
||||
end
|
||||
usage[usageLen] = nil
|
||||
end
|
||||
|
||||
-- Convert to character. Adapted from oli414's function:
|
||||
-- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/
|
||||
local data = 128
|
||||
for i = 1, #pattern - 1 do
|
||||
if pattern[i] ~= pattern[6] then
|
||||
data = data + 2 ^ (i - 1)
|
||||
end
|
||||
end
|
||||
return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]]
|
||||
else
|
||||
-- Solid colour character:
|
||||
return "\128", colourChar[pattern[1]], colourChar[pattern[1]]
|
||||
end
|
||||
end
|
||||
|
||||
local results, width, height, bgCol = { {}, {}, {} }, 0, #img + #img % 3, base.bgColor or colors.black
|
||||
for i = 1, #img do
|
||||
if #img[i] > width then
|
||||
width = #img[i]
|
||||
end
|
||||
end
|
||||
|
||||
for y = 0, height - 1, 3 do
|
||||
local cRow, tRow, bRow, counter = {}, {}, {}, 1
|
||||
|
||||
for x = 0, width - 1, 2 do
|
||||
-- Grab a 2x3 chunk:
|
||||
local pattern, totals = {}, {}
|
||||
|
||||
for yy = 1, 3 do
|
||||
for xx = 1, 2 do
|
||||
pattern[#pattern + 1] = (img[y + yy] and img[y + yy][x + xx]) and (img[y + yy][x + xx] == 0 and bgCol or img[y + yy][x + xx]) or bgCol
|
||||
totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1
|
||||
end
|
||||
end
|
||||
|
||||
cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals)
|
||||
counter = counter + 1
|
||||
end
|
||||
|
||||
results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow)
|
||||
end
|
||||
|
||||
results.width, results.height = #results[1][1], #results[1]
|
||||
|
||||
shrinkedGraphic = results
|
||||
end
|
||||
|
||||
local function redraw()
|
||||
local w,h = w,h
|
||||
if(isGraphicShrinked)then w = w*2 h = h*3 end
|
||||
for k,v in pairs(graphicObjects)do
|
||||
for a,b in pairs(v[1])do
|
||||
setBG(b.x, b.y, w, h, v[2])
|
||||
end
|
||||
end
|
||||
if(isGraphicShrinked)then
|
||||
shrink()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
self.bgColor = self.parent:getTheme("GraphicBG")
|
||||
end,
|
||||
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
setSize = function(self, width, height, rel)
|
||||
base.setSize(self, width, height, rel)
|
||||
if not(canvasSizeChanged)then
|
||||
w = width
|
||||
h = height
|
||||
redrawCanvasSize()
|
||||
setOffset = function(self, _x, _y, rel)
|
||||
if(rel)then
|
||||
xOffset = xOffset + _x or 0
|
||||
yOffset = yOffset + _y or 0
|
||||
else
|
||||
xOffset = _x or xOffset
|
||||
yOffset = _y or yOffset
|
||||
end
|
||||
redraw()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setOffset = function(self, x, y)
|
||||
xOffset = x or xOffset
|
||||
yOffset = y or yOffset
|
||||
return self
|
||||
end,
|
||||
|
||||
setCanvasSize = function(self, width, height)
|
||||
w,h = width,height
|
||||
canvasSizeChanged = true
|
||||
redrawCanvasSize()
|
||||
return self
|
||||
end,
|
||||
|
||||
clearCanvas = function(self)
|
||||
graphicObjects = {}
|
||||
graphic = {}
|
||||
redrawCanvasSize()
|
||||
end,
|
||||
|
||||
getOffset = function(self)
|
||||
return xOffset,yOffset
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("text", data)~=nil)then self:setText(xmlValue("text", data)) end
|
||||
if(xmlValue("xOffset", data)~=nil)then self:setOffset(xmlValue("xOffset", data), yOffset) end
|
||||
if(xmlValue("yOffset", data)~=nil)then self:setOffset(xOffset, xmlValue("yOffset", data)) end
|
||||
if(xmlValue("wCanvas", data)~=nil)then w = xmlValue("wCanvas", data) end
|
||||
if(xmlValue("hCanvas", data)~=nil)then h = xmlValue("hCanvas", data) end
|
||||
if(xmlValue("shrink", data)~=nil)then if(xmlValue("shrink", data))then self:shrink() end end
|
||||
if(xmlValue("dragable", data)~=nil)then if(xmlValue("dragable", data))then dragable = true end end
|
||||
if(data["ellipse"]~=nil)then
|
||||
local tab = data["ellipse"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
local col = colors[xmlValue("color", v)]
|
||||
local rad1 = xmlValue("radius", v)
|
||||
local rad2 = xmlValue("radius2", v)
|
||||
local x = xmlValue("x", v)
|
||||
local y = xmlValue("y", v)
|
||||
local filled = xmlValue("filled", v)
|
||||
self:addEllipse(col, rad1, rad2, x, y, filled)
|
||||
end
|
||||
end
|
||||
if(data["circle"]~=nil)then
|
||||
local tab = data["circle"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
local col = colors[xmlValue("color", v)]
|
||||
local rad = tonumber(xmlValue("radius", v))
|
||||
local x = tonumber(xmlValue("x", v))
|
||||
local y = tonumber(xmlValue("y", v))
|
||||
local filled = xmlValue("filled", v)
|
||||
self:addCircle(col, rad, x, y, filled)
|
||||
end
|
||||
end
|
||||
if(data["line"]~=nil)then
|
||||
local tab = data["line"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
local col = colors[xmlValue("color", v)]
|
||||
local x = tonumber(xmlValue("x", v))
|
||||
local x2 = tonumber(xmlValue("x2", v))
|
||||
local y = tonumber(xmlValue("y", v))
|
||||
local y2 = tonumber(xmlValue("y2", v))
|
||||
self:addLine(col, x, y, x2, y2)
|
||||
end
|
||||
end
|
||||
|
||||
if(data["rectangle"]~=nil)then
|
||||
local tab = data["rectangle"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
local col = colors[xmlValue("color", v)]
|
||||
local x = tonumber(xmlValue("x", v))
|
||||
local x2 = tonumber(xmlValue("x2", v))
|
||||
local y = tonumber(xmlValue("y", v))
|
||||
local y2 = tonumber(xmlValue("y2", v))
|
||||
local filled = xmlValue("filled", v)=="true" and true or false
|
||||
self:addRectangle(col, x, y, x2, y2, filled)
|
||||
end
|
||||
end
|
||||
if(data["triangle"]~=nil)then
|
||||
local tab = data["triangle"]
|
||||
if(tab.properties~=nil)then tab = {tab} end
|
||||
for k,v in pairs(tab)do
|
||||
local col = colors[xmlValue("color", v)]
|
||||
local x = tonumber(xmlValue("x", v))
|
||||
local x2 = tonumber(xmlValue("x2", v))
|
||||
local x3 = tonumber(xmlValue("x2", v))
|
||||
local y = tonumber(xmlValue("y", v))
|
||||
local y2 = tonumber(xmlValue("y2", v))
|
||||
local y3 = tonumber(xmlValue("y3", v))
|
||||
local filled = xmlValue("filled", v)
|
||||
self:addTriangle(col, x, y, x2, y2, x3, y3, filled)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return self
|
||||
end,
|
||||
|
||||
addCircle = function(self, color, rad, x, y, filled)
|
||||
local col = tHex[color]
|
||||
table.insert(graphicObjects, {geometric.circle(x or 1, y or 1, rad, filled), tHex[color]})
|
||||
redraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
addEllipse = function(self, color, rad, rad2, x, y, filled)
|
||||
table.insert(graphicObjects, {geometric.ellipse(x or 1, y or 1, rad, rad2, filled), tHex[color]})
|
||||
redraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
addLine = function(self, color, x1, y1, x2, y2)
|
||||
table.insert(graphicObjects, {geometric.line(x1 or 1, y1 or 1, x2 or 1, y2 or 1), tHex[color]})
|
||||
redraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
addTriangle = function(self, color, x1, y1, x2, y2, x3, y3, filled)
|
||||
table.insert(graphicObjects, {geometric.triangle(x1 or 1, y1 or 1, x2 or 1, y2 or 1, x3 or 1, y3 or 1, filled), tHex[color]})
|
||||
redraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
addRectangle = function(self, color, x1, y1, x2, y2, filled)
|
||||
table.insert(graphicObjects, {geometric.rectangle(x1 or 1, y1 or 1, x2 or 1, y2 or 1, filled), tHex[color]})
|
||||
redraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
shrink = function(self)
|
||||
isGraphicShrinked = true
|
||||
redrawCanvasSize()
|
||||
shrink()
|
||||
return self
|
||||
end,
|
||||
|
||||
setDragable = function(self, drag)
|
||||
dragable = drag == true and true or false
|
||||
return self
|
||||
end,
|
||||
|
||||
mouseHandler = function(self, event, button, x, y)
|
||||
if(base.mouseHandler(self, event, button, x, y))then
|
||||
if(dragable)then
|
||||
if(event=="mouse_click")then
|
||||
xMouse,yMouse = x,y
|
||||
end
|
||||
|
||||
if(event=="mouse_drag")then
|
||||
if(xMouse~=nil)and(yMouse~=nil)then
|
||||
xOffset = max(min(xOffset+xMouse-x, w-self:getWidth()),0)
|
||||
xMouse = x
|
||||
yOffset = max(min(yOffset+yMouse-y, h-self:getHeight()),0)
|
||||
yMouse = y
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
selectFrame = function(self, id)
|
||||
if(imgData.getFrameObject(id)==nil)then
|
||||
imgData.addFrame(id)
|
||||
end
|
||||
return false
|
||||
bimgFrame = imgData.getFrameObject(id)
|
||||
bimg = bimgFrame.getImage(id)
|
||||
selectedFrame = id
|
||||
self:updateDraw()
|
||||
end,
|
||||
|
||||
addFrame = function(self, id)
|
||||
imgData.addFrame(id)
|
||||
return self
|
||||
end,
|
||||
|
||||
getFrameMetadata = function(self, id, key)
|
||||
return imgData.getFrameData(id, key)
|
||||
end,
|
||||
|
||||
setFrameMetadata = function(self, id, key, val)
|
||||
imgData.setFrameData(id, key, val)
|
||||
return self
|
||||
end,
|
||||
|
||||
getMetadata = function(self, key)
|
||||
return imgData.getMetadata(key)
|
||||
end,
|
||||
|
||||
setMetadata = function(self, key, value)
|
||||
return imgData.setMetadata(key, value)
|
||||
end,
|
||||
|
||||
getFrame = function(self, id)
|
||||
return imgData.getFrame(id)
|
||||
end,
|
||||
|
||||
getFrameObject = function(self, id)
|
||||
return imgData.getFrameObject(id)
|
||||
end,
|
||||
|
||||
removeFrame = function(self, id)
|
||||
imgData.removeFrame(id)
|
||||
return self
|
||||
end,
|
||||
|
||||
moveFrame = function(self, id, dir)
|
||||
imgData.moveFrame(id, dir)
|
||||
return self
|
||||
end,
|
||||
|
||||
getFrames = function(self)
|
||||
return imgData.getFrames()
|
||||
end,
|
||||
|
||||
getFrameCount = function(self)
|
||||
return #imgData.getFrames()
|
||||
end,
|
||||
|
||||
getSelectedFrame = function(self)
|
||||
return selectedFrame
|
||||
end,
|
||||
|
||||
blit = function(self, text, fg, bg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.blit(text, fg, bg, x, y)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setText = function(self, text, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.text(text, x, y)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setBg = function(self, bg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.bg(bg, x, y)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setFg = function(self, fg, _x, _y)
|
||||
x = _x or x
|
||||
y = _y or y
|
||||
bimgFrame.fg(fg, x, y)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getImageSize = function(self)
|
||||
return imgData.getSize()
|
||||
end,
|
||||
|
||||
setImageSize = function(self, w, h)
|
||||
imgData.setSize(w, h)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
resizeImage = function(self, w, h)
|
||||
local newBimg = images.resizeBIMG(imgData.createBimg(), w, h)
|
||||
imgData = bimgLib(newBimg)
|
||||
selectedFrame = 1
|
||||
bimgFrame = imgData.getFrameObject(1)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
loadImage = function(self, path)
|
||||
if(fs.exists(path))then
|
||||
local newBimg = images.loadBIMG(path)
|
||||
imgData = bimgLib(newBimg)
|
||||
selectedFrame = 1
|
||||
bimgFrame = imgData.getFrameObject(1)
|
||||
bimg = bimgFrame.getImage()
|
||||
self:updateDraw()
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
clear = function(self)
|
||||
imgData = bimgLib()
|
||||
bimg = nil
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
getImage = function(self)
|
||||
return imgData.createBimg()
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
@@ -430,41 +192,22 @@ return function(name)
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if(self.bgColor~=false)then
|
||||
self.parent:drawBackgroundBox(obx, oby, w, h, self.bgColor)
|
||||
end
|
||||
if (isGraphicShrinked) then
|
||||
-- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
|
||||
local t, tC, bC = shrinkedGraphic[1], shrinkedGraphic[2], shrinkedGraphic[3]
|
||||
for i = 1, shrinkedGraphic.height do
|
||||
local x, y = obx+xOffset, oby + i - 1 + yOffset
|
||||
if(y>oby-1)and(y<=oby+h-1)and(x<=w+obx)then
|
||||
local tI = t[i]
|
||||
local xpos,substart,subend = max(x, obx), max(1 - x + 1, 1), min(w - (x-obx), w)
|
||||
if type(tI) == "string" then
|
||||
self.parent:setText(xpos, y, sub(tI, substart, subend))
|
||||
self.parent:setFG(xpos, y, sub(tC[i], substart, subend))
|
||||
self.parent:setBG(xpos, y, sub(bC[i], substart, subend))
|
||||
elseif type(tI) == "table" then
|
||||
self.parent:setText(xpos, y, sub(tI[2], substart, subend))
|
||||
self.parent:setFG(xpos, y, sub(tC[i], substart, subend))
|
||||
self.parent:setBG(xpos, y, sub(bC[i], substart, subend))
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for i = 1, #graphic do
|
||||
local x, y = obx+xOffset, oby + i - 1 + yOffset
|
||||
if(y>oby-1)and(y<=oby+h-1)and(x<=w+obx)then
|
||||
local xpos,substart,subend = max(x, obx), max(1 - x + 1, 1), min(w - (x-obx), w)
|
||||
self.parent:setBG(xpos, y, sub(graphic[i],substart,subend))
|
||||
if(bimg~=nil)then
|
||||
for k,v in pairs(bimg)do
|
||||
if(k<=h-yOffset)and(k+yOffset>=1)then
|
||||
self.parent:blit(obx+xOffset, oby+k-1+yOffset, v[1], v[2], v[3])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self:setVisualChanged(false)
|
||||
end
|
||||
end;
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("GraphicBG")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
return setmetatable(object, base)
|
||||
|
||||
@@ -1,197 +1,158 @@
|
||||
local Object = require("Object")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local images = require("images")
|
||||
|
||||
local unpack,sub = table.unpack,string.sub
|
||||
return function(name)
|
||||
-- Image
|
||||
local base = Object(name)
|
||||
local objectType = "Image"
|
||||
base:setZIndex(2)
|
||||
local originalImage
|
||||
local image
|
||||
local shrinkedImage
|
||||
local imageGotShrinked = false
|
||||
local curFrame = 1
|
||||
local infinitePlay = false
|
||||
local animTimer
|
||||
local usePalette = false
|
||||
|
||||
local function shrink()
|
||||
-- shrinkSystem is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
|
||||
local relations = { [0] = { 8, 4, 3, 6, 5 }, { 4, 14, 8, 7 }, { 6, 10, 8, 7 }, { 9, 11, 8, 0 }, { 1, 14, 8, 0 }, { 13, 12, 8, 0 }, { 2, 10, 8, 0 }, { 15, 8, 10, 11, 12, 14 },
|
||||
{ 0, 7, 1, 9, 2, 13 }, { 3, 11, 8, 7 }, { 2, 6, 7, 15 }, { 9, 3, 7, 15 }, { 13, 5, 7, 15 }, { 5, 12, 8, 7 }, { 1, 4, 7, 15 }, { 7, 10, 11, 12, 14 } }
|
||||
base.width = 24
|
||||
base.height = 8
|
||||
|
||||
local colourNum, exponents, colourChar = {}, {}, {}
|
||||
for i = 0, 15 do
|
||||
exponents[2 ^ i] = i
|
||||
end
|
||||
do
|
||||
local hex = "0123456789abcdef"
|
||||
for i = 1, 16 do
|
||||
colourNum[hex:sub(i, i)] = i - 1
|
||||
colourNum[i - 1] = hex:sub(i, i)
|
||||
colourChar[hex:sub(i, i)] = 2 ^ (i - 1)
|
||||
colourChar[2 ^ (i - 1)] = hex:sub(i, i)
|
||||
|
||||
local thisRel = relations[i - 1]
|
||||
for i = 1, #thisRel do
|
||||
thisRel[i] = 2 ^ thisRel[i]
|
||||
local function getPalette(id)
|
||||
if(originalImage~=nil)then
|
||||
local p = {}
|
||||
for k,v in pairs(colors)do
|
||||
if(type(v)=="number")then
|
||||
p[k] = {term.nativePaletteColor(v)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function getBestColourMatch(usage)
|
||||
local lastCol = relations[exponents[usage[#usage][1]]]
|
||||
|
||||
for j = 1, #lastCol do
|
||||
local thisRelation = lastCol[j]
|
||||
for i = 1, #usage - 1 do
|
||||
if usage[i][1] == thisRelation then
|
||||
return i
|
||||
end
|
||||
if(originalImage.palette~=nil)then
|
||||
for k,v in pairs(originalImage.palette)do
|
||||
p[k] = tonumber(v)
|
||||
end
|
||||
end
|
||||
|
||||
return 1
|
||||
end
|
||||
|
||||
local function colsToChar(pattern, totals)
|
||||
if not totals then
|
||||
local newPattern = {}
|
||||
totals = {}
|
||||
for i = 1, 6 do
|
||||
local thisVal = pattern[i]
|
||||
local thisTot = totals[thisVal]
|
||||
totals[thisVal], newPattern[i] = thisTot and (thisTot + 1) or 1, thisVal
|
||||
if(originalImage[id]~=nil)and(originalImage[id].palette~=nil)then
|
||||
for k,v in pairs(originalImage[id].palette)do
|
||||
p[k] = tonumber(v)
|
||||
end
|
||||
pattern = newPattern
|
||||
end
|
||||
|
||||
local usage = {}
|
||||
for key, value in pairs(totals) do
|
||||
usage[#usage + 1] = { key, value }
|
||||
end
|
||||
|
||||
if #usage > 1 then
|
||||
-- Reduce the chunk to two colours:
|
||||
while #usage > 2 do
|
||||
table.sort(usage, function(a, b)
|
||||
return a[2] > b[2]
|
||||
end)
|
||||
local matchToInd, usageLen = getBestColourMatch(usage), #usage
|
||||
local matchFrom, matchTo = usage[usageLen][1], usage[matchToInd][1]
|
||||
for i = 1, 6 do
|
||||
if pattern[i] == matchFrom then
|
||||
pattern[i] = matchTo
|
||||
usage[matchToInd][2] = usage[matchToInd][2] + 1
|
||||
end
|
||||
end
|
||||
usage[usageLen] = nil
|
||||
end
|
||||
|
||||
-- Convert to character. Adapted from oli414's function:
|
||||
-- http://www.computercraft.info/forums2/index.php?/topic/25340-cc-176-easy-drawing-characters/
|
||||
local data = 128
|
||||
for i = 1, #pattern - 1 do
|
||||
if pattern[i] ~= pattern[6] then
|
||||
data = data + 2 ^ (i - 1)
|
||||
end
|
||||
end
|
||||
return string.char(data), colourChar[usage[1][1] == pattern[6] and usage[2][1] or usage[1][1]], colourChar[pattern[6]]
|
||||
else
|
||||
-- Solid colour character:
|
||||
return "\128", colourChar[pattern[1]], colourChar[pattern[1]]
|
||||
end
|
||||
return p
|
||||
end
|
||||
|
||||
local results, width, height, bgCol = { {}, {}, {} }, 0, #image + #image % 3, base.bgColor or colors.black
|
||||
for i = 1, #image do
|
||||
if #image[i] > width then
|
||||
width = #image[i]
|
||||
end
|
||||
end
|
||||
|
||||
for y = 0, height - 1, 3 do
|
||||
local cRow, tRow, bRow, counter = {}, {}, {}, 1
|
||||
|
||||
for x = 0, width - 1, 2 do
|
||||
-- Grab a 2x3 chunk:
|
||||
local pattern, totals = {}, {}
|
||||
|
||||
for yy = 1, 3 do
|
||||
for xx = 1, 2 do
|
||||
pattern[#pattern + 1] = (image[y + yy] and image[y + yy][x + xx]) and (image[y + yy][x + xx] == 0 and bgCol or image[y + yy][x + xx]) or bgCol
|
||||
totals[pattern[#pattern]] = totals[pattern[#pattern]] and (totals[pattern[#pattern]] + 1) or 1
|
||||
end
|
||||
end
|
||||
|
||||
cRow[counter], tRow[counter], bRow[counter] = colsToChar(pattern, totals)
|
||||
counter = counter + 1
|
||||
end
|
||||
|
||||
results[1][#results[1] + 1], results[2][#results[2] + 1], results[3][#results[3] + 1] = table.concat(cRow), table.concat(tRow), table.concat(bRow)
|
||||
end
|
||||
|
||||
results.width, results.height = #results[1][1], #results[1]
|
||||
|
||||
shrinkedImage = results
|
||||
end
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
self.bgColor = self.parent:getTheme("ImageBG")
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ImageBG")
|
||||
end
|
||||
end,
|
||||
getType = function(self)
|
||||
return objectType
|
||||
end;
|
||||
|
||||
loadImage = function(self, path)
|
||||
image = paintutils.loadImage(path)
|
||||
imageGotShrinked = false
|
||||
loadImage = function(self, path, f)
|
||||
if not(fs.exists(path))then error("No valid path: "..path) end
|
||||
originalImage = images.loadImageAsBimg(path, f)
|
||||
curFrame = 1
|
||||
image = originalImage
|
||||
if(animTimer~=nil)then
|
||||
os.cancelTimer(animTimer)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
|
||||
shrink = function(self)
|
||||
shrink()
|
||||
imageGotShrinked = true
|
||||
setImage = function(self, data)
|
||||
originalImage = data
|
||||
image = originalImage
|
||||
curFrame = 1
|
||||
if(animTimer~=nil)then
|
||||
os.cancelTimer(animTimer)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
end,
|
||||
|
||||
usePalette = function(self, use)
|
||||
usePalette = use~=nil and use or true
|
||||
return self
|
||||
end,
|
||||
|
||||
play = function(self, inf)
|
||||
if(originalImage.animated)then
|
||||
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
|
||||
self.parent:addEvent("other_event", self)
|
||||
animTimer = os.startTimer(t)
|
||||
infinitePlay = inf or false
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
selectFrame = function(self, fr)
|
||||
if(originalImage[fr]~=nil)then
|
||||
curFrame = fr
|
||||
if(animTimer~=nil)then
|
||||
os.cancelTimer(animTimer)
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, timerId, ...)
|
||||
base.eventHandler(self, event, timerId, ...)
|
||||
if(event=="timer")then
|
||||
if(timerId==animTimer)then
|
||||
if(originalImage[curFrame+1]~=nil)then
|
||||
curFrame = curFrame + 1
|
||||
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
|
||||
animTimer = os.startTimer(t)
|
||||
else
|
||||
if(infinitePlay)then
|
||||
curFrame = 1
|
||||
local t = originalImage[curFrame].duration or originalImage.secondsPerFrame or 0.2
|
||||
animTimer = os.startTimer(t)
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
getMetadata = function(self, key)
|
||||
return originalImage[key]
|
||||
end,
|
||||
|
||||
getImageSize = function(self)
|
||||
return originalImage.width, originalImage.height
|
||||
end,
|
||||
|
||||
resizeImage = function(self, w, h)
|
||||
image = images.resizeBIMG(originalImage, w, h)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end,
|
||||
|
||||
setValuesByXMLData = function(self, data)
|
||||
base.setValuesByXMLData(self, data)
|
||||
if(xmlValue("shrink", data)~=nil)then if(xmlValue("shrink", data))then self:shrink() end end
|
||||
if(xmlValue("path", data)~=nil)then self:loadImage(xmlValue("path", data)) end
|
||||
return self
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
if (image ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
if (imageGotShrinked) then
|
||||
-- this is copy pasted (and slightly changed) from blittle by Bomb Bloke: http://www.computercraft.info/forums2/index.php?/topic/25354-cc-176-blittle-api/
|
||||
local t, tC, bC = shrinkedImage[1], shrinkedImage[2], shrinkedImage[3]
|
||||
for i = 1, shrinkedImage.height do
|
||||
local tI = t[i]
|
||||
if type(tI) == "string" then
|
||||
self.parent:setText(obx, oby + i - 1, tI)
|
||||
self.parent:setFG(obx, oby + i - 1, tC[i])
|
||||
self.parent:setBG(obx, oby + i - 1, bC[i])
|
||||
elseif type(tI) == "table" then
|
||||
self.parent:setText(obx, oby + i - 1, tI[2])
|
||||
self.parent:setFG(obx, oby + i - 1, tC[i])
|
||||
self.parent:setBG(obx, oby + i - 1, bC[i])
|
||||
end
|
||||
end
|
||||
else
|
||||
for yPos = 1, math.min(#image, h) do
|
||||
local line = image[yPos]
|
||||
for xPos = 1, math.min(#line, w) do
|
||||
if line[xPos] > 0 then
|
||||
self.parent:drawBackgroundBox(obx + xPos - 1, oby + yPos - 1, 1, 1, line[xPos])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if (image ~= nil) then
|
||||
if(usePalette)then
|
||||
self:getBaseFrame():setThemeColor(getPalette(curFrame))
|
||||
end
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local w,h = self:getSize()
|
||||
for y,v in ipairs(image[curFrame])do
|
||||
local t, f, b = unpack(v)
|
||||
t = sub(t, 1,w)
|
||||
f = sub(f, 1,w)
|
||||
b = sub(b, 1,w)
|
||||
self.parent:blit(obx, oby+y-1, t, f, b)
|
||||
if(y==h)then break end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -57,9 +57,9 @@ return function(name)
|
||||
setValue = function(self, val)
|
||||
base.setValue(self, tostring(val))
|
||||
if not (internalValueChange) then
|
||||
textX = tostring(val):len() + 1
|
||||
wIndex = math.max(1, textX-self:getWidth()+1)
|
||||
if(self:isFocused())then
|
||||
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:getHeight()/2), self.fgColor)
|
||||
end
|
||||
@@ -202,12 +202,15 @@ return function(name)
|
||||
if (text:len() < inputLimit or inputLimit <= 0) then
|
||||
if (inputType == "number") then
|
||||
local cache = text
|
||||
if (char == ".") or (tonumber(char) ~= nil) then
|
||||
if (textX==1 and char == "-") or (char == ".") or (tonumber(char) ~= nil) then
|
||||
self:setValue(text:sub(1, textX - 1) .. char .. text:sub(textX, text:len()))
|
||||
textX = textX + 1
|
||||
end
|
||||
if (tonumber(base.getValue()) == nil) then
|
||||
self:setValue(cache)
|
||||
if(char==".")or(char=="-")and(#text>0)then
|
||||
if (tonumber(base.getValue()) == nil) then
|
||||
self:setValue(cache)
|
||||
textX = textX - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
self:setValue(text:sub(1, textX - 1) .. char .. text:sub(textX, text:len()))
|
||||
@@ -267,44 +270,43 @@ return function(name)
|
||||
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
|
||||
eventHandler = function(self, event, paste, ...)
|
||||
base.eventHandler(self, event, paste, ...)
|
||||
if(event=="paste")then
|
||||
if(self:isFocused())then
|
||||
local text = base.getValue()
|
||||
local w, h = self:getSize()
|
||||
internalValueChange = true
|
||||
if (inputType == "number") then
|
||||
local cache = text
|
||||
if (paste == ".") or (tonumber(paste) ~= nil) then
|
||||
self:setValue(text:sub(1, textX - 1) .. paste .. text:sub(textX, text:len()))
|
||||
textX = textX + paste:len()
|
||||
end
|
||||
if (textX >= w + wIndex) then
|
||||
wIndex = (textX+1)-w
|
||||
if (tonumber(base.getValue()) == nil) then
|
||||
self:setValue(cache)
|
||||
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
|
||||
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,
|
||||
@@ -353,8 +355,6 @@ return function(name)
|
||||
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)
|
||||
@@ -362,6 +362,10 @@ return function(name)
|
||||
self.parent:addEvent("other_event", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
end
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("InputBG")
|
||||
self.fgColor = self.parent:getTheme("InputText")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,13 @@ return function(name)
|
||||
text = tostring(text)
|
||||
base:setValue(text)
|
||||
if (autoSize) then
|
||||
self.width = text:len()
|
||||
local xOffset = self.parent:getOffset()
|
||||
if(text:len()+self:getX()>self.parent:getWidth()+xOffset)then
|
||||
local newW = self.parent:getWidth()+xOffset - self:getX()
|
||||
base.setSize(self, newW, #createText(text, newW))
|
||||
else
|
||||
base.setSize(self, text:len(), 1)
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
@@ -86,6 +92,22 @@ return function(name)
|
||||
return self
|
||||
end;
|
||||
|
||||
eventHandler = function(self, event)
|
||||
if(event=="basalt_resize")then
|
||||
if (autoSize) then
|
||||
local text = self:getValue()
|
||||
if(text:len()+self:getX()>self.parent:getWidth())then
|
||||
local newW = self.parent:getWidth() - self:getX()
|
||||
base.setSize(self, newW, #createText(text, newW))
|
||||
else
|
||||
base.setSize(self, text:len(), 1)
|
||||
end
|
||||
else
|
||||
--self.parent:removeEvent("other_event", self)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
draw = function(self)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
@@ -96,10 +118,21 @@ return function(name)
|
||||
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)
|
||||
if(k<=h)then
|
||||
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
|
||||
end
|
||||
end
|
||||
else
|
||||
self.parent:writeText(obx, oby, self:getValue(), self.bgColor, self.fgColor)
|
||||
if(#self:getValue()+obx>self.parent:getWidth())then
|
||||
local text = createText(self:getValue(), self:getWidth())
|
||||
for k,v in pairs(text)do
|
||||
if(k<=h)then
|
||||
self.parent:writeText(obx, oby+k-1, v, self.bgColor, self.fgColor)
|
||||
end
|
||||
end
|
||||
else
|
||||
self.parent:writeText(obx, oby, self:getValue(), self.bgColor, self.fgColor)
|
||||
end
|
||||
end
|
||||
else
|
||||
local tData = bigFont(fontsize, self:getValue(), self.fgColor, self.bgColor or colors.lightGray)
|
||||
@@ -112,15 +145,16 @@ return function(name)
|
||||
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])
|
||||
self.parent:setFG(obx, oby + i - 1, tData[2][i])
|
||||
self.parent:setBG(obx, oby + i - 1, tData[3][i])
|
||||
self.parent:setText(obx, oby + i - 1, tData[1][i])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
init = function(self)
|
||||
self.parent:addEvent("other_event", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("LabelBG")
|
||||
self.fgColor = self.parent:getTheme("LabelText")
|
||||
|
||||
@@ -24,8 +24,8 @@ return function(name)
|
||||
|
||||
addItem = function(self, text, bgCol, fgCol, ...)
|
||||
table.insert(list, { text = text, bgCol = bgCol or self.bgColor, fgCol = fgCol or self.fgColor, args = { ... } })
|
||||
if (#list == 1) then
|
||||
self:setValue(list[1])
|
||||
if (#list <= 1) then
|
||||
self:setValue(list[1], false)
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
@@ -66,7 +66,7 @@ return function(name)
|
||||
|
||||
clear = function(self)
|
||||
list = {}
|
||||
self:setValue({})
|
||||
self:setValue({}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -83,7 +83,7 @@ return function(name)
|
||||
end;
|
||||
|
||||
selectItem = function(self, index)
|
||||
self:setValue(list[index] or {})
|
||||
self:setValue(list[index] or {}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -199,13 +199,15 @@ return function(name)
|
||||
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)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ListBG")
|
||||
self.fgColor = self.parent:getTheme("ListText")
|
||||
itemSelectedBG = self.parent:getTheme("SelectionBG")
|
||||
itemSelectedFG = self.parent:getTheme("SelectionText")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ return function(name)
|
||||
|
||||
clear = function(self)
|
||||
list = {}
|
||||
self:setValue({})
|
||||
self:setValue({}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -142,7 +142,7 @@ return function(name)
|
||||
end;
|
||||
|
||||
selectItem = function(self, index)
|
||||
self:setValue(list[index] or {})
|
||||
self:setValue(list[index] or {}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -226,14 +226,14 @@ return function(name)
|
||||
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)
|
||||
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("MenubarBG")
|
||||
self.fgColor = self.parent:getTheme("MenubarText")
|
||||
itemSelectedBG = self.parent:getTheme("SelectionBG")
|
||||
itemSelectedFG = self.parent:getTheme("SelectionText")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ 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
|
||||
|
||||
@@ -12,6 +11,7 @@ return function(name, parent)
|
||||
base:setZIndex(5)
|
||||
local object
|
||||
local cachedPath
|
||||
local enviroment = {}
|
||||
|
||||
local function createBasaltWindow(x, y, width, height, self)
|
||||
local xCursor, yCursor = 1, 1
|
||||
@@ -428,7 +428,21 @@ return function(name, parent)
|
||||
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())
|
||||
self.parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
|
||||
local function resumeProcess(self, event, ...)
|
||||
local ok, result = curProcess:resume(event, ...)
|
||||
if (ok==false)and(result~=nil)and(result~="Terminated")then
|
||||
local val = self:sendEvent("program_error", result)
|
||||
if(val~=false)then
|
||||
error("Basalt Program - "..result)
|
||||
end
|
||||
end
|
||||
|
||||
if(curProcess:getStatus()=="dead")then
|
||||
self:sendEvent("program_done")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -439,7 +453,7 @@ return function(name, parent)
|
||||
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)
|
||||
resumeProcess(self, event, p1, x-absX+1, y-absY+1)
|
||||
updateCursor(self)
|
||||
end
|
||||
end
|
||||
@@ -452,7 +466,7 @@ return function(name, parent)
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
if (self.draw) then
|
||||
curProcess:resume(event, key, isHolding)
|
||||
resumeProcess(self, event, key, isHolding)
|
||||
updateCursor(self)
|
||||
end
|
||||
end
|
||||
@@ -511,9 +525,14 @@ return function(name, parent)
|
||||
return "inactive"
|
||||
end;
|
||||
|
||||
setEnviroment = function(self, env)
|
||||
enviroment = env or {}
|
||||
return self
|
||||
end,
|
||||
|
||||
execute = function(self, path, ...)
|
||||
cachedPath = path or cachedPath
|
||||
curProcess = process:new(cachedPath, pWindow, ...)
|
||||
curProcess = process:new(cachedPath, pWindow, enviroment, ...)
|
||||
pWindow.setBackgroundColor(colors.black)
|
||||
pWindow.setTextColor(colors.white)
|
||||
pWindow.clear()
|
||||
@@ -521,7 +540,8 @@ return function(name, parent)
|
||||
pWindow.setBackgroundColor(self.bgColor)
|
||||
pWindow.setTextColor(self.fgColor)
|
||||
pWindow.basalt_setVisible(true)
|
||||
curProcess:resume()
|
||||
|
||||
resumeProcess(self)
|
||||
paused = false
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
@@ -539,7 +559,7 @@ return function(name, parent)
|
||||
stop = function(self)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
curProcess:resume("terminate")
|
||||
resumeProcess(self, "terminate")
|
||||
if (curProcess:isDead()) then
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(false)
|
||||
@@ -572,7 +592,7 @@ return function(name, parent)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
if (paused == false) or (ign) then
|
||||
curProcess:resume(event, p1, p2, p3, p4)
|
||||
resumeProcess(self, event, p1, p2, p3, p4)
|
||||
else
|
||||
table.insert(queuedEvent, { event = event, args = { p1, p2, p3, p4 } })
|
||||
end
|
||||
@@ -594,7 +614,7 @@ return function(name, parent)
|
||||
if (curProcess ~= nil) then
|
||||
if not (curProcess:isDead()) then
|
||||
for _, value in pairs(events) do
|
||||
curProcess:resume(value.event, table.unpack(value.args))
|
||||
resumeProcess(self, value.event, table.unpack(value.args))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -665,11 +685,9 @@ return function(name, parent)
|
||||
if (self.parent ~= nil) then
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
if (self.parent ~= nil) then
|
||||
local w,h = self:getSize()
|
||||
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
|
||||
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
local w,h = self:getSize()
|
||||
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
|
||||
self.parent:setCursor(pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -699,7 +717,7 @@ return function(name, parent)
|
||||
if(w~=pW)or(h~=pH)then
|
||||
pWindow.basalt_resize(pW, pH)
|
||||
if not (curProcess:isDead()) then
|
||||
curProcess:resume("term_resize")
|
||||
resumeProcess(self, "term_resize")
|
||||
end
|
||||
end
|
||||
pWindow.basalt_reposition(self:getAnchorPosition())
|
||||
@@ -708,7 +726,7 @@ return function(name, parent)
|
||||
if not (curProcess:isDead()) then
|
||||
if not (paused) then
|
||||
if(event ~= "terminate") then
|
||||
curProcess:resume(event, p1, p2, p3, p4)
|
||||
resumeProcess(self, event, p1, p2, p3, p4)
|
||||
end
|
||||
if (self:isFocused()) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
@@ -721,8 +739,7 @@ return function(name, parent)
|
||||
end
|
||||
|
||||
if (event == "terminate") then
|
||||
log(self:isFocused())
|
||||
curProcess:resume(event)
|
||||
resumeProcess(self, event)
|
||||
self.parent:setCursor(false)
|
||||
return true
|
||||
end
|
||||
@@ -739,15 +756,45 @@ return function(name, parent)
|
||||
if (base.draw(self)) then
|
||||
if (self.parent ~= nil) then
|
||||
local obx, oby = self:getAnchorPosition()
|
||||
local xCur, yCur = pWindow.getCursorPos()
|
||||
local w,h = self:getSize()
|
||||
pWindow.basalt_reposition(obx, oby)
|
||||
pWindow.basalt_update()
|
||||
if (obx + xCur - 1 >= 1 and obx + xCur - 1 <= obx + w - 1 and yCur + oby - 1 >= 1 and yCur + oby - 1 <= oby + h - 1) then
|
||||
self.parent:setCursor(self:isFocused() and pWindow.getCursorBlink(), obx + xCur - 1, yCur + oby - 1, pWindow.getTextColor())
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
onError = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("program_error", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("other_event", self)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
onDone = function(self, ...)
|
||||
for _,v in pairs(table.pack(...))do
|
||||
if(type(v)=="function")then
|
||||
self:registerEvent("program_done", v)
|
||||
end
|
||||
end
|
||||
if(self.parent~=nil)then
|
||||
self.parent:addEvent("other_event", self)
|
||||
end
|
||||
return self
|
||||
end,
|
||||
|
||||
init = function(self)
|
||||
self.bgColor = self.parent:getTheme("ProgramBG")
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ProgramBG")
|
||||
end
|
||||
end,
|
||||
|
||||
}
|
||||
|
||||
@@ -21,9 +21,11 @@ return function(name)
|
||||
|
||||
local object = {
|
||||
init = function(self)
|
||||
self.bgColor = self.parent:getTheme("ProgressbarBG")
|
||||
self.fgColor = self.parent:getTheme("ProgressbarText")
|
||||
activeBarColor = self.parent:getTheme("ProgressbarActiveBG")
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ProgressbarBG")
|
||||
self.fgColor = self.parent:getTheme("ProgressbarText")
|
||||
activeBarColor = self.parent:getTheme("ProgressbarActiveBG")
|
||||
end
|
||||
end,
|
||||
getType = function(self)
|
||||
return objectType
|
||||
|
||||
@@ -77,7 +77,7 @@ return function(name)
|
||||
|
||||
clear = function(self)
|
||||
list = {}
|
||||
self:setValue({})
|
||||
self:setValue({}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -94,7 +94,7 @@ return function(name)
|
||||
end;
|
||||
|
||||
selectItem = function(self, index)
|
||||
self:setValue(list[index] or {})
|
||||
self:setValue(list[index] or {}, false)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -153,13 +153,15 @@ return function(name)
|
||||
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)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("MenubarBG")
|
||||
self.fgColor = self.parent:getTheme("MenubarFG")
|
||||
itemSelectedBG = self.parent:getTheme("SelectionBG")
|
||||
itemSelectedFG = self.parent:getTheme("SelectionText")
|
||||
boxSelectedBG = self.parent:getTheme("MenubarBG")
|
||||
boxSelectedFG = self.parent:getTheme("MenubarText")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -173,12 +173,14 @@ return function(name)
|
||||
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)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("ScrollbarBG")
|
||||
self.fgColor = self.parent:getTheme("ScrollbarText")
|
||||
symbolColor = self.parent:getTheme("ScrollbarSymbolColor")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -173,12 +173,14 @@ return function(name)
|
||||
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)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("SliderBG")
|
||||
self.fgColor = self.parent:getTheme("SliderText")
|
||||
symbolColor = self.parent:getTheme("SliderSymbolColor")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -74,12 +74,14 @@ return function(name)
|
||||
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)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("SwitchBG")
|
||||
self.fgColor = self.parent:getTheme("SwitchText")
|
||||
bgSymbol = self.parent:getTheme("SwitchBGSymbol")
|
||||
inactiveBG = self.parent:getTheme("SwitchInactive")
|
||||
activeBG = self.parent:getTheme("SwitchActive")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +1,101 @@
|
||||
local Object = require("Object")
|
||||
local tHex = require("tHex")
|
||||
local log = require("basaltLogs")
|
||||
local xmlValue = require("utils").getValueFromXML
|
||||
local log = require("basaltLogs")
|
||||
|
||||
local rep = string.rep
|
||||
local rep,find,gmatch,sub,len = string.rep,string.find,string.gmatch,string.sub,string.len
|
||||
|
||||
return function(name)
|
||||
local base = Object(name)
|
||||
local objectType = "Textfield"
|
||||
local hIndex, wIndex, textX, textY = 1, 1, 1, 1
|
||||
|
||||
local lines = { "" }
|
||||
local lines = { " " }
|
||||
local bgLines = { "" }
|
||||
local fgLines = { "" }
|
||||
local keyWords = { }
|
||||
local rules = { }
|
||||
|
||||
local startSelX,endSelX,startSelY,endSelY
|
||||
|
||||
local selectionBG,selectionFG = colors.lightBlue,colors.black
|
||||
|
||||
base.width = 30
|
||||
base.height = 12
|
||||
base:setZIndex(5)
|
||||
|
||||
local function isSelected()
|
||||
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function getSelectionCoordinates()
|
||||
local sx,ex,sy,ey
|
||||
if(isSelected())then
|
||||
if(startSelX>endSelX)then
|
||||
sx,ex = endSelX,startSelX
|
||||
else
|
||||
sx,ex = startSelX,endSelX
|
||||
end
|
||||
if(startSelY>endSelY)then
|
||||
sy,ey = endSelY,startSelY
|
||||
else
|
||||
sy,ey = startSelY,endSelY
|
||||
end
|
||||
end
|
||||
return sx,ex,sy,ey
|
||||
end
|
||||
|
||||
local function getSelection()
|
||||
|
||||
end
|
||||
|
||||
local function removeSelection(self)
|
||||
local sx,ex,sy,ey = getSelectionCoordinates(self)
|
||||
for n=ey,sy,-1 do
|
||||
if(n==sy)or(n==ey)then
|
||||
local l = lines[n]
|
||||
local b = bgLines[n]
|
||||
local f = fgLines[n]
|
||||
if(n==sy)and(n==ey)then
|
||||
l = l:sub(1,sx-1)..l:sub(ex+1,l:len())
|
||||
b = b:sub(1,sx-1)..b:sub(ex+1,b:len())
|
||||
f = f:sub(1,sx-1)..f:sub(ex+1,f:len())
|
||||
elseif(n==sx)then
|
||||
l = l:sub(1, sx)
|
||||
b = b:sub(1, sx)
|
||||
f = f:sub(1, sx)
|
||||
elseif(n==sy)then
|
||||
l = l:sub(ex, l:len())
|
||||
b = b:sub(ex, b:len())
|
||||
f = f:sub(ex, f:len())
|
||||
end
|
||||
lines[n] = l
|
||||
bgLines[n] = b
|
||||
fgLines[n] = f
|
||||
else
|
||||
table.remove(lines, n)
|
||||
table.remove(bgLines, n)
|
||||
table.remove(fgLines, n)
|
||||
end
|
||||
end
|
||||
textX,textY = startSelX,startSelY
|
||||
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
|
||||
return self
|
||||
end
|
||||
|
||||
local function stringGetPositions(str, word)
|
||||
local pos = {}
|
||||
if(str:len()>0)then
|
||||
for w in string.gmatch(str, word)do
|
||||
local s, e = string.find(str, w)
|
||||
for w in gmatch(str, word)do
|
||||
local s, e = find(str, w)
|
||||
if(s~=nil)and(e~=nil)then
|
||||
table.insert(pos,s)
|
||||
table.insert(pos,e)
|
||||
local startL = string.sub(str, 1, (s-1))
|
||||
local endL = string.sub(str, e+1, str:len())
|
||||
local startL = sub(str, 1, (s-1))
|
||||
local endL = sub(str, e+1, str:len())
|
||||
str = startL..(":"):rep(w:len())..endL
|
||||
end
|
||||
end
|
||||
@@ -144,14 +210,16 @@ return function(name)
|
||||
|
||||
editLine = function(self, index, text)
|
||||
lines[index] = text or lines[index]
|
||||
updateColors(self, index)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
|
||||
clear = function(self)
|
||||
lines = {""}
|
||||
lines = {" "}
|
||||
bgLines = {""}
|
||||
fgLines = {""}
|
||||
startSelX,endSelX,startSelY,endSelY = nil,nil,nil,nil
|
||||
hIndex, wIndex, textX, textY = 1, 1, 1, 1
|
||||
self:updateDraw()
|
||||
return self
|
||||
@@ -163,18 +231,20 @@ return function(name)
|
||||
lines[1] = text
|
||||
bgLines[1] = tHex[self.bgColor]:rep(text:len())
|
||||
fgLines[1] = tHex[self.fgColor]:rep(text:len())
|
||||
updateColors(self, 1)
|
||||
return self
|
||||
end
|
||||
if (index ~= nil) then
|
||||
table.insert(lines, index, text)
|
||||
table.insert(bgLines, index, tHex[self.bgColor]:rep(text:len()))
|
||||
table.insert(fgLines, tHex[self.fgColor]:rep(text:len()))
|
||||
table.insert(fgLines, index, tHex[self.fgColor]:rep(text:len()))
|
||||
else
|
||||
table.insert(lines, text)
|
||||
table.insert(bgLines, tHex[self.bgColor]:rep(text:len()))
|
||||
table.insert(fgLines, tHex[self.fgColor]:rep(text:len()))
|
||||
end
|
||||
end
|
||||
updateColors(self, index or #lines)
|
||||
self:updateDraw()
|
||||
return self
|
||||
end;
|
||||
@@ -224,9 +294,14 @@ return function(name)
|
||||
end;
|
||||
|
||||
removeLine = function(self, index)
|
||||
table.remove(lines, index or #lines)
|
||||
if (#lines <= 0) then
|
||||
table.insert(lines, "")
|
||||
if(#lines>1)then
|
||||
table.remove(lines, index or #lines)
|
||||
table.remove(bgLines, index or #bgLines)
|
||||
table.remove(fgLines, index or #fgLines)
|
||||
else
|
||||
lines = {" "}
|
||||
bgLines = {""}
|
||||
fgLines = {""}
|
||||
end
|
||||
self:updateDraw()
|
||||
return self
|
||||
@@ -308,17 +383,21 @@ return function(name)
|
||||
|
||||
if (key == keys.delete) then
|
||||
-- on delete
|
||||
if (textX > lines[textY]:len()) then
|
||||
if (lines[textY + 1] ~= nil) then
|
||||
lines[textY] = lines[textY] .. lines[textY + 1]
|
||||
table.remove(lines, textY + 1)
|
||||
table.remove(bgLines, textY + 1)
|
||||
table.remove(fgLines, textY + 1)
|
||||
end
|
||||
if(isSelected())then
|
||||
removeSelection(self)
|
||||
else
|
||||
lines[textY] = lines[textY]:sub(1, textX - 1) .. lines[textY]:sub(textX + 1, lines[textY]:len())
|
||||
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. fgLines[textY]:sub(textX + 1, fgLines[textY]:len())
|
||||
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. bgLines[textY]:sub(textX + 1, bgLines[textY]:len())
|
||||
if (textX > lines[textY]:len()) then
|
||||
if (lines[textY + 1] ~= nil) then
|
||||
lines[textY] = lines[textY] .. lines[textY + 1]
|
||||
table.remove(lines, textY + 1)
|
||||
table.remove(bgLines, textY + 1)
|
||||
table.remove(fgLines, textY + 1)
|
||||
end
|
||||
else
|
||||
lines[textY] = lines[textY]:sub(1, textX - 1) .. lines[textY]:sub(textX + 1, lines[textY]:len())
|
||||
fgLines[textY] = fgLines[textY]:sub(1, textX - 1) .. fgLines[textY]:sub(textX + 1, fgLines[textY]:len())
|
||||
bgLines[textY] = bgLines[textY]:sub(1, textX - 1) .. bgLines[textY]:sub(textX + 1, bgLines[textY]:len())
|
||||
end
|
||||
end
|
||||
updateColors(self)
|
||||
end
|
||||
@@ -427,9 +506,14 @@ return function(name)
|
||||
end
|
||||
end
|
||||
|
||||
if not((obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h)) then
|
||||
wIndex = math.max(1, lines[textY]:len()-w+1)
|
||||
hIndex = math.max(1, textY - h + 1)
|
||||
end
|
||||
|
||||
local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1)
|
||||
if (cursorX > self.x + w - 1) then
|
||||
cursorX = self.x + w - 1
|
||||
if (cursorX > self:getX() + w - 1) then
|
||||
cursorX = self:getX() + w - 1
|
||||
end
|
||||
local cursorY = (textY - hIndex < h and textY - hIndex or textY - hIndex - 1)
|
||||
if (cursorX < 1) then
|
||||
@@ -455,14 +539,22 @@ return function(name)
|
||||
updateColors(self)
|
||||
self:setValue("")
|
||||
|
||||
if not((obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (oby + textY - hIndex >= oby and oby + textY - hIndex < oby + h)) then
|
||||
wIndex = math.max(1, lines[textY]:len()-w+1)
|
||||
hIndex = math.max(1, textY - h + 1)
|
||||
end
|
||||
|
||||
local cursorX = (textX <= lines[textY]:len() and textX - 1 or lines[textY]:len()) - (wIndex - 1)
|
||||
if (cursorX > self.x + w - 1) then
|
||||
cursorX = self.x + w - 1
|
||||
if (cursorX > self:getX() + w - 1) then
|
||||
cursorX = self:getX() + w - 1
|
||||
end
|
||||
local cursorY = (textY - hIndex < h and textY - hIndex or textY - hIndex - 1)
|
||||
if (cursorX < 1) then
|
||||
cursorX = 0
|
||||
end
|
||||
if(isSelected())then
|
||||
removeSelection(self)
|
||||
end
|
||||
self.parent:setCursor(true, obx + cursorX, oby + cursorY, self.fgColor)
|
||||
self:updateDraw()
|
||||
return true
|
||||
@@ -478,18 +570,21 @@ return function(name)
|
||||
if(anchx+w > anchx + x - (obx+1)+ wIndex)and(anchx < anchx + x - obx+ wIndex)then
|
||||
textX = x - obx + wIndex
|
||||
textY = y - oby + hIndex
|
||||
endSelX = textX
|
||||
endSelY = textY
|
||||
if (textX > lines[textY]:len()) then
|
||||
textX = lines[textY]:len() + 1
|
||||
endSelX = textX
|
||||
end
|
||||
|
||||
if (textX < wIndex) then
|
||||
wIndex = textX - 1
|
||||
if (wIndex < 1) then
|
||||
wIndex = 1
|
||||
end
|
||||
end
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
end
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
|
||||
self:updateDraw()
|
||||
end
|
||||
end
|
||||
@@ -511,12 +606,10 @@ return function(name)
|
||||
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
|
||||
if (obx + textX - wIndex >= obx and obx + textX - wIndex < obx + w) and (anchy + textY - hIndex >= anchy and anchy + textY - hIndex < anchy + h) then
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
else
|
||||
self.parent:setCursor(false)
|
||||
end
|
||||
self:updateDraw()
|
||||
return true
|
||||
@@ -530,8 +623,13 @@ return function(name)
|
||||
if (lines[y - oby + hIndex] ~= nil) then
|
||||
textX = x - obx + wIndex
|
||||
textY = y - oby + hIndex
|
||||
endSelX = nil
|
||||
endSelY = nil
|
||||
startSelX = textX
|
||||
startSelY = textY
|
||||
if (textX > lines[textY]:len()) then
|
||||
textX = lines[textY]:len() + 1
|
||||
startSelX = textX
|
||||
end
|
||||
if (textX < wIndex) then
|
||||
wIndex = textX - 1
|
||||
@@ -539,6 +637,7 @@ return function(name)
|
||||
wIndex = 1
|
||||
end
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
if (self.parent ~= nil) then
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
@@ -547,6 +646,25 @@ return function(name)
|
||||
end
|
||||
end,
|
||||
|
||||
mouseUpHandler = function(self, button, x, y)
|
||||
if (base.mouseUpHandler(self, button, x, y)) then
|
||||
local obx, oby = self:getAbsolutePosition(self:getAnchorPosition())
|
||||
local anchx, anchy = self:getAnchorPosition()
|
||||
if (lines[y - oby + hIndex] ~= nil) then
|
||||
endSelX = x - obx + wIndex
|
||||
endSelY = y - oby + hIndex
|
||||
if (endSelX > lines[endSelY]:len()) then
|
||||
endSelX = lines[endSelY]:len() + 1
|
||||
end
|
||||
if(startSelX==endSelX)and(startSelY==endSelY)then
|
||||
startSelX, endSelX, startSelY, endSelY = nil, nil, nil, nil
|
||||
end
|
||||
self:updateDraw()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, paste, p2, p3, p4)
|
||||
if(base.eventHandler(self, event, paste, p2, p3, p4))then
|
||||
if(event=="paste")then
|
||||
@@ -596,23 +714,44 @@ return function(name)
|
||||
self.parent:setBG(obx, oby + n - 1, bg)
|
||||
self.parent:setFG(obx, oby + n - 1, fg)
|
||||
end
|
||||
if(startSelX~=nil)and(endSelX~=nil)and(startSelY~=nil)and(endSelY~=nil)then
|
||||
local sx,ex,sy,ey = getSelectionCoordinates(self)
|
||||
for n=sy,ey do
|
||||
local line = lines[n]:len()
|
||||
local xOffset = 0
|
||||
if(n==sy)and(n==ey)then
|
||||
xOffset = sx-1
|
||||
line = line - (sx-1) - (line - ex)
|
||||
elseif(n==ey)then
|
||||
line = line - (line - ex)
|
||||
elseif(n==sy)then
|
||||
line = line-(sx-1)
|
||||
xOffset = sx-1
|
||||
end
|
||||
self.parent:setBG(obx + xOffset, oby + n - 1, rep(tHex[selectionBG], line))
|
||||
self.parent:setFG(obx + xOffset, oby + n - 1, rep(tHex[selectionFG], line))
|
||||
end
|
||||
end
|
||||
if(self:isFocused())then
|
||||
local anchx, anchy = self:getAnchorPosition()
|
||||
self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor)
|
||||
--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_up", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
self.parent:addEvent("key", self)
|
||||
self.parent:addEvent("char", self)
|
||||
self.parent:addEvent("other_event", self)
|
||||
if(base.init(self))then
|
||||
self.bgColor = self.parent:getTheme("TextfieldBG")
|
||||
self.fgColor = self.parent:getTheme("TextfieldText")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ return function(name)
|
||||
local func
|
||||
local cRoutine
|
||||
local isActive = false
|
||||
local filter
|
||||
|
||||
local generateXMLEventFunction = function(self, str)
|
||||
if(str:sub(1,1)=="#")then
|
||||
@@ -53,12 +54,21 @@ return function(name)
|
||||
func = f
|
||||
cRoutine = coroutine.create(func)
|
||||
isActive = true
|
||||
filter=nil
|
||||
local ok, result = coroutine.resume(cRoutine)
|
||||
filter = result
|
||||
if not (ok) then
|
||||
if (result ~= "Terminated") then
|
||||
error("Thread Error Occurred - " .. result)
|
||||
end
|
||||
end
|
||||
self.parent:addEvent("mouse_click", self)
|
||||
self.parent:addEvent("mouse_up", self)
|
||||
self.parent:addEvent("mouse_scroll", self)
|
||||
self.parent:addEvent("mouse_drag", self)
|
||||
self.parent:addEvent("key", self)
|
||||
self.parent:addEvent("key_up", self)
|
||||
self.parent:addEvent("char", self)
|
||||
self.parent:addEvent("other_event", self)
|
||||
return self
|
||||
end;
|
||||
@@ -72,21 +82,58 @@ return function(name)
|
||||
|
||||
stop = function(self, f)
|
||||
isActive = false
|
||||
self.parent:removeEvent("mouse_click", self)
|
||||
self.parent:removeEvent("mouse_up", self)
|
||||
self.parent:removeEvent("mouse_scroll", self)
|
||||
self.parent:removeEvent("mouse_drag", self)
|
||||
self.parent:removeEvent("key", self)
|
||||
self.parent:removeEvent("key_up", self)
|
||||
self.parent:removeEvent("char", self)
|
||||
self.parent:removeEvent("other_event", self)
|
||||
return self
|
||||
end;
|
||||
|
||||
eventHandler = function(self, event, p1, p2, p3)
|
||||
mouseHandler = function(self, ...)
|
||||
self:eventHandler("mouse_click", ...)
|
||||
end,
|
||||
mouseUpHandler = function(self, ...)
|
||||
self:eventHandler("mouse_up", ...)
|
||||
end,
|
||||
mouseScrollHandler = function(self, ...)
|
||||
self:eventHandler("mouse_scroll", ...)
|
||||
end,
|
||||
mouseDragHandler = function(self, ...)
|
||||
self:eventHandler("mouse_drag", ...)
|
||||
end,
|
||||
mouseMoveHandler = function(self, ...)
|
||||
self:eventHandler("mouse_move", ...)
|
||||
end,
|
||||
keyHandler = function(self, ...)
|
||||
self:eventHandler("key", ...)
|
||||
end,
|
||||
keyUpHandler = function(self, ...)
|
||||
self:eventHandler("key_up", ...)
|
||||
end,
|
||||
charHandler = function(self, ...)
|
||||
self:eventHandler("char", ...)
|
||||
end,
|
||||
|
||||
eventHandler = function(self, event, ...)
|
||||
if (isActive) then
|
||||
if (coroutine.status(cRoutine) ~= "dead") then
|
||||
local ok, result = coroutine.resume(cRoutine, event, p1, p2, p3)
|
||||
if (coroutine.status(cRoutine) == "suspended") then
|
||||
if(filter~=nil)then
|
||||
if(event~=filter)then return end
|
||||
filter=nil
|
||||
end
|
||||
local ok, result = coroutine.resume(cRoutine, event, ...)
|
||||
filter = result
|
||||
if not (ok) then
|
||||
if (result ~= "Terminated") then
|
||||
error("Thread Error Occurred - " .. result)
|
||||
end
|
||||
end
|
||||
else
|
||||
isActive = false
|
||||
self:stop()
|
||||
end
|
||||
end
|
||||
end;
|
||||
|
||||
@@ -40,6 +40,8 @@ return { -- The default main theme for basalt!
|
||||
SwitchInactive = colors.red,
|
||||
SwitchActive = colors.green,
|
||||
LabelBG = false,
|
||||
LabelText = colors.black
|
||||
LabelText = colors.black,
|
||||
GraphBG = colors.gray,
|
||||
GraphText = colors.black
|
||||
|
||||
}
|
||||
19
docs/Home.md
19
docs/Home.md
@@ -1,24 +1,19 @@
|
||||
# Welcome to The Basalt Wiki!
|
||||
# Welcome to The Basalt Wiki
|
||||
|
||||
*Note: The Basalt Wiki is a work in progress. Please treat Wiki errors the same as bugs and report them accordingly.*
|
||||
*Note: The Basalt Wiki is a work in progress. Please treat wiki errors the same as bugs and report them accordingly.*
|
||||
|
||||
Here you can find information about how to use Basalt as well as examples of functional Basalt code. The aim of Basalt is to improve user interaction through visual display.
|
||||
|
||||
## About Basalt
|
||||
|
||||
Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (Also know as "ComputerCraft: Tweaked") - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's [wiki](https://tweaked.cc/) or [download](https://www.curseforge.com/minecraft/mc-mods/cc-tweaked).
|
||||
Basalt is intended to be an easy-to-understand UI Framework designed for CC:Tweaked (Also known as "ComputerCraft: Tweaked") - a popular minecraft mod. For more information about CC:Tweaked, checkout the project's [wiki](https://tweaked.cc/) or [download](https://modrinth.com/mod/cc-tweaked).
|
||||
|
||||
## Quick Demo
|
||||
<img src="https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/_media/basaltPreview2.gif" width="600">
|
||||
|
||||

|
||||
|
||||
## Questions & Bugs
|
||||
|
||||
Obviously NyoriE has implemented some easter eggs, *some people* call them "bugs". If you happen to discover one of these just make a new <a href="https://github.com/Pyroxenium/Basalt/issues">issue</a>.
|
||||
Obviously NyoriE has implemented some easter eggs, *some people* call them "bugs". If you happen to discover one of these just make a new [Github Issue](https://github.com/Pyroxenium/Basalt/issues)
|
||||
|
||||
Additionally, if you have questions about Basalt or how to make use of it, feel free to create a new discussion on <a href="https://github.com/Pyroxenium/Basalt/discussions">Basalt's Discussion Board</a>, or ask in our [discord](https://discord.gg/yNNnmBVBpE).
|
||||
|
||||
---
|
||||
|
||||
Feel free to join our [discord](https://discord.gg/yNNnmBVBpE)!
|
||||
|
||||
<br><br>
|
||||
Additionally, if you have questions about Basalt or how to make use of it, feel free to create a new discussion on [Basalt's Discussion Board (Github)](https://github.com/Pyroxenium/Basalt/discussions), or ask in our [discord](https://discord.gg/yNNnmBVBpE).
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
Thanks for checking out our wiki, join our discord for more help: [discord.gg/yM7kndJdJJ](discord.gg/yM7kndJdJJ)
|
||||
---
|
||||
|
||||
Thanks for checking out our wiki, join our discord for more help: [discord.gg/yM7kndJdJJ](discord.gg/yNNnmBVBpE)
|
||||
BIN
docs/_media/dynamic-frames.mp4
Normal file
BIN
docs/_media/dynamic-frames.mp4
Normal file
Binary file not shown.
BIN
docs/_media/frames-with-menubars.mp4
Normal file
BIN
docs/_media/frames-with-menubars.mp4
Normal file
Binary file not shown.
BIN
docs/_media/frames-with-sidebar.mp4
Normal file
BIN
docs/_media/frames-with-sidebar.mp4
Normal file
Binary file not shown.
BIN
docs/_media/pane-example-1.png
Normal file
BIN
docs/_media/pane-example-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
BIN
docs/_media/pane-example-2.png
Normal file
BIN
docs/_media/pane-example-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 717 B |
BIN
docs/_media/resizable-frames.mp4
Normal file
BIN
docs/_media/resizable-frames.mp4
Normal file
Binary file not shown.
BIN
docs/_media/scrollable-frames.mp4
Normal file
BIN
docs/_media/scrollable-frames.mp4
Normal file
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
- Getting Started
|
||||
- [Home](Home.md)
|
||||
- [Quick Start](home/Quick-Start.md)
|
||||
- [Installer](home/installer)
|
||||
- [Home](Home)
|
||||
- [How To](home/How-To)
|
||||
- [Download](home/download)
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
- About
|
||||
- [Home](Home.md)
|
||||
- [Quick Start](home/Quick-Start.md)
|
||||
- [Installer](home/installer)
|
||||
- [Home](home)
|
||||
- [How To](home/How-To)
|
||||
- [Download](home/download)
|
||||
- Objects
|
||||
- [Basalt](objects/Basalt.md)
|
||||
- [Object](objects/Object.md)
|
||||
- [Button](objects/Button.md)
|
||||
- [Checkbox](objects/Checkbox.md)
|
||||
- [Dropdown](objects/Dropdown.md)
|
||||
- [Frame](objects/Frame.md)
|
||||
- [Image](objects/Image.md)
|
||||
- [Input](objects/Input.md)
|
||||
- [Label](objects/Label.md)
|
||||
- [List](objects/List.md)
|
||||
- [Menubar](objects/Menubar.md)
|
||||
- [Pane](objects/Pane.md)
|
||||
- [Program](objects/Program.md)
|
||||
- [Progressbar](objects/Progressbar.md)
|
||||
- [Radio](objects/Radio.md)
|
||||
- [Scrollbar](objects/Scrollbar.md)
|
||||
- [Slider](objects/Slider.md)
|
||||
- [Textfield](objects/Textfield.md)
|
||||
- [Animation](objects/Animation.md)
|
||||
- [Thread](objects/Thread.md)
|
||||
- [Timer](objects/Timer.md)
|
||||
- [Basalt](objects/Basalt.md)
|
||||
- [Object](objects/Object.md)
|
||||
- [Button](objects/Button.md)
|
||||
- [Checkbox](objects/Checkbox.md)
|
||||
- [Dropdown](objects/Dropdown.md)
|
||||
- [Frame](objects/Frame.md)
|
||||
- [Image](objects/Image.md)
|
||||
- [Input](objects/Input.md)
|
||||
- [Label](objects/Label.md)
|
||||
- [List](objects/List.md)
|
||||
- [Menubar](objects/Menubar.md)
|
||||
- [Pane](objects/Pane.md)
|
||||
- [Program](objects/Program.md)
|
||||
- [Progressbar](objects/Progressbar.md)
|
||||
- [Radio](objects/Radio.md)
|
||||
- [Scrollbar](objects/Scrollbar.md)
|
||||
- [Slider](objects/Slider.md)
|
||||
- [Textfield](objects/Textfield.md)
|
||||
- [Animation](objects/Animation.md)
|
||||
- [Thread](objects/Thread.md)
|
||||
- [Timer](objects/Timer.md)
|
||||
- Tips & Tricks
|
||||
- [Your Logic](tips/logic.md)
|
||||
- [Button coloring](tips/buttonColoring.md)
|
||||
- [Designing/Animating](tips/design.md)
|
||||
- [Dynamic Values](tips/dynamicvalues.md)
|
||||
- [XML](tips/xml.md)
|
||||
- [Your Logic](tips/logic.md)
|
||||
- [Button coloring](tips/buttonColoring.md)
|
||||
- [Designing/Animating](tips/design.md)
|
||||
- [Dynamic Values](tips/dynamicvalues.md)
|
||||
- [XML](tips/xml.md)
|
||||
|
||||
59
docs/home/How-To.md
Normal file
59
docs/home/How-To.md
Normal file
@@ -0,0 +1,59 @@
|
||||
After downloading the project you can finally start creating your own program and use basalt. The first thing you want to use in your program is always:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
```
|
||||
|
||||
It doesn't matter if you're using the source folder or the minified/packed version of basalt. Both can be found by using require("basalt") without .lua.
|
||||
|
||||
Also to really run basalt you should use
|
||||
|
||||
```lua
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
somewhere on the bottom of your program. basalt.autoUpdate() starts the event listener and the draw handler.
|
||||
|
||||
## Example
|
||||
|
||||
Here is a fully working example of how a program could look like:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") --> Load the basalt framework into the variable called "basalt"
|
||||
|
||||
--> Now we want to create a base frame, we call the variable "main" - by default everything you create is visible. (you don't need to use :show())
|
||||
local main = basalt.createFrame()
|
||||
|
||||
local button = mainFrame:addButton() --> Here we add our first button
|
||||
button:setPosition(4, 4) -- of course we want to change the default position of our button
|
||||
button:setSize(16, 3) -- and the default size.
|
||||
button:setText("Click me!") --> This method displays what the text of our button should look like
|
||||
|
||||
local function buttonClick() --> Let us create a function we want to call when the button gets clicked
|
||||
basalt.debug("I got clicked!")
|
||||
end
|
||||
|
||||
-- Now we just need to register the function to the buttons onClick event handlers, this is how we can achieve that:
|
||||
button:onClick(buttonClick)
|
||||
|
||||
|
||||
basalt.autoUpdate() -- As soon as we call basalt.autoUpdate, the event and draw handlers will listen to any incomming events (and draw if necessary)
|
||||
```
|
||||
|
||||
If you're like us and strive for succinct and beautiful code, here is a cleaner implementation of the code above:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
local button = main --> Basalt returns an instance of the object on most methods, to make use of "call-chaining"
|
||||
:addButton() --> This is an example of call chaining
|
||||
:setPosition(4,4)
|
||||
:setText("Click me!")
|
||||
:onClick(
|
||||
function()
|
||||
basalt.debug("I got clicked!")
|
||||
end)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
@@ -1,92 +0,0 @@
|
||||
## HowTo Use
|
||||
|
||||
To load the framework into your project, make use of the following code on top of your code.
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
```
|
||||
|
||||
It does not matter if you have installed the single file version or the full folder project. <br>
|
||||
Both versions can be loaded by using `require("Basalt")`, you dont need to add `.lua`.
|
||||
|
||||
## Download
|
||||
|
||||
### Download the folder version
|
||||
This version is for people who'd like to work with Basalt, change something in Basalt or checkout the project.<br>
|
||||
But you are also able to just use it to create your own UI.<br>
|
||||
|
||||
To install the full project to your CC:Tweaked Computer, use the following command on your CC:Tweaked shell:
|
||||
|
||||
`pastebin run ESs1mg7P`
|
||||
|
||||
This will download the project as a folder called "Basalt". You are immediatly after the download is done able to use it in your projects.
|
||||
|
||||
### Download the single file version
|
||||
This is the version you should use if you're done with programming. It is a little bit faster and it is also minified, which makes the project smaller.
|
||||
To install the single filed project to your CC:Tweaked Computer, use the following command on your CC:Tweaked shell:
|
||||
|
||||
`pastebin run ESs1mg7P packed`
|
||||
|
||||
This will download the project as a single file called "basalt.lua". You are immediatly after the download is done able to use it in your projects.
|
||||
|
||||
### Basalt Package Manager
|
||||
|
||||
The Basalt Package Manager is still in alpha!<br><br>
|
||||
The Basalt Package Manager is a visual installer, you are able to change some settings, also to choose which objects are necessary for your projects and which are not.
|
||||
|
||||
To install the BPM (Basalt Package Manager) use the following command on your CC:Tweaked shell:
|
||||
|
||||
`pastebin run ESs1mg7P bpm true`
|
||||
|
||||
The true keyword in the end is optional and would simply start BPM immediately.
|
||||
|
||||
## Example
|
||||
Here is a fully functioning example of Basalt code
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") --> Load the Basalt framework
|
||||
|
||||
--> Create the first frame. Please note that Basalt needs at least one active "non-parent" frame to properly supply events
|
||||
--> When Basalt#createFrame makes use of unique identifiers (commonly referred to as UIDs), meaning that the supplied value must be UNIQUE
|
||||
local mainFrame = basalt.createFrame("mainFrame")
|
||||
|
||||
--> Show the frame to the user
|
||||
mainFrame:show()
|
||||
|
||||
local button = mainFrame:addButton("clickableButton") --> Add a button to the mainFrame (With a unique identifier)
|
||||
|
||||
--> Set the position of the button, Button#setPosition follows an x, y pattern.
|
||||
--> The x value is how far right the object should be from its anchor (negative values from an anchor will travel left)
|
||||
--> The y value is how far down the object should be from its anchor (negative values from an anchor will travel up)
|
||||
button:setPosition(4, 4)
|
||||
|
||||
button:setText("Click me!") --> Set the text of our button
|
||||
|
||||
local function buttonClick() --> This function serves as our click logic
|
||||
basalt.debug("I got clicked!")
|
||||
end
|
||||
|
||||
--> Remember! You cannot supply buttonClick(), that will only supply the result of the function
|
||||
--> Make sure the button knows which function to call when it's clicked
|
||||
button:onClick(buttonClick)
|
||||
|
||||
button:show() --> Make the button visible, so the user can click it
|
||||
|
||||
basalt.autoUpdate() --> Basalt#autoUpdate starts the event listener to detect user input
|
||||
```
|
||||
If you're like us and strive for succinct and beautiful code, here is a cleaner implementation of the code above:
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame("mainFrame"):show()
|
||||
local button = mainFrame --> Basalt returns an instance of the object on most methods, to make use of "call-chaining"
|
||||
:addButton("clickableButton") --> This is an example of call chaining
|
||||
:setPosition(4,4)
|
||||
:setText("Click me!")
|
||||
:onClick(
|
||||
function()
|
||||
basalt.debug("I got clicked!")
|
||||
end)
|
||||
:show()
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
36
docs/home/download.md
Normal file
36
docs/home/download.md
Normal file
@@ -0,0 +1,36 @@
|
||||
Basalt provides multiple unique versions. A source version, a minified version and a web version.
|
||||
|
||||
## Source
|
||||
|
||||
This version is, like the name already says, the source code of basalt. If you want to dig into the code, add additional content or just prefer to use the source, then you should aim for the source-version.
|
||||
|
||||
The following command allows you to download the source-version on your computer:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua source [foldername] [branch]`
|
||||
|
||||
The first optional argument is the folder name you wish that basalt should be installed into, by default the folder is called basalt.
|
||||
The second optional argument is the branch you want to use. If you don't know what this means please ignore it (the 2 options are master and dev)
|
||||
|
||||
## Minified / Packed
|
||||
|
||||
This version is the minified version, i also call it the packed version. There are 2 changes, the first one is that the code will be shown minified which makes the size much smaller, the second change is that you will recieve a file instead of a folder.
|
||||
|
||||
The following command allows you to download the packed-version on your computer:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua packed [filename] [branch]`
|
||||
|
||||
The first optional argument is the file name you wish that the installer should use, by default the file is called basalt.lua.
|
||||
The second optional argument is the branch you want to use. If you don't know what this means please ignore it (the 2 options are master and dev)
|
||||
|
||||
## Web
|
||||
|
||||
The web version is a special version, used if your goal is to keep your project's size as small as possible. I suggest you to use the web version only if you don't restart your program over and over again. For example if you designed your program to reboot after the user made a bad choice (leads into a error or something like that) it is better to use the minified/source version.
|
||||
|
||||
The following command allows you to download the web-version on your computer:
|
||||
|
||||
`wget run https://basalt.madefor.cc/install.lua web [version] [filename]`
|
||||
|
||||
By default the first argument is the latest version of basalt's releases. [Here](https://github.com/Pyroxenium/Basalt/tree/master/docs/versions) you can see which versions are available to use.
|
||||
For example: wget run https://basalt.madefor.cc/install.lua web basalt-1.6.3.lua - the second argument is just the file name, default is basaltWeb.lua.
|
||||
|
||||
Remember to rename `local basalt = require("basalt")` into `local basalt = require("basaltWeb")` if you want to use the web-version
|
||||
@@ -1,74 +0,0 @@
|
||||
# Installer
|
||||
|
||||
This is just a script which helps you to setup your program to automatically install the Basalt UI Framework, if it doesn't exists. Means, you create your program (which requires basalt) and add this on the top of your program. Now, everytime you execute your program it checks if basalt.lua (or your custom filepath) exists or not, if not it installs it, or if you are using the advanced installer, it asks the user if the program is allowed to install basalt for you.
|
||||
|
||||
## Basic Installer
|
||||
Here is a very basic one which just installs basalt.lua if don't exist:
|
||||
```lua
|
||||
--Basalt configurated installer
|
||||
local filePath = "basalt.lua" --here you can change the file path default: basalt
|
||||
if not(fs.exists(filePath))then
|
||||
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
|
||||
end
|
||||
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
|
||||
```
|
||||
|
||||
## Advanced Installer
|
||||
This is a visual version, it asks the user if he wants to install basalt.lua (if not found)<br>
|
||||

|
||||
```lua
|
||||
--Basalt configurated installer
|
||||
local filePath = "basalt.lua" --here you can change the file path default: basalt
|
||||
if not(fs.exists(filePath))then
|
||||
local w,h = term.getSize()
|
||||
term.clear()
|
||||
local _installerWindow = window.create(term.current(),w/2-8,h/2-3,18,6)
|
||||
_installerWindow.setBackgroundColor(colors.gray)
|
||||
_installerWindow.setTextColor(colors.black)
|
||||
_installerWindow.write(" Basalt Installer ")
|
||||
_installerWindow.setBackgroundColor(colors.lightGray)
|
||||
for line=2,6,1 do
|
||||
_installerWindow.setCursorPos(1,line)
|
||||
if(line==3)then
|
||||
_installerWindow.write(" No Basalt found! ")
|
||||
elseif(line==4)then
|
||||
_installerWindow.write(" Install it? ")
|
||||
elseif(line==6)then
|
||||
_installerWindow.setTextColor(colors.black)
|
||||
_installerWindow.setBackgroundColor(colors.gray)
|
||||
_installerWindow.write("Install")
|
||||
_installerWindow.setBackgroundColor(colors.lightGray)
|
||||
_installerWindow.write(string.rep(" ",5))
|
||||
_installerWindow.setBackgroundColor(colors.red)
|
||||
_installerWindow.write("Cancel")
|
||||
else
|
||||
_installerWindow.write(string.rep(" ",18))
|
||||
end
|
||||
end
|
||||
_installerWindow.setVisible(true)
|
||||
_installerWindow.redraw()
|
||||
while(not(fs.exists(filePath))) do
|
||||
local event, p1,p2,p3,p4 = os.pullEvent()
|
||||
if(event=="mouse_click")then
|
||||
if(p3==math.floor(h/2+2))and(p2>=w/2-8)and(p2<=w/2-2)then
|
||||
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", ""))
|
||||
_installerWindow.setVisible(false)
|
||||
term.clear()
|
||||
break
|
||||
end
|
||||
if(p3==math.floor(h/2+2))and(p2<=w/2+9)and(p2>=w/2+4)then
|
||||
_installerWindow.clear()
|
||||
_installerWindow.setVisible(false)
|
||||
term.setCursorPos(1,1)
|
||||
term.clear()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
term.setCursorPos(1,1)
|
||||
term.clear()
|
||||
end
|
||||
|
||||
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
|
||||
------------------------------
|
||||
```
|
||||
@@ -33,22 +33,40 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">Did you know: Basalt is a Pyroxene?></div>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-edit-on-github"></script>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
logo: '/_media/logo.png',
|
||||
loadNavbar: true,
|
||||
loadSidebar: true,
|
||||
loadFooter: '_footer.md',
|
||||
autoHeader: true,
|
||||
subMaxLevel: 2,
|
||||
subMaxLevel: 3,
|
||||
homepage: 'Home.md',
|
||||
name: 'Basalt',
|
||||
repo: 'https://github.com/Pyroxenium/Basalt',
|
||||
auto2top: true
|
||||
auto2top: true,
|
||||
search: {
|
||||
maxAge: 86400000, // Expiration time, the default one day
|
||||
paths: 'auto',
|
||||
placeholder: 'Type to search',
|
||||
noData: 'No Results!',
|
||||
// Headline depth, 1 - 6
|
||||
depth: 2,
|
||||
hideOtherSidebarContent: false, // whether or not to hide other sidebar content
|
||||
},
|
||||
plugins: [
|
||||
EditOnGithubPlugin.create("https://github.com/Pyroxenium/Basalt/blob/master/docs/", null, "Edit on Github")
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<!-- Docsify v4 -->
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/js/docsify-themeable.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/prismjs@1.28.0/components/prism-lua.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/@alertbox/docsify-footer/dist/docsify-footer.min.js"></script>
|
||||
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code/dist/docsify-copy-code.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
375
docs/install.lua
Normal file
375
docs/install.lua
Normal file
@@ -0,0 +1,375 @@
|
||||
-- this file can download the project or other tools from github
|
||||
|
||||
local args = table.pack(...)
|
||||
local installer = {printStatus=true}
|
||||
installer.githubPath = "https://raw.githubusercontent.com/Pyroxenium/Basalt/"
|
||||
|
||||
local function printStatus(...)
|
||||
if(installer.printStatus)then
|
||||
print(...)
|
||||
elseif(type(installer.printStatus)=="function")then
|
||||
installer.printStatus(...)
|
||||
end
|
||||
end
|
||||
|
||||
function installer.get(url)
|
||||
local httpReq = http.get(url, _G._GIT_API_KEY and {Authorization = "token ".._G._GIT_API_KEY})
|
||||
printStatus("Downloading "..url)
|
||||
if(httpReq~=nil)then
|
||||
local content = httpReq.readAll()
|
||||
if not content then
|
||||
error("Could not connect to website")
|
||||
end
|
||||
return content
|
||||
end
|
||||
end
|
||||
|
||||
local basaltDataCache
|
||||
function installer.getBasaltData()
|
||||
if(basaltDataCache~=nil)then return basaltDataCache end
|
||||
local content
|
||||
printStatus("Downloading basalt data...")
|
||||
if(fs.exists("basaltdata.json"))then
|
||||
content = fs.open("basaltdata.json", "r")
|
||||
else
|
||||
content = installer.get("https://basalt.madefor.cc/basaltdata.json")
|
||||
end
|
||||
if(content~=nil)then
|
||||
content = content.readAll()
|
||||
basaltDataCache = textutils.unserializeJSON(content)
|
||||
printStatus("Successfully downloaded basalt data!")
|
||||
return basaltDataCache
|
||||
end
|
||||
end
|
||||
|
||||
-- Creates a filetree based on my github project, ofc you can use this in your projects if you'd like to
|
||||
function installer.createTree(page, branch, dirName)
|
||||
dirName = dirName or ""
|
||||
printStatus("Receiving file tree for "..(dirName~="" and "Basalt/"..dirName or "Basalt"))
|
||||
local tree = {}
|
||||
local request = http.get(page, _G._GIT_API_KEY and {Authorization = "token ".._G._GIT_API_KEY})
|
||||
if not(page)then return end
|
||||
if(request==nil)then error("API rate limit exceeded. It will be available again in one hour.") end
|
||||
for _,v in pairs(textutils.unserialiseJSON(request.readAll()).tree)do
|
||||
if(v.type=="blob")then
|
||||
table.insert(tree, {name = v.path, path=fs.combine(dirName, v.path), url=installer.githubPath..branch.."/Basalt/"..fs.combine(dirName, v.path), size=v.size})
|
||||
elseif(v.type=="tree")then
|
||||
tree[v.path] = installer.createTree(v.url, branch, fs.combine(dirName, v.path))
|
||||
end
|
||||
end
|
||||
return tree
|
||||
end
|
||||
|
||||
function installer.createTreeByBasaltData(page, branch, dirName)
|
||||
dirName = dirName or ""
|
||||
printStatus("Receiving file tree for "..(dirName~="" and "Basalt/"..dirName or "Basalt"))
|
||||
local bData = installer.getBasaltData()
|
||||
if(bData~=nil)then
|
||||
local tree = {}
|
||||
for k,v in pairs(bData.structure)do
|
||||
if(k=="base")then
|
||||
for a,b in pairs(v)do
|
||||
table.insert(tree, b)
|
||||
end
|
||||
else
|
||||
tree[k] = v
|
||||
end
|
||||
end
|
||||
return tree
|
||||
end
|
||||
end
|
||||
|
||||
local function splitString(str, sep)
|
||||
if sep == nil then
|
||||
sep = "%s"
|
||||
end
|
||||
local t={}
|
||||
for v in string.gmatch(str, "([^"..sep.."]+)") do
|
||||
table.insert(t, v)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function installer.createIgnoreList(str)
|
||||
local files = splitString(str, ":")
|
||||
local ignList = {}
|
||||
for k,v in pairs(files)do
|
||||
local a = splitString(v, "/")
|
||||
if(#a>1)then
|
||||
if(ignList[a[1]]==nil)then ignList[a[1]] = {} end
|
||||
table.insert(ignList[a[1]], a[2])
|
||||
else
|
||||
table.insert(ignList, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function installer.download(url, file)
|
||||
local content = installer.get(url)
|
||||
if(content~=nil)then
|
||||
local f = fs.open(file, "w")
|
||||
f.write(content)
|
||||
f.close()
|
||||
end
|
||||
end
|
||||
|
||||
function installer.getRelease(version)
|
||||
local v = installer.getBasaltData().versions[version]
|
||||
if(v~=nil)then
|
||||
printStatus("Downloading basalt "..version)
|
||||
local content = http.get("https://basalt.madefor.cc/versions/"..v, {Authorization = _G._GIT_API_KEY and "token ".._G._GIT_API_KEY})
|
||||
if(content~=nil)then
|
||||
return content.readAll()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function installer.downloadRelease(version, file)
|
||||
local content = installer.getRelease(version)
|
||||
if(content~=nil)then
|
||||
local f = fs.open(file or "basalt.lua", "w")
|
||||
f.write(content)
|
||||
f.close()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function installer.getPackedProject(branch, ignoreList)
|
||||
if (ignoreList==nil)then
|
||||
ignoreList = {"init.lua"}
|
||||
else
|
||||
table.insert(ignoreList, "init.lua")
|
||||
end
|
||||
local projTree = installer.createTree("https://api.github.com/repos/Pyroxenium/Basalt/git/trees/"..branch..":Basalt", branch, "")
|
||||
local filteredList = {}
|
||||
local project = {}
|
||||
|
||||
local function isInIgnoreList(file, ign)
|
||||
if(ign~=nil)then
|
||||
for k,v in pairs(ign)do
|
||||
if(v==file.name)then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
for k,v in pairs(projTree)do
|
||||
if(type(k)=="string")then
|
||||
for a,b in pairs(v)do
|
||||
if not(isInIgnoreList(b, ignoreList~=nil and ignoreList[k] or nil))then
|
||||
if(filteredList[k]==nil)then filteredList[k] = {} end
|
||||
table.insert(filteredList[k], b)
|
||||
end
|
||||
end
|
||||
else
|
||||
if not(isInIgnoreList(v, ignoreList))then
|
||||
table.insert(filteredList, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local fList = {}
|
||||
local delay = 0
|
||||
for k,v in pairs(filteredList)do
|
||||
if(type(k)=="string")then
|
||||
for a,b in pairs(v)do
|
||||
table.insert(fList, function() sleep(delay)
|
||||
if(project[k]==nil)then project[k] = {} end
|
||||
table.insert(project[k], {content=installer.get(b.url), name=b.name, path=b.path, size = b.size, url = b.url})
|
||||
delay = delay + 0.05
|
||||
end)
|
||||
end
|
||||
else
|
||||
table.insert(fList, function() sleep(delay) table.insert(project, {content=installer.get(v.url), name=v.name, path=v.path, size = v.size, url = v.url}) delay = delay + 0.05 end)
|
||||
end
|
||||
end
|
||||
|
||||
parallel.waitForAll(table.unpack(fList))
|
||||
|
||||
local projectContent =
|
||||
[[
|
||||
local project = {}
|
||||
local packaged = true
|
||||
local baseRequire = require
|
||||
local require = function(path)
|
||||
for k,v in pairs(project)do
|
||||
if(type(v)=="table")then
|
||||
for name,b in pairs(v)do
|
||||
if(name==path)then
|
||||
return b()
|
||||
end
|
||||
end
|
||||
else
|
||||
if(k==path)then
|
||||
return v()
|
||||
end
|
||||
end
|
||||
end
|
||||
return baseRequire(path);
|
||||
end
|
||||
local getProject = function(subDir)
|
||||
if(subDir~=nil)then
|
||||
return project[subDir]
|
||||
end
|
||||
return project
|
||||
end
|
||||
]]
|
||||
|
||||
for k,v in pairs(project)do
|
||||
if(type(k)=="string")then
|
||||
local newSubDir = 'project["'..k..'"] = {}\n'
|
||||
projectContent = projectContent.."\n"..newSubDir
|
||||
for a,b in pairs(v)do
|
||||
local newFile = 'project["'..k..'"]["'..b.name:gsub(".lua", "")..'"] = function(...)\n'..b.content..'\nend'
|
||||
projectContent = projectContent.."\n"..newFile
|
||||
end
|
||||
else
|
||||
local newFile = 'project["'..v.name:gsub(".lua", "")..'"] = function(...)\n'..v.content..'\nend'
|
||||
projectContent = projectContent.."\n"..newFile
|
||||
end
|
||||
end
|
||||
projectContent = projectContent..'\n return project["main"]()'
|
||||
|
||||
return projectContent
|
||||
end
|
||||
|
||||
function installer.generateWebVersion(file, version)
|
||||
if(fs.exists(file))then error("A file called "..file.." already exists!") end
|
||||
version = version or "latest.lua"
|
||||
local request = http.get("https://basalt.madefor.cc/versions/"..version, _G._GIT_API_KEY and {Authorization = "token ".._G._GIT_API_KEY})
|
||||
if(request~=nil)then
|
||||
if(fs.exists(file))then
|
||||
fs.delete(file)
|
||||
local f = fs.open(file, "w")
|
||||
local link = "https://basalt.madefor.cc/versions/"..version
|
||||
local content = 'local request = http.get("'..link..'", _G._GIT_API_KEY and {Authorization = "token ".._G._GIT_API_KEY})\n'
|
||||
content = content..
|
||||
[[
|
||||
if(request~=nil)then
|
||||
return load(request.readAll())()
|
||||
else
|
||||
error("Unable to connect to ]]..link..[[")
|
||||
end
|
||||
]]
|
||||
f.write(content)
|
||||
f.close()
|
||||
printStatus("Web version successfully downloaded!")
|
||||
end
|
||||
else
|
||||
error("Version doesn't exist!")
|
||||
end
|
||||
end
|
||||
|
||||
function installer.getProjectFiles(branch, ignoreList)
|
||||
local projTree = installer.createTree("https://api.github.com/repos/Pyroxenium/Basalt/git/trees/"..branch..":Basalt", branch, "")
|
||||
local filteredList = {}
|
||||
local project = {}
|
||||
|
||||
local function isInIgnoreList(file)
|
||||
if(ignoreList~=nil)then
|
||||
for k,v in pairs(ignoreList)do
|
||||
if(v==file)then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
for k,v in pairs(projTree)do
|
||||
if not(isInIgnoreList(v.name))then
|
||||
if(type(k)=="string")then
|
||||
local sub = {}
|
||||
for a,b in pairs(v)do
|
||||
if not(isInIgnoreList(b.name))then
|
||||
table.insert(sub, b)
|
||||
end
|
||||
end
|
||||
filteredList[k] = sub
|
||||
else
|
||||
table.insert(filteredList, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function downloadFile(url, path)
|
||||
project[path] = installer.get(url)
|
||||
end
|
||||
|
||||
local fList = {}
|
||||
local delay = 0
|
||||
for k,v in pairs(filteredList)do
|
||||
if(type(k)=="string")then
|
||||
for a,b in pairs(v)do
|
||||
table.insert(fList, function() sleep(delay) downloadFile(b.url, b.path) end)
|
||||
delay = delay + 0.05
|
||||
end
|
||||
else
|
||||
table.insert(fList, function() sleep(delay) downloadFile(v.url, v.path) end)
|
||||
delay = delay + 0.05
|
||||
end
|
||||
end
|
||||
parallel.waitForAll(table.unpack(fList))
|
||||
|
||||
return project
|
||||
end
|
||||
|
||||
function installer.downloadPacked(filename, branch, ignoreList, minify)
|
||||
if(fs.exists(filename))then error("A file called "..filename.." already exists!") end
|
||||
local projectContent = installer.getPackedProject(branch, ignoreList)
|
||||
if(minify)then
|
||||
local min
|
||||
if(fs.exists("packager.lua"))then
|
||||
min = require("packager")
|
||||
else
|
||||
min = load(installer.get("https://raw.githubusercontent.com/Pyroxenium/Basalt/master/docs/packager.lua"))()
|
||||
end
|
||||
if(min~=nil)then
|
||||
success, data = min(projectContent)
|
||||
if(success)then
|
||||
projectContent = data
|
||||
else
|
||||
error(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
local f = fs.open(filename, "w")
|
||||
f.write(projectContent)
|
||||
f.close()
|
||||
printStatus("Packed version successfully downloaded!")
|
||||
end
|
||||
|
||||
function installer.downloadProject(projectDir, branch, ignoreList)
|
||||
if(fs.exists(projectDir))then error("A folder called "..projectDir.." already exists!") end
|
||||
projectDir = projectDir or "basalt"
|
||||
branch = branch or "master"
|
||||
local projectFiles = installer.getProjectFiles(branch, ignoreList)
|
||||
fs.makeDir(projectDir)
|
||||
for k,v in pairs(projectFiles)do
|
||||
local f = fs.open(fs.combine(projectDir, k), "w")
|
||||
f.write(v)
|
||||
f.close()
|
||||
end
|
||||
printStatus("Source version successfully downloaded!")
|
||||
end
|
||||
|
||||
if(#args>0)then
|
||||
if(string.lower(args[1])=="bpm")or(string.lower(args[1])=="basaltpackagemanager")or(string.lower(args[1])=="gui")then
|
||||
installer.download("https://raw.githubusercontent.com/Pyroxenium/Basalt/master/basaltPackageManager.lua", "basaltPackageManager.lua")
|
||||
if(args[2]=="true")then shell.run("basaltPackageManager.lua") fs.delete("basaltPackageManager.lua") end
|
||||
|
||||
elseif(string.lower(args[1])=="packed")then
|
||||
installer.downloadPacked(args[2] or "basalt.lua", args[3] or "master", args[4]~=nil and installer.createIgnoreList(args[4]) or nil, args[5] == "false" and false or true)
|
||||
elseif(string.lower(args[1])=="source")then
|
||||
installer.downloadProject(args[2] or "basalt", args[3] or "master", args[4]~=nil and installer.createIgnoreList(args[4]) or nil)
|
||||
elseif(string.lower(args[1])=="web")then
|
||||
installer.generateWebVersion(args[3] or "basaltWeb.lua", args[2] or "latest.lua")
|
||||
elseif(string.lower(args[1])=="file")then
|
||||
installer.download("https://basalt.madefor.cc/versions/"..args[2] or "latest.lua", args[3] or "basalt.lua")
|
||||
end
|
||||
end
|
||||
|
||||
return installer
|
||||
@@ -1,487 +0,0 @@
|
||||
--Basalt configurated installer
|
||||
local filePath = "basalt.lua" --here you can change the file path default: basalt
|
||||
if not(fs.exists(filePath))then
|
||||
shell.run("pastebin run ESs1mg7P packed true "..filePath:gsub(".lua", "")) -- this is an alternative to the wget command
|
||||
end
|
||||
local basalt = require(filePath:gsub(".lua", "")) -- here you can change the variablename in any variablename you want default: basalt
|
||||
|
||||
local maxCoWorker = 3
|
||||
|
||||
local recipeList = {}
|
||||
local craftingQueue = {}
|
||||
local bridge = peripheral.find("rsBridge")
|
||||
local w, h = term.getSize()
|
||||
|
||||
local main = basalt.createFrame()
|
||||
local home = main:addFrame():setPosition(1,2):setBackground(colors.lightGray):setSize(w, h-2)
|
||||
local recipes = main:addFrame():setPosition(1,2):setBackground(colors.lightGray):hide()
|
||||
local log = main:addFrame():setPosition(1,2):setBackground(colors.lightGray):hide()
|
||||
|
||||
local menuBar = main:addMenubar():addItem("Home"):addItem("Recipes"):addItem("Log"):setBackground(colors.gray):setSize(w, 1):setSpace(6):setScrollable():show()
|
||||
menuBar:onChange(function(self)
|
||||
home:hide()
|
||||
recipes:hide()
|
||||
log:hide()
|
||||
if(self:getValue().text=="Home")then
|
||||
home:show()
|
||||
elseif(self:getValue().text=="Recipes")then
|
||||
recipes:show()
|
||||
elseif(self:getValue().text=="Log")then
|
||||
log:show()
|
||||
end
|
||||
end)
|
||||
|
||||
local function buttonVisuals(btn)
|
||||
btn:onClick(basalt.schedule(function() btn:setBackground(colors.black) btn:setForeground(colors.lightGray) os.sleep(0.1) btn:setBackground(colors.gray) btn:setForeground(colors.black) end))
|
||||
end
|
||||
|
||||
local coworkerCount = home:addLabel():setText(maxCoWorker):setPosition(45,2):show()
|
||||
home:addLabel():setText("Co-Worker:"):setPosition(32,2):show()
|
||||
buttonVisuals(home:addButton():setText(">"):setSize(1,1):setPosition(47,2):onClick(function() if(maxCoWorker<100)then maxCoWorker = maxCoWorker+1 end coworkerCount:setText(maxCoWorker) end):show())
|
||||
buttonVisuals(home:addButton():setText("<"):setSize(1,1):setPosition(43,2):onClick(function() if(maxCoWorker>1)then maxCoWorker = maxCoWorker-1 end coworkerCount:setText(maxCoWorker) end):show())
|
||||
|
||||
local logList = log:addList():setPosition(2,2):setSize(w-2,h-3):setScrollable(false):show()
|
||||
local jobList = home:addList():setPosition(20,4):setSize(30,10):show()
|
||||
local rList = recipes:addList():setPosition(13,2):setSize(38,16):show()
|
||||
|
||||
local function logging(text)
|
||||
logList:addItem(text)
|
||||
if(logList:getItemCount()>h-3)then
|
||||
logList:removeItem(1)
|
||||
end
|
||||
end
|
||||
|
||||
logging("Loading autocrafter...")
|
||||
|
||||
function SaveToFile()
|
||||
local file = io.open("recipes", "wb")
|
||||
local sel = rList:getItemIndex()
|
||||
rList:clear()
|
||||
for _,v in pairs(recipeList)do
|
||||
if(v.useDmg)then
|
||||
file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|true|", "\n")
|
||||
else
|
||||
file:write(v.name.."|"..v.damage.."|"..v.minAmount.."|"..v.maxCraftAmount.."|false|", "\n")
|
||||
end
|
||||
rList:addItem(v.minAmount.."x "..v.name..":"..v.damage, nil, nil, v)
|
||||
end
|
||||
rList:selectItem(sel)
|
||||
file:close()
|
||||
end
|
||||
|
||||
buttonVisuals(recipes:addButton():setPosition(2,2):setText("Remove"):setSize(8,1):onClick(function()
|
||||
if(rList:getValue()~=nil)then
|
||||
local sel = rList:getValue().args[1]
|
||||
for k,v in pairs(recipeList)do
|
||||
if(v.name==sel.name)and(tonumber(v.damage)==tonumber(sel.damage))then
|
||||
table.remove(recipeList, k)
|
||||
logging("Removed recipe: "..v.name..":"..v.damage)
|
||||
SaveToFile()
|
||||
end
|
||||
end
|
||||
end
|
||||
end))
|
||||
local changeAmn = recipes:addInput():setPosition(4,4):setSize(5,1):setInputType("number"):setForeground(colors.black):setDefaultText("32", colors.black):onChange(function(self)
|
||||
local val = tonumber(self:getValue()) or 32
|
||||
if(val<0)then
|
||||
self:setValue(0)
|
||||
end
|
||||
end)
|
||||
buttonVisuals(recipes:addButton():setPosition(2,4):setSize(1,1):setText("-"):onClick(function()
|
||||
local val = tonumber(changeAmn:getValue()) or 32
|
||||
if(rList:getValue()~=nil)then
|
||||
local sel = rList:getValue().args[1]
|
||||
if(val>0)and(sel.name~=nil)and(sel.damage~=nil)then
|
||||
for k,v in pairs(recipeList)do
|
||||
if(v.name==sel.name)and(tonumber(v.damage)==tonumber(sel.damage))then
|
||||
v.minAmount = v.minAmount - val
|
||||
if(v.minAmount < 0)then v.minAmount = 0 end
|
||||
SaveToFile()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end))
|
||||
buttonVisuals(recipes:addButton():setPosition(10,4):setSize(1,1):setText("+"):onClick(function()
|
||||
local val = tonumber(changeAmn:getValue()) or 32
|
||||
if(rList:getValue()~=nil)then
|
||||
local sel = rList:getValue().args[1]
|
||||
if(val>0)and(sel.name~=nil)and(sel.damage~=nil)then
|
||||
for k,v in pairs(recipeList)do
|
||||
if(v.name==sel.name)and(tonumber(v.damage)==tonumber(sel.damage))then
|
||||
v.minAmount = v.minAmount + val
|
||||
SaveToFile()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end))
|
||||
|
||||
buttonVisuals(recipes:addButton():setPosition(2,6):setSize(8,1):setText("Set"):onClick(function()
|
||||
local val = tonumber(changeAmn:getValue()) or 32
|
||||
if(rList:getValue()~=nil)then
|
||||
local sel = rList:getValue().args[1]
|
||||
if(val>0)and(sel.name~=nil)and(sel.damage~=nil)then
|
||||
for k,v in pairs(recipeList)do
|
||||
if(v.name==sel.name)and(tonumber(v.damage)==tonumber(sel.damage))then
|
||||
v.minAmount = val
|
||||
SaveToFile()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end))
|
||||
|
||||
local rItemFrame = home:addFrame():setPosition(7,3):setBackground(colors.gray):setSize(27,6):setMoveable(true):setBar("Remove Item", colors.black, colors.lightGray):showBar():hide()
|
||||
rItemFrame:addButton():setPosition(1,1):setAnchor("topRight"):setSize(1,1):setBackground(colors.black):setForeground(colors.lightGray):setText("x"):onClick(function() rItemFrame:hide() end):show()
|
||||
rItemFrame:addLabel():setText("Item ID:"):setPosition(2,3):show()
|
||||
local ritemId = rItemFrame:addInput("itemid"):setPosition(12,3):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setDefaultText("minecraft:stick", colors.gray):show()
|
||||
rItemFrame:addButton():setPosition(-7,0):setAnchor("bottomRight"):setSize(8,1):setBackground(colors.black):setForeground(colors.lightGray):setText("Remove"):onClick(function()
|
||||
local id = ritemId:getValue()
|
||||
|
||||
for k,v in pairs(recipeList)do
|
||||
if(v.name==id)then
|
||||
table.remove(recipeList, k)
|
||||
logging("Removed recipe: "..v.name..":"..v.damage)
|
||||
end
|
||||
end
|
||||
SaveToFile()
|
||||
end)
|
||||
|
||||
|
||||
local aItemFrame = home:addFrame():setPosition(7,3):setBackground(colors.gray):setSize(27,12):setMoveable(true):setBar("Add Item", colors.black, colors.lightGray):showBar():hide()
|
||||
aItemFrame:addLabel():setText("Item ID:"):setPosition(2,3)
|
||||
aItemFrame:addLabel():setText("Damage:"):setPosition(2,5)
|
||||
aItemFrame:addLabel():setText("Count:"):setPosition(2,7)
|
||||
aItemFrame:addLabel():setText("Max:"):setPosition(2,9)
|
||||
aItemFrame:addLabel():setText("Use Damage:"):setAnchor("bottomLeft"):setPosition(4,0)
|
||||
local itemId = aItemFrame:addInput():setPosition(12,3):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setDefaultText("minecraft:stick", colors.gray)
|
||||
local itemDamage = aItemFrame:addInput():setPosition(12,5):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setInputType("number"):setDefaultText("0", colors.gray)
|
||||
local itemCount = aItemFrame:addInput():setPosition(12,7):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setInputType("number"):setDefaultText("64", colors.gray)
|
||||
local itemMaxCount = aItemFrame:addInput():setPosition(12,9):setSize(15,1):setBackground(colors.black):setForeground(colors.lightGray):setInputType("number"):setDefaultText("0", colors.gray)
|
||||
local useDamage = aItemFrame:addCheckbox():setAnchor("bottomLeft"):setPosition(2,0):setBackground(colors.black):setForeground(colors.lightGray):setValue(true)
|
||||
aItemFrame:addButton():setAnchor("topRight"):setPosition(1,1):setSize(1,1):setBackground(colors.black):setForeground(colors.lightGray):setText("x"):onClick(function() aItemFrame:hide() end)
|
||||
aItemFrame:addButton():setAnchor("bottomRight"):setPosition(-4,0):setSize(5,1):setBackground(colors.black):setForeground(colors.lightGray):setText("Add"):onClick(function()
|
||||
local id = itemId:getValue()
|
||||
local dmg = itemDamage:getValue() == "" and 0 or itemDamage:getValue()
|
||||
local count = itemCount:getValue() == "" and 64 or itemCount:getValue()
|
||||
local maxCount = itemMaxCount:getValue() == "" and 0 or itemMaxCount:getValue()
|
||||
local usedamage = useDamage:getValue() or true
|
||||
if(id~="")then
|
||||
local itemExist = false
|
||||
for k,v in pairs(recipeList)do
|
||||
if(v.name==id)then
|
||||
if(usedamage)then
|
||||
if(v.damage==dmg)then
|
||||
itemExist = true
|
||||
v.minAmount = count or 64
|
||||
v.maxCraftAmount = maxCount or 0
|
||||
logging("Edited recipe: "..(count).."x "..id..":"..dmg)
|
||||
end
|
||||
else
|
||||
itemExist = true
|
||||
v.minAmount = count or 64
|
||||
v.maxCraftAmount = maxCount or 0
|
||||
logging("Edited recipe: "..(count).."x "..id..":"..dmg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if(itemExist == false)then
|
||||
table.insert(recipeList, {name = id, damage = dmg or 0, minAmount = count, maxCraftAmount = maxCount or 0, useDmg = usedamage, fails = 0, timer = 0})
|
||||
logging("Added recipe: "..(count).."x "..id..":"..dmg)
|
||||
end
|
||||
SaveToFile()
|
||||
else
|
||||
logging("Please set a ID.")
|
||||
end
|
||||
end)
|
||||
|
||||
buttonVisuals(home:addButton():setText("Add Item"):setSize(12,3):setPosition(2,6):onClick(function() aItemFrame:show() aItemFrame:setFocus() end):show())
|
||||
buttonVisuals(home:addButton():setText("Remove Item"):setSize(12,3):setPosition(2,10):onClick(function() rItemFrame:show() rItemFrame:setFocus() end):show())
|
||||
|
||||
local function StringSeperate(str, seperator)
|
||||
local words = {}
|
||||
local word = ""
|
||||
|
||||
if(string.sub(str, str:len(), str:len())~=seperator)then
|
||||
str = str..""..seperator
|
||||
end
|
||||
for x=1,str:len() do
|
||||
local s = string.sub(str,x,x)
|
||||
if(s==seperator)then
|
||||
table.insert(words, word)
|
||||
word = ""
|
||||
else
|
||||
word = word..s
|
||||
end
|
||||
end
|
||||
return words
|
||||
end
|
||||
|
||||
if not(fs.exists("recipes"))then
|
||||
fs.open("recipes","w").close()
|
||||
end
|
||||
|
||||
local f = fs.open("recipes", "r")
|
||||
for line in f.readLine do
|
||||
local tab = StringSeperate(line, "|")
|
||||
if(tab[1]~=nil)and(tab[2]~=nil)and(tab[3]~=nil)and(tab[4]~=nil)and(tab[5]~=nil)then
|
||||
logging("Registered recipe: "..tab[3].."x "..tab[1]..":"..tab[2])
|
||||
local recipe = {name=tab[1],damage=tonumber(tab[2]),minAmount=tonumber(tab[3]),maxCraftAmount=tonumber(tab[4]),fails=0,timer=0}
|
||||
if(tab[5]=="true")then
|
||||
recipe.useDmg=true
|
||||
else
|
||||
recipe.useDmg=false
|
||||
end
|
||||
rList:addItem(recipe.minAmount.."x "..recipe.name..":"..recipe.damage, nil, nil, recipe)
|
||||
table.insert(recipeList, recipe)
|
||||
end
|
||||
end
|
||||
f.close()
|
||||
|
||||
local function findKeyWithItemName(table, itemname, damage)
|
||||
for k,v in pairs(table)do
|
||||
if(v.name==itemname)and(v.damage == damage)then
|
||||
return k
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local scanChestBtn = home:addButton("scanChest"):setText("Scan Chest"):setSize(12,3):setPosition(2,2):show()
|
||||
local function checkChestForNewEntrys()
|
||||
scanChestBtn:setText("Scanning..")
|
||||
local inventory = peripheral.find("minecraft:chest")
|
||||
local items = {}
|
||||
local itemAmounts = {}
|
||||
local somethingChanged = false
|
||||
|
||||
if(inventory~=nil)then
|
||||
for x=1,inventory.size(), 1 do
|
||||
local item = inventory.getItemDetail(x)
|
||||
if(item~=nil)then
|
||||
if(item.damage==nil)then item.damage = 0 end
|
||||
table.insert(items, item)
|
||||
end
|
||||
os.sleep(0.1)
|
||||
end
|
||||
else
|
||||
logging("No chest available!")
|
||||
end
|
||||
|
||||
if(#items > 0)then
|
||||
for _,v in pairs(items)do
|
||||
local key = findKeyWithItemName(itemAmounts, v.name, v.damage)
|
||||
if(key~=nil)then
|
||||
itemAmounts[key].count = itemAmounts[key].count + v.count
|
||||
else
|
||||
table.insert( itemAmounts, {name=v.name, damage=v.damage, count = v.count})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if(#itemAmounts > 0)then
|
||||
for _,v in pairs(itemAmounts)do
|
||||
local key = findKeyWithItemName(recipeList, v.name, v.damage)
|
||||
if(key~=nil)then
|
||||
if(recipeList[key].minAmount ~= v.count)then
|
||||
logging("Edited recipe: "..v.name.. ":"..v.damage.." new count: "..v.count)
|
||||
end
|
||||
somethingChanged = true
|
||||
recipeList[key].minAmount = v.count
|
||||
else
|
||||
table.insert( recipeList, {name=v.name, damage=v.damage, minAmount = v.count, maxCraftAmount = 0, useDmg = true, fails = 0, timer = 0})
|
||||
somethingChanged = true
|
||||
logging("Registered recipe: "..v.count.."x "..v.name.. ":"..v.damage)
|
||||
end
|
||||
end
|
||||
if(somethingChanged)then
|
||||
SaveToFile()
|
||||
end
|
||||
end
|
||||
scanChestBtn:setText("Scan Chest")
|
||||
logging("Scanning chest done.")
|
||||
end
|
||||
|
||||
local chestScanThread = main:addThread("chestScanThread")
|
||||
buttonVisuals(scanChestBtn:onClick(function() chestScanThread:start(checkChestForNewEntrys) end))
|
||||
|
||||
|
||||
local function GetAmount(itemAmount, recipe)
|
||||
local amount = 0
|
||||
if(itemAmount < recipe.minAmount)then
|
||||
if(recipe.maxCraftAmount > 0)then
|
||||
if(recipe.minAmount-itemAmount > recipe.maxCraftAmount)then
|
||||
amount = recipe.maxCraftAmount
|
||||
else
|
||||
amount = recipe.minAmount-itemAmount
|
||||
end
|
||||
else
|
||||
amount = recipe.minAmount-itemAmount
|
||||
end
|
||||
end
|
||||
return amount
|
||||
end
|
||||
|
||||
function GetRecipeKey(pattern)
|
||||
for k,v in pairs(recipeList)do
|
||||
if(v.name == pattern.name)then
|
||||
if(pattern.damage==nil)then return k end
|
||||
if(v.useDmg)then
|
||||
if(v.damage == pattern.damage)then
|
||||
return k
|
||||
end
|
||||
else
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function CheckCraftingRecipe(recipe)
|
||||
local pattern = bridge.getItem({name=recipe.name})
|
||||
local item = {pattern=pattern, amount=0}
|
||||
if(pattern~=nil)then
|
||||
local storedAmount = pattern.amount
|
||||
local neededItemAmount = GetAmount(storedAmount, recipe)
|
||||
if(neededItemAmount > 0)then
|
||||
item.amount = neededItemAmount
|
||||
table.insert(craftingQueue, item)
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function RemoveRecipe(item)
|
||||
local key = -1
|
||||
for k,v in pairs(recipeList)do
|
||||
if(v.name == item.name)and(v.damage== item.damage)then
|
||||
key = k
|
||||
end
|
||||
end
|
||||
if(key>=0)then
|
||||
table.remove(recipeList, key)
|
||||
end
|
||||
SaveToFile()
|
||||
end
|
||||
|
||||
local function FindKeyInTable(table, item)
|
||||
for k,v in pairs(table)do
|
||||
if(v==item)then
|
||||
return k
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function CheckAllRecipes()
|
||||
for _,v in pairs(recipeList)do
|
||||
if(type(v)=="table")then
|
||||
CheckCraftingRecipe(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function jobCrafting(coworker, item)
|
||||
if(jobList:getItem(coworker)~=nil)then
|
||||
jobList:editItem(coworker, "Co-Worker "..coworker..": "..item.amountToCraft.."x "..item.item.displayName:gsub(" ", ""))
|
||||
else
|
||||
jobList:addItem("Co-Worker "..coworker..": "..item.amountToCraft.."x "..item.item.displayName:gsub(" ", ""))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function jobDone(coworker)
|
||||
if(jobList:getItem(coworker)~=nil)then
|
||||
jobList:editItem(coworker, "Co-Worker "..coworker..": waiting...")
|
||||
else
|
||||
jobList:addItem("Co-Worker "..coworker..": waiting...")
|
||||
end
|
||||
end
|
||||
|
||||
local coWorkerId = 1
|
||||
local function UpdateCraftingQueue()
|
||||
while(#craftingQueue > 0)do
|
||||
local activeCoWorkers = {}
|
||||
local craftingQueuesToRemove = {}
|
||||
for _,v in pairs(craftingQueue)do
|
||||
if(#activeCoWorkers+1 <= maxCoWorker)then
|
||||
local stack = v.pattern
|
||||
local recipeKey = GetRecipeKey(stack)
|
||||
|
||||
local waittimer = 0
|
||||
local multiplier = 1
|
||||
|
||||
if(recipeList[recipeKey].fails > 0)and(recipeList[recipeKey].fails <=10)then
|
||||
multiplier = recipeList[recipeKey].fails
|
||||
elseif(recipeList[recipeKey].fails > 10)then
|
||||
multiplier = 20
|
||||
end
|
||||
waittimer = multiplier * 30
|
||||
if(os.clock()>=recipeList[recipeKey].timer+waittimer)then
|
||||
if not(bridge.isItemCrafting(stack.name))then
|
||||
local currentItemState = {item=stack, curAmount = stack.count, amountToCraft = v.amount}
|
||||
if(bridge.isItemCraftable({name=stack.name}))then
|
||||
local task, errormsg = bridge.craftItem({name=stack.name, count = v.amount})
|
||||
if(task)then
|
||||
logging("Sheduled Task: "..v.amount.." ("..stack.name..") "..stack.displayName:gsub(" ", ""))
|
||||
jobCrafting(coWorkerId, currentItemState)
|
||||
currentItemState.coWorker = coWorkerId
|
||||
coWorkerId = coWorkerId + 1
|
||||
if(coWorkerId > maxCoWorker)then coWorkerId = 1 end
|
||||
table.insert(activeCoWorkers, currentItemState)
|
||||
recipeList[recipeKey].fails = 0
|
||||
else
|
||||
logging("Error sheduling task: "..v.amount.."x ("..stack.name..") "..stack.displayName:gsub(" ", ""))
|
||||
logging("Not enough materials!")
|
||||
recipeList[recipeKey].fails = recipeList[recipeKey].fails + 1
|
||||
recipeList[recipeKey].timer = os.clock()
|
||||
end
|
||||
else
|
||||
logging("Error sheduling task: "..v.amount.."x ("..stack.name..") "..stack.displayName:gsub(" ", ""))
|
||||
logging("No pattern available!")
|
||||
recipeList[recipeKey].fails = recipeList[recipeKey].fails + 1
|
||||
recipeList[recipeKey].timer = os.clock()
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert(craftingQueuesToRemove, v)
|
||||
end
|
||||
end
|
||||
|
||||
if(#craftingQueuesToRemove > 0)then
|
||||
for _,v in pairs(craftingQueuesToRemove)do
|
||||
local id = FindKeyInTable(craftingQueue, v)
|
||||
table.remove(craftingQueue, id)
|
||||
end
|
||||
end
|
||||
|
||||
while(#activeCoWorkers > 0)do
|
||||
local finishedCoworker = {}
|
||||
for _,v in pairs(activeCoWorkers)do
|
||||
if not(bridge.isItemCrafting(v.item.name))then
|
||||
logging("Task done: "..v.amountToCraft.."x ("..v.item.name..") "..v.item.displayName:gsub(" ", ""))
|
||||
table.insert(finishedCoworker, v)
|
||||
end
|
||||
end
|
||||
if(#finishedCoworker>0)then
|
||||
for _,v in pairs(finishedCoworker)do
|
||||
local id = FindKeyInTable(activeCoWorkers, v)
|
||||
table.remove(activeCoWorkers, id)
|
||||
jobDone(v.coWorker)
|
||||
end
|
||||
end
|
||||
os.sleep(0.75)
|
||||
end
|
||||
os.sleep(0.75)
|
||||
end
|
||||
end
|
||||
|
||||
main:addThread("craftingThread"):start(function() while true do CheckAllRecipes() os.sleep(1) UpdateCraftingQueue() os.sleep(1) end end)
|
||||
|
||||
logging("Autocrafter successfully loaded!")
|
||||
|
||||
basalt.autoUpdate()
|
||||
@@ -1,4 +1,12 @@
|
||||
With animations, you can create a beautiful experience for users while interacting with your program.<br>
|
||||
With animations, you can create a beautiful experience for users while interacting with your program.
|
||||
There are 2 types of animations, predefined animations and custom animations. By using add and wait you can create custom
|
||||
animations (calls). Pre-defined methods are for example move, offset, size, changeText,...
|
||||
|
||||
:setObject always sets the object on what pre-defined methods should apply on.
|
||||
|
||||
When calling a pre-defined animation it will check what is safed as object (:setObject) and will calculate the animation methods based on that which means you won't
|
||||
be able to change the object on the fly - you will always have to recreate the animation itself
|
||||
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
@@ -6,6 +14,8 @@ With animations, you can create a beautiful experience for users while interacti
|
||||
|[wait](objects/Animation/wait.md)|Adds a amount to the animation time
|
||||
|[play](objects/Animation/play.md)|Plays the animation
|
||||
|[cancel](objects/Animation/cancel.md)|Cancels the animation
|
||||
|[addMode](objects/Animation/addMode.md)|Adds custom easings
|
||||
|[setMode](objects/Animation/setMode.md)|Changes the current easing-calculation
|
||||
|[setObject](objects/Animation/setObject.md)|Sets an object on which predefined animations should work on
|
||||
|[move](objects/Animation/move.md)|Predefined animation: moves the object to a new position
|
||||
|[offset](objects/Animation/offset.md)|Predefined animation: Changes the offset of that object
|
||||
@@ -18,4 +28,5 @@ With animations, you can create a beautiful experience for users while interacti
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|[onStart](objects/Animation/onStart.md)|Gets called as soon as the animation is started
|
||||
|[onDone](objects/Animation/onDone.md)|Gets called as soon as the animation has finished
|
||||
|
||||
30
docs/objects/Animation/addMode.md
Normal file
30
docs/objects/Animation/addMode.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## addMode
|
||||
Adds a new easing curve into the available easing list. Checkout the animation object if you want to know how this works.
|
||||
|
||||
#### Parameters:
|
||||
|
||||
1. `string` - The name of the curve you want to use.
|
||||
2. `functon` - The function to call
|
||||
|
||||
#### Returns:
|
||||
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
|
||||
* Creates a new curve
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton)
|
||||
|
||||
local function easeInBack(t) -- t is the time from 0 to 1
|
||||
local c1 = 1.70158;
|
||||
local c3 = c1 + 1
|
||||
return c3*t^3-c1*t^2
|
||||
end
|
||||
|
||||
aAnimation:addMode("coolEaseInBack", easeInBack)
|
||||
aAnimation:setMode("coolEaseInBack"):move(15,3,2):play()
|
||||
```
|
||||
@@ -2,9 +2,9 @@
|
||||
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)
|
||||
1. `number` duration in seconds
|
||||
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
|
||||
3. `...` multiple color numbers - example: colors.red, colors.yellow, colors.green
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
@@ -3,8 +3,10 @@ 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)
|
||||
1. `number` duration in seconds
|
||||
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
|
||||
3. `...` multiple text strings - example: "i", "am", "groot"
|
||||
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
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)
|
||||
1. `number` duration in seconds
|
||||
2. `number` time - time when this part should begin (offset to when the animation starts - default 0)
|
||||
1. `...` multiple color numbers - example: colors.red, colors.yellow, colors.green
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
16
docs/objects/Animation/onStart.md
Normal file
16
docs/objects/Animation/onStart.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## onStart
|
||||
`onStart(self)`<br>
|
||||
This is a event which gets fired as soon as the animation is started.
|
||||
|
||||
```lua
|
||||
local basalt = require("Basalt")
|
||||
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):changeTextColor({colors.red, colors.yellow, colors.green}, 2)
|
||||
aAnimation:onStart(function()
|
||||
basalt.debug("The animation is started")
|
||||
end)
|
||||
|
||||
aAnimation:play()
|
||||
```
|
||||
36
docs/objects/Animation/setMode.md
Normal file
36
docs/objects/Animation/setMode.md
Normal file
@@ -0,0 +1,36 @@
|
||||
## setMode
|
||||
Changes the easing curve. If you want to test them, here is a interesting website: https://easings.co
|
||||
|
||||
#### Parameters:
|
||||
1. `string` - The name of the curve you want to use.
|
||||
|
||||
#### Returns:
|
||||
1. `animation` Animation in use
|
||||
|
||||
#### Usage:
|
||||
* Takes 2 seconds to move the object from its current position to x15 y3
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local testButton = mainFrame:addButton("buttonToAnimate")
|
||||
local aAnimation = mainFrame:addAnimation():setObject(testButton):setMode("easeInBounce"):move(15,3,2):play()
|
||||
```
|
||||
|
||||
## Easing Curve List
|
||||
|
||||
Here is a list of all available easing curves:
|
||||
|
||||
| | | |
|
||||
|---|---|---|
|
||||
|linear||
|
||||
|easIn|easeOut|easeInOut
|
||||
|easeInSine|easeOutSine|easeInOutSine
|
||||
|easeInBack|easeOutBack|easeInOutBack
|
||||
|easeInCubic|easeOutCubic|easeInOutCubic
|
||||
|easeInElastic|easeOutElastic|easeInOutElastic
|
||||
|easeInExpo|easeOutExpo|easeInOutExpo
|
||||
|easeInBack|easeOutBack|easeInOutBack
|
||||
|easeInQuad|easeOutQuad|easeInOutQuad
|
||||
|easeInQuint|easeOutQuint|easeInOutQuint
|
||||
|easeInQuart|easeOutQuart|easeInOutQuart
|
||||
|easeInCirc|easeOutCirc|easeInOutCirc
|
||||
|easeInBounce|easeOutBounce|easeInOutBounce
|
||||
@@ -1,37 +1,48 @@
|
||||
# Basalt
|
||||
|
||||
This is the UI Manager and the first thing you want to access.
|
||||
Before you can access Basalt, you need to add the following code on top of your file:
|
||||
|
||||
`local basalt = require("basalt")`
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
```
|
||||
|
||||
require loads the UI Framework into your project.
|
||||
|
||||
Now you are able to access the following list of methods:
|
||||
What this code does is it loads basalt into the basalt variable.
|
||||
You are now able to access the following list of methods:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|[autoUpdate](objects/Basalt/autoUpdate.md)|Starts the event and draw listener
|
||||
|[createFrame](objects/Basalt/createFrame.md)|Creates a new base frame
|
||||
|[removeFrame](objects/Basalt/removeFrame.md)|Removes a previously created base frame
|
||||
|[debug](objects/Basalt/debug.md)|Writes something into the debug console
|
||||
|[getFrame](objects/Basalt/getFrame.md)|Returns a frame object by it's id
|
||||
|[getActiveFrame](objects/Basalt/getActiveFrame.md)|Returns the currently active base frame
|
||||
|[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
|
||||
|[getTheme](objects/Basalt/getTheme.md)|Returns the currently active theme
|
||||
|[getVariable](objects/Basalt/getVariable.md)|Returns a variable defined with setVariable
|
||||
|[getVersion](objects/Basalt/getVersion.md)|Returns the Basalt version
|
||||
|[isKeyDown](objects/Basalt/isKeyDown.md)|Returns if the key is held down
|
||||
|[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
|
||||
|[onEvent](objects/Basalt/onEvent.md)|Event listener
|
||||
|[removeFrame](objects/Basalt/removeFrame.md)|Removes a previously created base frame
|
||||
|[schedule](objects/Basalt/schedule.md)|Schedules a new task
|
||||
|[setActiveFrame](objects/Basalt/setActiveFrame.md)|Sets the active frame
|
||||
|[setTheme](objects/Basalt/setTheme.md)|Changes the base theme of basalt
|
||||
|[setMouseDragThrottle](objects/Basalt/setMouseDragThrottle.md)|Changes the mouse drag throttle amount
|
||||
|[setMouseMoveThrottle](objects/Basalt/setMouseMoveThrottle.md)|CraftOS-PC: Changes the mouse move throttle amount
|
||||
|[setVariable](objects/Basalt/setVariable.md)|Sets a variable which you can access via XML
|
||||
|[stopUpdate / stop](objects/Basalt/stopUpdate.md)|Stops the currently active event and draw listener
|
||||
|[update](objects/Basalt/update.md)|Starts the event and draw listener once
|
||||
|
||||
# Examples
|
||||
## Examples
|
||||
|
||||
Here is a lua example on how to create a empty base frame and start basalt's listener.
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") -- we load the UI Framework into our project
|
||||
local basalt = require("basalt") -- Loads Basalt into our project
|
||||
|
||||
local main = basalt.createFrame() -- we create a base frame - on that frame we are able to add object's
|
||||
local main = basalt.createFrame() -- Creates a base frame. On that frame we are able to add object's
|
||||
|
||||
-- here we would add additional object's
|
||||
-- Here we would add additional object's
|
||||
|
||||
basalt.autoUpdate() -- we start listening to incoming events and draw stuff on the screen
|
||||
```
|
||||
basalt.autoUpdate() -- Starts listening to incoming events and draw stuff on the screen. This should nearly always be the last line.
|
||||
```
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
## basalt.autoUpdate
|
||||
# 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.
|
||||
### Parameters
|
||||
|
||||
1. `boolean` optional - if you use false as the first parameter it would stop the listeners. Using false is a synonym for [`basalt.stopUpdate()`](objects/Basalt/stopUpdate.md).
|
||||
|
||||
### Usage
|
||||
|
||||
* Enables the basalt listeners, otherwise the screen will not continue to update
|
||||
|
||||
#### Usage:
|
||||
* Enable the basalt listeners, otherwise the screen will not continue to update
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
## basalt.createFrame
|
||||
# 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:
|
||||
### Parameters
|
||||
|
||||
1. `string` id - optional (if you dont set a id it will automatically create a uuid for you)
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `frame` object
|
||||
|
||||
#### Usage:
|
||||
### Usage
|
||||
|
||||
* How to use multiple base frames:
|
||||
|
||||
```lua
|
||||
local main1 = basalt.createFrame() -- Visible base frame on program start
|
||||
local main2 = basalt.createFrame()
|
||||
@@ -24,4 +31,5 @@ main1:addButton()
|
||||
end)
|
||||
main2:addLabel()
|
||||
:setText("We are currently on main2")
|
||||
```
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
## basalt.debug
|
||||
# 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
|
||||
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.
|
||||
`basalt.debugFrame` and `basalt.debugList` are also available.
|
||||
|
||||
### Parameters
|
||||
|
||||
#### Parameters:
|
||||
1. `...` (multiple parameters are possible, like print does)
|
||||
|
||||
#### Usage:
|
||||
### 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!")
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
## basalt.getActiveFrame
|
||||
Returns the currently active/visible base frame
|
||||
# Basalt
|
||||
|
||||
## getActiveFrame
|
||||
|
||||
Returns the currently active/visible base frame.
|
||||
|
||||
### Returns
|
||||
|
||||
#### Returns:
|
||||
1. `frame` The current frame
|
||||
|
||||
#### Usage:
|
||||
### Usage
|
||||
|
||||
* Displays the active frame name in the debug console
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
basalt.debug(basalt.getActiveFrame():getName()) -- returns the id
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
## basalt.getFrame
|
||||
Returns a base frame by the given id
|
||||
# Basalt
|
||||
|
||||
## getFrame
|
||||
|
||||
Returns a base frame by the given id.
|
||||
|
||||
### Parameters
|
||||
|
||||
#### Parameters:
|
||||
1. `string` id
|
||||
|
||||
#### Returns:
|
||||
1. `frame` object
|
||||
### Returns
|
||||
|
||||
1. `frame` The frame with the supplied id.
|
||||
|
||||
### Usage
|
||||
|
||||
#### Usage:
|
||||
* Creates, fetches and shows the "myFirstFrame" object
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame("firstBaseFrame")
|
||||
local main2 = basalt.createFrame("secondBaseFrame")
|
||||
@@ -16,8 +23,9 @@ main:addButton()
|
||||
:setText("Show")
|
||||
:onClick(function()
|
||||
local frame2 = basalt.getFrame("secondBaseFrame")
|
||||
if(frame2~=nil)then
|
||||
if(frame2 ~= nil)then
|
||||
frame2:show()
|
||||
end
|
||||
end)
|
||||
```
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
18
docs/objects/Basalt/getTheme.md
Normal file
18
docs/objects/Basalt/getTheme.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Basalt
|
||||
|
||||
## basalt.getTheme
|
||||
|
||||
Returns the current base-theme. This base-theme can be set using setTheme.md.
|
||||
A list of base-theme keys can be found [here](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua).
|
||||
|
||||
### Returns
|
||||
|
||||
1. `number` The color of the requested base-theme key.
|
||||
|
||||
### Usage
|
||||
|
||||
* Displays the color of the main background in the debug console
|
||||
|
||||
```lua
|
||||
basalt.debug(basalt.getTheme("BasaltBG"))
|
||||
```
|
||||
26
docs/objects/Basalt/getVariable.md
Normal file
26
docs/objects/Basalt/getVariable.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Basalt
|
||||
|
||||
## getVariable
|
||||
|
||||
Returns a variable defined with [setVariable](objects/Basalt/setVariable)
|
||||
|
||||
### Returns
|
||||
|
||||
1. `variable` The variable stored
|
||||
|
||||
### Usage
|
||||
|
||||
* Displays the stored variable in the debug console
|
||||
|
||||
```lua
|
||||
basalt.setVariable("abc", function()
|
||||
basalt.debug("I got clicked")
|
||||
return 1
|
||||
end)
|
||||
|
||||
basalt.debug(basalt.getVariable("abc")()) -- Should debug log "I got clicked" and debug log 1 (which was returned from the function)
|
||||
```
|
||||
|
||||
```xml
|
||||
<button onClick="abc" text="Click me" />
|
||||
```
|
||||
17
docs/objects/Basalt/getVersion.md
Normal file
17
docs/objects/Basalt/getVersion.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Basalt
|
||||
|
||||
## getVersion
|
||||
|
||||
Returns the currently active/visible base frame.
|
||||
|
||||
### Returns
|
||||
|
||||
1. `string` The current version of Basalt
|
||||
|
||||
### Usage
|
||||
|
||||
* Displays the version of Basalt in the debug console
|
||||
|
||||
```lua
|
||||
basalt.debug(basalt.getVersion()) -- Example: 1.6.2
|
||||
```
|
||||
@@ -1,14 +1,21 @@
|
||||
## basalt.isKeyDown
|
||||
# Basalt
|
||||
|
||||
## isKeyDown
|
||||
|
||||
Checks if the user is currently holding a key
|
||||
|
||||
#### Parameters:
|
||||
1. `number` key code (use the keys table for that)
|
||||
### Parameters
|
||||
|
||||
1. `number` key code (use the [keys table](https://tweaked.cc/module/keys.html) for that)
|
||||
|
||||
### Returns
|
||||
|
||||
#### Returns:
|
||||
1. `boolean` true or false
|
||||
|
||||
#### Usage:
|
||||
### 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()
|
||||
@@ -18,4 +25,4 @@ local aButton = mainFrame:addButton()
|
||||
basalt.debug(basalt.isKeyDown(keys.leftCtrl))
|
||||
end)
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
## basalt.log
|
||||
This writes something into a file. The main goal is to make debugging errors easier. Lets say you'r program is crashing and
|
||||
you don't know why, you could use basalt.log
|
||||
# Basalt
|
||||
|
||||
The log files will automatically removed after you start your program again
|
||||
## 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
|
||||
|
||||
#### Parameters:
|
||||
1. `string` The text to write into the log file
|
||||
2. `string` - optional (default: "Debug") - the type to write
|
||||
|
||||
#### Usage:
|
||||
### Usage
|
||||
|
||||
* Writes "Hello!" into the log file
|
||||
|
||||
```lua
|
||||
basalt.log("Hello!")
|
||||
```
|
||||
|
||||
This should result in there beeing a file called `basaltLog.txt`. In the file it should say `[Basalt][Debug]: Hello!`.
|
||||
|
||||
* Writes "Config file missing" into the log file, with warning as prefix.
|
||||
|
||||
```lua
|
||||
basalt.log("Config file is missing", "WARNING")
|
||||
```
|
||||
|
||||
This should result in there beeing a file called `basaltLog.txt`. In the file it should say `[Basalt][WARNING]: Config file is missing`.
|
||||
|
||||
21
docs/objects/Basalt/onEvent.md
Normal file
21
docs/objects/Basalt/onEvent.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Basalt
|
||||
|
||||
## onEvent
|
||||
|
||||
This is the top-level method to intercept an event before sending it to the object event handlers. If you use return false, the event is not passed to the event handlers.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `function` The function which should be called
|
||||
|
||||
### Usage
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
basalt.onEvent(function(event)
|
||||
if(event=="terminate")then
|
||||
return false
|
||||
end
|
||||
end)
|
||||
```
|
||||
@@ -1,17 +1,37 @@
|
||||
## basalt.removeFrame
|
||||
Removes the base frame by it's id. This only works for base-frames.
|
||||
# Basalt
|
||||
|
||||
#### Parameters:
|
||||
1. `string` id
|
||||
## removeFrame
|
||||
|
||||
Removes the base frame by it's id. **This only works for base-frames.**
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `string` id - ID of the base-frame.
|
||||
|
||||
### Usage
|
||||
|
||||
* Removes the previously created frame with id "secondBaseFrame"
|
||||
The frame id is gotten from a frame variable's `:getName()`
|
||||
|
||||
#### 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"
|
||||
basalt.removeFrame(main2:getName())
|
||||
end)
|
||||
```
|
||||
```
|
||||
|
||||
* Removes the previously created frame with id "secondBaseFrame", without frame stored in variable
|
||||
The frame id is the frame's name
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame("firstBaseFrame")
|
||||
local main2 = basalt.createFrame("secondBaseFrame")
|
||||
main:addButton()
|
||||
:setText("Remove")
|
||||
:onClick(function()
|
||||
basalt.removeFrame("secondBaseFrame")
|
||||
end)
|
||||
```
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
## 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.
|
||||
# Basalt
|
||||
|
||||
## schedule
|
||||
|
||||
Schedules a function which gets called in a coroutine. After the coroutine is finished it will get destroyed immediatly. It's something like threads, but with some limits.
|
||||
**A guide can be found [here](/tips/logic).**
|
||||
|
||||
### Parameters
|
||||
|
||||
#### Parameters:
|
||||
1. `function` a function which should get executed
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `function` it returns the function which you have to execute in order to start the coroutine
|
||||
|
||||
#### Usage:
|
||||
### Usage
|
||||
|
||||
* Creates a schedule which switches the color between red and gray
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aButton = mainFrame:addButton():setText("Click me")
|
||||
@@ -25,4 +33,4 @@ aButton:onClick(basalt.schedule(function(self)
|
||||
os.sleep(0.1)
|
||||
self:setBackground(colors.gray)
|
||||
end))
|
||||
```
|
||||
```
|
||||
|
||||
13
docs/objects/Basalt/setActiveFrame.md
Normal file
13
docs/objects/Basalt/setActiveFrame.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Basalt
|
||||
|
||||
## setActiveFrame
|
||||
|
||||
Sets what should be the active baseframe.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `frame` frame - The frame that should be the active base-frame.
|
||||
|
||||
### Usage
|
||||
|
||||
TODO
|
||||
18
docs/objects/Basalt/setMouseDragThrottle.md
Normal file
18
docs/objects/Basalt/setMouseDragThrottle.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Basalt
|
||||
|
||||
## setMouseDragThrottle
|
||||
|
||||
Changes the drag throttle of all drag events. Default value is 50ms - which is 0.05s.
|
||||
Instead of sending all mouse_drag events to the :onDrag handlers basalt sends every 0.05s (while dragging) the most recent drag event to all
|
||||
drag handlers. If you need all drag events - just change the value to 0.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `number` A number in miliseconds.
|
||||
|
||||
### Usage
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
basalt.setMouseDragThrottle(0)
|
||||
```
|
||||
20
docs/objects/Basalt/setMouseMoveThrottle.md
Normal file
20
docs/objects/Basalt/setMouseMoveThrottle.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Basalt
|
||||
|
||||
## setMouseMoveThrottle
|
||||
|
||||
This feature is only available for [CraftOS-PC](https://www.craftos-pc.cc).
|
||||
|
||||
CraftOS-PC has a builtin mouse_move event, which is disabled by default. By using this method it will also enable the event for you. Remember - basalt does not disable the event after closing the program, which means the event stays active. If you want to disable the event please use config.set("mouse_move_throttle", -1) in your lua prompt or your program.
|
||||
|
||||
Sidenote: a very low amount can make the program laggy - because it litterally spams the mouse_move event. So use it carefully.
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `number` A number in miliseconds.
|
||||
|
||||
### Usage
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
basalt.setMouseMoveThrottle(50)
|
||||
```
|
||||
@@ -1,15 +1,21 @@
|
||||
## basalt.setTheme
|
||||
Sets the base theme of the project! Make sure to cover all existing objects, otherwise it will result in errors. A good example is [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua)
|
||||
# Basalt
|
||||
|
||||
## setTheme
|
||||
|
||||
Sets the base theme of the project! Make sure to cover all existing objects, otherwise it will result in errors. A good example is [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua). The theme can also be gotten with [`basalt.getTheme()`](objects/Basalt/getTheme)
|
||||
|
||||
### Parameters
|
||||
|
||||
#### Parameters:
|
||||
1. `table` theme layout look into [theme](https://github.com/Pyroxenium/Basalt/blob/master/Basalt/theme.lua) for a example
|
||||
|
||||
#### Usage:
|
||||
### Usage
|
||||
|
||||
* Sets the default theme of basalt.
|
||||
|
||||
```lua
|
||||
basalt.setTheme({
|
||||
ButtonBG = colors.yellow,
|
||||
ButtonText = colors.red,
|
||||
...,
|
||||
})
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
## basalt.setVariable
|
||||
# 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
|
||||
### Parameters
|
||||
|
||||
1. `string` a key name
|
||||
2. `any` any variable
|
||||
|
||||
### Usage
|
||||
|
||||
#### Usage:
|
||||
* Adds a function to basalt.
|
||||
|
||||
```lua
|
||||
basalt.setVariable("clickMe", function()
|
||||
basalt.debug("I got clicked")
|
||||
end)
|
||||
|
||||
```
|
||||
|
||||
```xml
|
||||
<button onClick="clickMe" text="Click me" />
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
## basalt.stopUpdate or basalt.stop
|
||||
Stops the automatic draw and event handler which got started by basalt.autoUpdate()
|
||||
# Basalt
|
||||
|
||||
## stopUpdate / stop
|
||||
|
||||
Stops the automatic draw and event handler which got started by `basalt.autoUpdate()`.
|
||||
`basalt.autoUpdate(false)` also does the same.
|
||||
|
||||
### Usage
|
||||
|
||||
#### 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()
|
||||
main:addButton()
|
||||
:setPosition(2,2)
|
||||
:setText("Stop Basalt!")
|
||||
:onClick(function()
|
||||
basalt.stopUpdate()
|
||||
end)
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,18 +1,24 @@
|
||||
## basalt.update
|
||||
# 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
|
||||
### Parameters
|
||||
|
||||
1. `string` The event to be received
|
||||
2. `...` Additional event variables to capture
|
||||
|
||||
#### Usage:
|
||||
### Usage
|
||||
|
||||
* Creates and starts a custom update cycle
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aButton = mainFrame:addButton():setPosition(2,2)
|
||||
mainFrame:addButton():setPosition(2,2)
|
||||
while true do
|
||||
local ev = table.pack(os.pullEventRaw())
|
||||
basalt.update(table.unpack(ev))
|
||||
end
|
||||
```
|
||||
```
|
||||
|
||||
@@ -28,6 +28,7 @@ some special functionality to create very advanced programs.
|
||||
|[setScrollAmount](objects/Frame/setScrollAmount.md)|Sets how far the user is allowed to scroll
|
||||
|
||||
This is how you would implement frames via xml:
|
||||
|
||||
```xml
|
||||
<frame>
|
||||
<frame width="parent.w * 0.5" bg="red">
|
||||
@@ -37,4 +38,297 @@ This is how you would implement frames via xml:
|
||||
<textfield bg="green" x="2" width="parent.w-2" />
|
||||
</frame>
|
||||
</frame>
|
||||
```
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
Here are some examples on how you can use frames to create very advanced programs. Because of the screen size limitation of CC:Tweaked frames can become very useful in almost every scenario. You will find some examples here on how you could implement them.
|
||||
|
||||
### Menubar for switching frames
|
||||
|
||||
This is a example on how you can create a menubar which switches your frames (without animation).
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") -- we need basalt here
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black}) -- we change the default bg and fg color for frames
|
||||
|
||||
local sub = { -- here we create a table where we gonna add some frames
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"), -- obviously the first one should be shown on program start
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"):hide(),
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"):hide(),
|
||||
}
|
||||
|
||||
local function openSubFrame(id) -- we create a function which switches the frame for us
|
||||
if(sub[id]~=nil)then
|
||||
for k,v in pairs(sub)do
|
||||
v:hide()
|
||||
end
|
||||
sub[id]:show()
|
||||
end
|
||||
end
|
||||
|
||||
local menubar = main:addMenubar():setScrollable() -- we create a menubar in our main frame.
|
||||
:setSize("parent.w")
|
||||
:onChange(function(self, val)
|
||||
openSubFrame(self:getItemIndex()) -- here we open the sub frame based on the table index
|
||||
end)
|
||||
:addItem("Example 1")
|
||||
:addItem("Example 2")
|
||||
:addItem("Example 3")
|
||||
|
||||
-- Now we can change our sub frames, if you want to access a sub frame just use sub[subid], some examples:
|
||||
sub[1]:addButton():setPosition(2, 2)
|
||||
|
||||
sub[2]:addLabel():setText("Hello World!"):setPosition(2, 2)
|
||||
|
||||
sub[3]:addLabel():setText("Now we're on example 3!"):setPosition(2, 2)
|
||||
sub[3]:addButton():setText("No functionality"):setPosition(2, 4):setSize(18, 3)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/frames-with-menubars.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Sidebar with buttons to switch frames
|
||||
|
||||
Here we will find out how to create a sidebar (which are also just frames) - the sidebar should have buttons to opens the frames for us.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") -- we need basalt here
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black})
|
||||
|
||||
--[[
|
||||
Here we create the sidebar, on focus it should change the position to parent.w - (self.w-1) which "opens the frame"
|
||||
when the focus gets lost we simply change the position to "parent.w"
|
||||
As you can see we add :setZIndex(25) - this makes sure the sidebar frame is always more important than our normal sub frames.
|
||||
:setScrollable just makes the sidebar frame scrollable (in case you're adding more frames)
|
||||
]]
|
||||
local sidebar = main:addFrame():setBackground(colors.gray):setPosition("parent.w", 1):setSize(15, "parent.h"):setZIndex(25):setScrollable()
|
||||
:onGetFocus(function(self)
|
||||
self:setPosition("parent.w - (self.w-1)")
|
||||
end)
|
||||
:onLoseFocus(function(self)
|
||||
self:setPosition("parent.w")
|
||||
end)
|
||||
|
||||
-- Once again we add 3 frames, the first one should be immediatly visible
|
||||
local sub = {
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"),
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"):hide(),
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"):hide(),
|
||||
}
|
||||
|
||||
--This part of the code adds buttons based on the sub table.
|
||||
local y = 2
|
||||
for k,v in pairs(sub)do
|
||||
sidebar:addButton():setText("Example "..k) -- creating the button and adding a name k is just the index
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.lightGray)
|
||||
:setSize("parent.w - 2", 3)
|
||||
:setPosition(2, y)
|
||||
:onClick(function() -- here we create a on click event which hides ALL sub frames and then shows the one which is linked to the button
|
||||
for a, b in pairs(sub)do
|
||||
b:hide()
|
||||
v:show()
|
||||
end
|
||||
end)
|
||||
y = y + 4
|
||||
end
|
||||
|
||||
sub[1]:addButton():setPosition(2, 2)
|
||||
|
||||
sub[2]:addLabel():setText("Hello World!"):setPosition(2, 2)
|
||||
|
||||
sub[3]:addLabel():setText("Now we're on example 3!"):setPosition(2, 2)
|
||||
sub[3]:addButton():setText("No functionality"):setPosition(2, 4):setSize(18, 3)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/frames-with-sidebar.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Movable frames with a program object
|
||||
|
||||
In this example you will see how you can add movable frames with a program object in it. It also shows you how you dynamically add new frames.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black})
|
||||
|
||||
local id = 1
|
||||
local processes = {}
|
||||
|
||||
local function openProgram(path, title, x, y, w, h)
|
||||
local pId = id
|
||||
id = id + 1
|
||||
local f = main:addFrame()
|
||||
:setMovable()
|
||||
:setSize(w or 30, h or 12)
|
||||
:setPosition(x or math.random(2, 12), y or math.random(2, 8))
|
||||
|
||||
f:addLabel()
|
||||
:setSize("parent.w", 1)
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.lightGray)
|
||||
:setText(title or "New Program")
|
||||
|
||||
f:addProgram()
|
||||
:setSize("parent.w", "parent.h - 1")
|
||||
:setPosition(1, 2)
|
||||
:execute(path or "rom/programs/shell.lua")
|
||||
|
||||
f:addButton()
|
||||
:setSize(1, 1)
|
||||
:setText("X")
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.red)
|
||||
:setPosition("parent.w", 1)
|
||||
:onClick(function()
|
||||
f:remove()
|
||||
processes[pId] = nil
|
||||
end)
|
||||
processes[pId] = f
|
||||
return f
|
||||
end
|
||||
|
||||
openProgram("rom/programs/fun/worm.lua")
|
||||
|
||||
main:addButton():setPosition("parent.w - 16", 2):setText("Open"):onClick(function()
|
||||
openProgram()
|
||||
end)
|
||||
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/dynamic-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
|
||||
### Resizable frames
|
||||
|
||||
If you want to make your frames resizeable, there is no way offered by basalt - so you would have to do it yourself. However such a implementation is very simple as you can see here.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.black, FrameFG = colors.lightGray})
|
||||
|
||||
local sub = main:addFrame():setSize(25, 12):setPosition(3, 3)
|
||||
|
||||
local function makeResizeable(frame, minW, minH, maxW, maxH)
|
||||
minW = minW or 4
|
||||
minH = minH or 4
|
||||
maxW = maxW or 99
|
||||
maxH = maxH or 99
|
||||
local btn = frame:addButton()
|
||||
:setPosition("parent.w", "parent.h")
|
||||
:setSize(1, 1)
|
||||
:setText("/")
|
||||
:setForeground(colors.blue)
|
||||
:setBackground(colors.black)
|
||||
:onDrag(function(self, event, btn, xOffset, yOffset)
|
||||
local w, h = frame:getSize()
|
||||
local wOff, hOff = w, h
|
||||
if(w+xOffset-1>=minW)and(w+xOffset-1<=maxW)then
|
||||
wOff = w+xOffset-1
|
||||
end
|
||||
if(h+yOffset-1>=minH)and(h+yOffset-1<=maxH)then
|
||||
hOff = h+yOffset-1
|
||||
end
|
||||
frame:setSize(wOff, hOff)
|
||||
end)
|
||||
end
|
||||
|
||||
makeResizeable(sub, 8, 4)
|
||||
|
||||
sub:addLabel():setText("Hello World")
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/resizable-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Scrollable frames
|
||||
|
||||
Another important feature of frames is the possibility to make them scrollable. Basalt only provides vertical scrolling for frames. If you want to make horizontal scrolling possible, you need to do it yourself. Also, if you're using :setScrollable() the amount to scroll is based on the object's y-position + height - you can change this by using :setScrollAmount(amount). Only count's for the basalt implementation of scrollable frames.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.black, FrameFG = colors.lightGray})
|
||||
|
||||
-- Vertical scrolling is pretty simple, as you can tell:
|
||||
local sub1 = main:addFrame():setScrollable():setSize(20, 15):setPosition(2, 2)
|
||||
|
||||
sub1:addLabel():setPosition(3, 2):setText("Scrollable")
|
||||
sub1:addLabel():setPosition(3, 12):setText("Inside")
|
||||
sub1:addLabel():setPosition(3, 20):setText("Outside")
|
||||
|
||||
-- Here we create a custom scroll event as you can see we dont add a :setScrollable() method to our frame, instead we add a custom scroll event
|
||||
local objects = {}
|
||||
|
||||
local sub2 = main:addFrame():setPosition(23, 2):setSize(25, 5):onScroll(function(self, event, dir)
|
||||
local maxScroll = 0
|
||||
for k,v in pairs(objects)do -- here we iterate trough every object and get their x position + width this way we can find out what's the maximum allowed value to scroll
|
||||
local x = v:getX()
|
||||
local w = v:getWidth()
|
||||
maxScroll = x + w > maxScroll and x + w or maxScroll -- if you don't understand this line, http://lua-users.org/wiki/TernaryOperator
|
||||
end
|
||||
local xOffset = self:getOffset()
|
||||
if(xOffset+dir>=0 and xOffset+dir<=maxScroll-self:getWidth())then
|
||||
self:setOffset(xOffset+dir, 0)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Because we need to iterate the objects, we add them into a table.
|
||||
table.insert(objects, sub2:addButton():setPosition(2, 2):setText("Scrollable"))
|
||||
table.insert(objects, sub2:addButton():setPosition(16, 2):setText("Inside"))
|
||||
table.insert(objects, sub2:addButton():setPosition(30, 2):setText("Outside"))
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/scrollable-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
This is the base class for all visual objects. It covers positioning, sizing, showing/hiding and much more.
|
||||
|
||||
By default a freshly created object is visible and automatically listens to all incoming events.
|
||||
By default a freshly created object is visible and doesn't listens to any incoming events.
|
||||
Its default position is always 1, 1 (based on it's parent frame). The default anchor is also topLeft.
|
||||
|
||||
| | |
|
||||
@@ -10,6 +10,7 @@ Its default position is always 1, 1 (based on it's parent frame). The default an
|
||||
|[isVisible](objects/Object/isVisible.md)|Returns if the object is currently visible
|
||||
|[enable](objects/Object/enable.md)|Listens to incoming events
|
||||
|[disable](objects/Object/disable.md)|Ignores all incoming events
|
||||
|[remove](objects/Object/remove.md)|Removes the children object from it's parent object
|
||||
|[setPosition](objects/Object/setPosition.md)|Changes the position (x,y)
|
||||
|[getPosition](objects/Object/getPosition.md)|Returns the current position
|
||||
|[setBackground](objects/Object/setBackground.md)|Changes the object's background
|
||||
@@ -31,16 +32,42 @@ Its default position is always 1, 1 (based on it's parent frame). The default an
|
||||
|
||||
# Events
|
||||
|
||||
This is a list of all available events for all objects:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
|[onClick](objects/Object/onClick.md)|Fires as soon as the object gets clicked
|
||||
|[onClickUp](objects/Object/onClickUp.md)|Fires as soon as the mouse button gets released on the object
|
||||
|[onScroll](objects/Object/onScroll.md)|Fires as soon as you scroll with the mousewheel
|
||||
|[onRelease](objects/Object/onRelease.md)|Fires as soon as the mouse button gets released
|
||||
|[onScroll](objects/Object/onScroll.md)|Fires as soon as you scroll with the mousewheel
|
||||
|[onDrag](objects/Object/onDrag.md)|Fires as soon as the object is beeing dragged
|
||||
|[onHover](objects/Object/onHover.md)|CraftOS-PC - fires when the mouse hovers over a object
|
||||
|[onLeave](objects/Object/onLeave.md)|CraftOS-PC - fires when the mouse leaves a object
|
||||
|[onKey](objects/Object/onKey.md)|Fires when the object is focused and a keyboard key has been clicked
|
||||
|[onChar](objects/Object/onChar.md)|Fires when the object is focused and a character has been clicked
|
||||
|[onKeyUp](objects/Object/onKeyUp.md)|Fires when the object is focused and a keyboard key has been released
|
||||
|[onChange](objects/Object/onChange.md)|Fires when the object value has been changed
|
||||
|[onResize](objects/Object/onResize.md)|Fires when the object got resized
|
||||
|[onReposition](objects/Object/onReposition.md)|Fires when the object has been repositioned
|
||||
|[onGetFocus](objects/Object/onGetFocus.md)|Fires when the object is focused
|
||||
|[onLoseFocus](objects/Object/onLoseFocus.md)|Fires when the object lost it's focus
|
||||
|[onLoseFocus](objects/Object/onLoseFocus.md)|Fires when the object lost it's focus
|
||||
|[onEvent](objects/Object/onEvent.md)|Fires on any other event
|
||||
|
||||
Sidenote: When you use return false this will skip the object's event handler. Here is a example for that.
|
||||
|
||||
This code would make it impossible to write a into the input:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
local input = main:addInput()
|
||||
:setPosition(3,3)
|
||||
|
||||
function checkInput(self, event, char)
|
||||
if(char=="a")then
|
||||
return false
|
||||
end
|
||||
end
|
||||
main:onChar(checkInput)
|
||||
```
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
# Object
|
||||
|
||||
## disable
|
||||
|
||||
Disables the object's event listeners
|
||||
|
||||
This will disable the object. Which means it doesn't listen to any events anymore.
|
||||
This will disable the object. Which means it doesn't listen to any events anymore.
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
# Object
|
||||
|
||||
## enable
|
||||
|
||||
Enables the object's event listeners
|
||||
|
||||
If the object's is disabled, it will stop listening to incoming events, this will reenable it.
|
||||
If the object's is disabled, it will stop listening to incoming events, this will reenable it.
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
# Object
|
||||
|
||||
## getAbsolutePosition
|
||||
|
||||
Converts the relative coordinates into absolute coordinates
|
||||
#### Parameters:
|
||||
|
||||
### Parameters
|
||||
|
||||
1. `number|nil` x
|
||||
2. `number|nil` y
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
#### Usage:
|
||||
### Usage
|
||||
|
||||
* Creates a frame and a button and prints the button's absolute position to the debug console
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame():setPosition(3,3)
|
||||
local aButton = mainFrame:addButton():setSize(8,1):setPosition(4,2)
|
||||
basalt.debug(aButton:getAbsolutePosition()) -- returns 7,5 (frame coords + own coords) instead of 4,2
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
# Object
|
||||
|
||||
## getAnchorPosition
|
||||
|
||||
Converts the x and y coordinates into the anchor coordinates of the object
|
||||
|
||||
#### Parameters:
|
||||
### Parameters
|
||||
|
||||
1. `number|nil` x
|
||||
2. `number|nil` y, if nothing it uses the object's x, y
|
||||
|
||||
#### Returns:
|
||||
#### Returns
|
||||
|
||||
1. `number` x
|
||||
2. `number` y
|
||||
|
||||
#### Usage:
|
||||
#### Usage
|
||||
|
||||
* Prints the anchor position to the debug console
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame():setSize(15,15)
|
||||
local aButton = mainFrame:addButton()
|
||||
@@ -18,4 +25,4 @@ local aButton = mainFrame:addButton()
|
||||
:setSize(8,1)
|
||||
:setPosition(1,1)
|
||||
basalt.debug(aButton:getAnchorPosition()) -- returns 7,14 (framesize - own size) instead of 1,1
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Object
|
||||
|
||||
## getBackground
|
||||
|
||||
Returns the current background color
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `number` color
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Object
|
||||
|
||||
## getForeground
|
||||
|
||||
Returns the current foreground color
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `number` color
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
# Object
|
||||
|
||||
## getName
|
||||
|
||||
Returns the given name of the object
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `string` name
|
||||
|
||||
#### Usage:
|
||||
#### Usage
|
||||
|
||||
* Prints name of object to debug window
|
||||
|
||||
```lua
|
||||
local main = basalt.createFrame()
|
||||
basalt.debug(main:getName()) -- returns the uuid
|
||||
@@ -14,4 +20,4 @@ basalt.debug(main:getName()) -- returns the uuid
|
||||
```lua
|
||||
local main = basalt.createFrame("myFirstMainFrame")
|
||||
basalt.debug(main:getName()) -- returns myFirstMainFrame
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Object
|
||||
|
||||
## getPosition
|
||||
|
||||
Returns the object's position
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `number` x
|
||||
2. `number` y
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Object
|
||||
|
||||
## getSize
|
||||
|
||||
Returns the object's size
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `number` w
|
||||
2. `number` h
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
# Object
|
||||
|
||||
## getValue
|
||||
|
||||
Returns the currently saved value
|
||||
#### Returns:
|
||||
|
||||
### Returns
|
||||
|
||||
1. `any` Object's value
|
||||
|
||||
#### Usage:
|
||||
### Usage
|
||||
|
||||
* Prints the value of the checkbox to the debug console
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aCheckbox = mainFrame:addCheckbox():setValue(true)
|
||||
basalt.debug(aCheckbox:getValue()) -- returns true
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
# Object
|
||||
|
||||
## hide
|
||||
|
||||
Hides the object
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `object` The object in use
|
||||
|
||||
#### Usage:
|
||||
#### Usage
|
||||
|
||||
* Hides a frame
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local button = mainFrame:addButton():setText("Close"):onClick(function() mainFrame:hide() end)
|
||||
```
|
||||
|
||||
```xml
|
||||
<button visible="false" />
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
# Object
|
||||
|
||||
## isFocused
|
||||
|
||||
Returns if the object is currently the focused object of the parent frame
|
||||
|
||||
#### Returns:
|
||||
### Returns
|
||||
|
||||
1. `boolean` Whether the object is focused
|
||||
|
||||
#### Usage:
|
||||
#### Usage
|
||||
|
||||
* Prints whether the button is focused to the debug console
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aButton = mainFrame:addButton()
|
||||
basalt.debug(aButton:isFocused()) -- shows true or false as a debug message
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
# Object
|
||||
|
||||
## isVisible
|
||||
|
||||
Returns if the object is currently visible
|
||||
#### Returns:
|
||||
|
||||
### Returns
|
||||
|
||||
1. `boolean`
|
||||
|
||||
#### Usage:
|
||||
#### Usage
|
||||
|
||||
* Prints boolean visibility of object to debug console
|
||||
|
||||
```lua
|
||||
local mainFrame = basalt.createFrame()
|
||||
local aButton = mainFrame:addButton():setSize(5,8)
|
||||
basalt.debug(aButton:isVisible()) -- returns true
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# onChange
|
||||
`onChange(self)`<br>
|
||||
# Object - Event
|
||||
|
||||
## onChange
|
||||
|
||||
`onChange(self)`
|
||||
|
||||
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:
|
||||
@@ -25,4 +29,4 @@ end
|
||||
|
||||
aInput:onChange(checkInput)
|
||||
aCheckbox:onChange(checkCheckbox)
|
||||
```
|
||||
```
|
||||
|
||||
28
docs/objects/Object/onChar.md
Normal file
28
docs/objects/Object/onChar.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Object - Event
|
||||
|
||||
## onChar
|
||||
|
||||
`onChar(self, event, char)`
|
||||
|
||||
The computercraft event which triggers this method is `char`.
|
||||
|
||||
The char event always happens after the key event (just like in cc:tweaked)
|
||||
|
||||
Here is a example on how to add a onChar event to your frame:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
local subFrame = main:addFrame()
|
||||
:setPosition(3,3)
|
||||
:setSize(18,6)
|
||||
:hide()
|
||||
|
||||
function openSubFrame(self, event, char)
|
||||
if(char=="a")then
|
||||
subFrame:show()
|
||||
end
|
||||
end
|
||||
main:onChar(openSubFrame)
|
||||
```
|
||||
@@ -1,5 +1,7 @@
|
||||
# onClick
|
||||
`onClick(self, event, button, x, y)`<br>
|
||||
|
||||
`onClick(self, event, button, x, y)`
|
||||
|
||||
The computercraft event which triggers this method is `mouse_click` and `monitor_touch`.
|
||||
|
||||
Here is a example on how to add a onClick event to your button:
|
||||
@@ -20,6 +22,7 @@ button:onClick(buttonOnClick)
|
||||
```
|
||||
|
||||
Here is also a example on how you could create double clicks:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
local doubleClickMaxTime = 0.25 -- in seconds
|
||||
@@ -44,4 +47,4 @@ end
|
||||
createDoubleClick(button, debugSomething) -- this is how you will create a double click.
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# onClickUp
|
||||
`onClickUp(self, event, button, x, y)`<br>
|
||||
# Object - Event
|
||||
|
||||
## onClickUp
|
||||
|
||||
`onClickUp(self, event, button, x, y)`
|
||||
|
||||
The computercraft event which triggers this method is `mouse_up`.
|
||||
|
||||
Here is a example on how to add a onClickUp event to your button:
|
||||
@@ -22,4 +26,4 @@ function buttonOnRelease(self, button, x, y)
|
||||
basalt.debug("Button got released!")
|
||||
end
|
||||
button:onClickUp(buttonOnRelease)
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
# onDrag
|
||||
`onDrag(self, event, button, x, y, xOffset, yOffset)`<br>
|
||||
# Object - Event
|
||||
|
||||
## onDrag
|
||||
|
||||
`onDrag(self, event, button, x, y, xOffset, yOffset)`
|
||||
|
||||
The computercraft event which triggers this method is `mouse_drag`.
|
||||
|
||||
This is a example on how you would create a movable button:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
@@ -21,6 +26,7 @@ basalt.autoUpdate()
|
||||
```
|
||||
|
||||
Another example on how you could change the frame's offset by dragging around.
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
@@ -43,6 +49,7 @@ basalt.autoUpdate()
|
||||
```
|
||||
|
||||
Also very interesting is a button where you are able to resize the frame just by dragging the button.
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
@@ -57,7 +64,7 @@ local dragButton = sub:addButton()
|
||||
:setSize(1,1)
|
||||
:setText("/")
|
||||
:onDrag(function(self, button, x, y, xOffset, yOffset)
|
||||
sub:setSize(-xOffset, -yOffset, true)
|
||||
sub:setSize(-xOffset, -yOffset, true)
|
||||
end)
|
||||
|
||||
basalt.autoUpdate()
|
||||
|
||||
22
docs/objects/Object/onEvent.md
Normal file
22
docs/objects/Object/onEvent.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Object - Event
|
||||
|
||||
## onEvent
|
||||
|
||||
`onEvent(self, event, ...)`
|
||||
|
||||
This event gets called on any other event. Some examples: http_success, disk, modem_message, paste, peripheral, redstone,...
|
||||
|
||||
You can find a full list here: [CC:Tweaked](https://tweaked.cc/) (on the left sidebar)
|
||||
|
||||
Here is a example on how to add a onEvent event to your frame:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
main:onEvent(function(event, side, channel, replyChannel, message, distance)
|
||||
if(event=="modem_message")then
|
||||
basalt.debug("Mesage received: "..tostring(message))
|
||||
end
|
||||
end)
|
||||
```
|
||||
@@ -1,5 +1,9 @@
|
||||
# onGetFocus
|
||||
`onGetFocus(self)`<br>
|
||||
# Object - Event
|
||||
|
||||
## onGetFocus
|
||||
|
||||
`onGetFocus(self)`
|
||||
|
||||
This event gets triggered as soon as the object is the currently focused object.
|
||||
|
||||
```lua
|
||||
|
||||
24
docs/objects/Object/onHover.md
Normal file
24
docs/objects/Object/onHover.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Object - Event
|
||||
|
||||
## onHover
|
||||
|
||||
`onHover(self, event, button, x, y)`
|
||||
|
||||
The computercraft event which triggers this method is `mouse_move` - only available in [CraftOS-PC](https://www.craftos-pc.cc).
|
||||
|
||||
Here is a example on how to add a onHover event to your button:
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame()
|
||||
local button = main:addButton()
|
||||
:setPosition(3,3)
|
||||
:setSize(12,3)
|
||||
:setText("Hover")
|
||||
|
||||
function buttonOnHover()
|
||||
basalt.debug("The mouse hovers over the button!")
|
||||
end
|
||||
button:onHover(buttonOnHover)
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user