diff --git a/Basalt/Frame.lua b/Basalt/Frame.lua index 6ba3875..c225374 100644 --- a/Basalt/Frame.lua +++ b/Basalt/Frame.lua @@ -3,6 +3,7 @@ local _OBJECTS = require("loadObjects") local BasaltDraw = require("basaltDraw") local utils = require("utils") local layout = require("layout") +local basaltMon = require("basaltMon") local uuid = utils.uuid local rpairs = utils.rpairs local xmlValue = utils.getValueFromXML @@ -27,6 +28,7 @@ return function(name, parent, pTerm, basalt) local monSide = "" local isMonitor = false + local isGroupedMonitor = false local monitorAttached = false local dragXOffset = 0 local dragYOffset = 0 @@ -138,7 +140,7 @@ return function(name, parent, pTerm, basalt) if (value == obj) then table.remove(events[a][c], key) if(self.parent~=nil)then - if(tableCount(events[event])<=0)then + if(tableCount(events[a])<=0)then self.parent:removeEvent(a, self) end end @@ -148,13 +150,23 @@ return function(name, parent, pTerm, basalt) end end - local function removeObject(obj) + local function removeObject(self, obj) for a, b in pairs(objects) do for key, value in pairs(b) do - if (value == obj) then - table.remove(objects[a], key) - removeEvents(object, obj) - return true; + if(type(obj)=="string")then + if (value:getName() == obj) then + table.remove(objects[a], key) + removeEvents(object, value) + self:updateDraw() + return true; + end + else + if (value == obj) then + table.remove(objects[a], key) + removeEvents(object, value) + self:updateDraw() + return true; + end end end end @@ -206,20 +218,22 @@ return function(name, parent, pTerm, basalt) end local function removeEvent(self, event, obj) - for a, b in pairs(events[event]) do - for key, value in pairs(b) do - if (value == obj) then - table.remove(events[event][a], key) - if(#events[event][a]<=0)then - events[event][a] = nil - if(self.parent~=nil)then - if(tableCount(events[event])<=0)then - activeEvents[event] = false - self.parent:removeEvent(event, self) + if(events[event]~=nil)then + for a, b in pairs(events[event]) do + for key, value in pairs(b) do + if (value == obj) then + table.remove(events[event][a], key) + if(#events[event][a]<=0)then + events[event][a] = nil + if(self.parent~=nil)then + if(tableCount(events[event])<=0)then + activeEvents[event] = false + self.parent:removeEvent(event, self) + end end end + return true; end - return true; end end end @@ -338,6 +352,7 @@ return function(name, parent, pTerm, basalt) end end + local function focusSystem(self) if(focusedObject~=focusedObjectCache)then if(focusedObject~=nil)then @@ -372,6 +387,7 @@ return function(name, parent, pTerm, basalt) setFocusedObject = function(self, obj) focusedObjectCache = obj + focusSystem(self) return self end; @@ -448,6 +464,7 @@ return function(name, parent, pTerm, basalt) removeFocusedObject = function(self) focusedObjectCache = nil + focusSystem(self) return self end; @@ -494,7 +511,7 @@ return function(name, parent, pTerm, basalt) end; setScrollable = function(self, scrollable) - isScrollable = scrollable and true or false + isScrollable = (scrollable or scrollable==nil) and true or false if(self.parent~=nil)then self.parent:addEvent("mouse_scroll", self) end @@ -510,15 +527,17 @@ return function(name, parent, pTerm, basalt) getScrollAmount = function(self) - return scrollAmount + return autoScroll and scrollAmount or calculateMaxScroll(self) end, show = function(self) base.show(self) if(self.parent==nil)then basalt.setActiveFrame(self) - if(isMonitor)then + if(isMonitor)and not(isGroupedMonitor)then basalt.setMonitorFrame(monSide, self) + elseif(isGroupedMonitor)then + basalt.setMonitorFrame(self:getName(), self, monSide) else basalt.setMainFrame(self) end @@ -529,11 +548,15 @@ return function(name, parent, pTerm, basalt) hide = function (self) base.hide(self) if(self.parent==nil)then - if(activeFrame == self)then activeFrame = nil end - if(isMonitor)then + if(activeFrame == self)then activeFrame = nil end -- bug activeFrame always nil + if(isMonitor)and not(isGroupedMonitor)then if(basalt.getMonitorFrame(monSide) == self)then basalt.setActiveFrame(nil) end + elseif(isGroupedMonitor)then + if(basalt.getMonitorFrame(self:getName()) == self)then + basalt.setActiveFrame(nil) + end else if(basalt.getMainFrame() == self)then basalt.setMainFrame(nil) @@ -637,25 +660,47 @@ return function(name, parent, pTerm, basalt) return self end, - setMonitor = function(self, side) + setMonitorScale = function(self, scale) + if(isMonitor)then + termObject.setTextScale(scale) + end + return self + end, + + setMonitor = function(self, side, scale) if(side~=nil)and(side~=false)then - if(peripheral.getType(side)=="monitor")then - termObject = peripheral.wrap(side) + if(type(side)=="string")then + if(peripheral.getType(side)=="monitor")then + termObject = peripheral.wrap(side) + monitorAttached = true + end + if(self.parent~=nil)then + self.parent:removeObject(self) + end + isMonitor = true + basalt.setMonitorFrame(side, self) + elseif(type(side)=="table")then + termObject = basaltMon(side) monitorAttached = true - + isMonitor = true + isGroupedMonitor = true + basalt.setMonitorFrame(self:getName(), self, true) end - if(self.parent~=nil)then - self.parent:removeObject(self) - end - isMonitor = true - basalt.setMonitorFrame(side, self) else termObject = parentTerminal isMonitor = false - if(basalt.getMonitorFrame(monSide)==self)then - basalt.setMonitorFrame(monSide, nil) + isGroupedMonitor = false + if(type(monSide)=="string")then + if(basalt.getMonitorFrame(monSide)==self)then + basalt.setMonitorFrame(monSide, nil) + end + else + if(basalt.getMonitorFrame(self:getName())==self)then + basalt.setMonitorFrame(self:getName(), nil) + end end end + if(scale~=nil)then termObject.setTextScale(scale) end basaltDraw = BasaltDraw(termObject) self:setSize(termObject.getSize()) autoSize = true @@ -712,8 +757,18 @@ return function(name, parent, pTerm, basalt) end if(isMonitor)then if(autoSize)then - if(event=="monitor_resize")and(p1==monSide)then - self:setSize(termObject.getSize()) + if(event=="monitor_resize")then + if(type(monSide)=="string")then + self:setSize(termObject.getSize()) + elseif(type(monSide)=="table")then + for k,v in pairs(monSide)do + for a,b in pairs(v)do + if(p1==b)then + self:setSize(termObject.getSize()) + end + end + end + end autoSize = true self:updateDraw() end @@ -747,7 +802,12 @@ return function(name, parent, pTerm, basalt) end end, - mouseHandler = function(self, button, x, y) + mouseHandler = function(self, button, x, y, _, side) + if(isGroupedMonitor)then + if(termObject.calculateClick~=nil)then + x, y = termObject.calculateClick(side, x, y) + end + end if(base.mouseHandler(self, button, x, y))then if(events["mouse_click"]~=nil)then self:setCursor(false) @@ -773,7 +833,6 @@ return function(name, parent, pTerm, basalt) end end self:removeFocusedObject() - focusSystem(self) return true end return false @@ -829,13 +888,31 @@ return function(name, parent, pTerm, basalt) end end self:removeFocusedObject() - focusSystem(self) if(yOffset==cache)then return false end 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() @@ -850,14 +927,16 @@ return function(name, parent, pTerm, basalt) self:updateDraw() return true end - if(events["mouse_drag"]~=nil)then - for _, index in ipairs(eventZIndex["mouse_drag"]) do - if (events["mouse_drag"][index] ~= nil) then - 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 + if(self:isVisible())and(self:isEnabled())then + if(events["mouse_drag"]~=nil)then + for _, index in ipairs(eventZIndex["mouse_drag"]) do + if (events["mouse_drag"][index] ~= nil) then + 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 end end @@ -976,6 +1055,17 @@ return function(name, parent, pTerm, basalt) end end; + blit = function (self, x, y, t, b, f) + local obx, oby = self:getAnchorPosition() + if (y >= 1) and (y <= self:getHeight()) then + if (self.parent ~= nil) then + self.parent:blit(max(x + (obx - 1), obx), oby + y - 1, sub(text, max(1 - x + 1, 1), self:getWidth() - x + 1), bgCol, fgCol) + else + basaltDraw.blit(max(x + (obx - 1), obx), oby + y - 1, sub(text, max(1 - x + 1, 1), max(self:getWidth() - x + 1,1)), bgCol, fgCol) + end + end + end, + drawBackgroundBox = function(self, x, y, width, height, bgCol) local obx, oby = self:getAnchorPosition() @@ -1066,9 +1156,7 @@ return function(name, parent, pTerm, basalt) return addObject(obj) end; - removeObject = function(self, obj) - return removeObject(obj) - end; + removeObject = removeObject, getObject = function(self, obj) return getObject(obj) @@ -1104,4 +1192,4 @@ return function(name, parent, pTerm, basalt) end setmetatable(object, base) return object -end \ No newline at end of file +end diff --git a/Basalt/Object.lua b/Basalt/Object.lua index a64d3f0..35b0de1 100644 --- a/Basalt/Object.lua +++ b/Basalt/Object.lua @@ -14,6 +14,7 @@ return function(name) local ignOffset = false local isVisible = true local initialized = false + local isHovered = false local shadow = false local borderColors = { @@ -56,17 +57,21 @@ return function(name) isVisible = false self:updateDraw() return self - end; + end, enable = function(self) isEnabled = true return self - end; + end, disable = function(self) isEnabled = false return self - end; + end, + + isEnabled = function(self) + return isEnabled + end, generateXMLEventFunction = function(self, func, val) local createF = function(str) @@ -114,6 +119,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 @@ -413,41 +420,48 @@ return function(name) 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, borderColors["left"]) - self.parent:drawForegroundBox(x-1, y, 1, h, self.parent.bgColor) + if(bgCol~=false)then self.parent:drawBackgroundBox(x-1, y, 1, h, self.bgColor) end + 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, borderColors["left"]) - self.parent:drawForegroundBox(x-1, y-1, 1, 1, self.parent.bgColor) + if(bgCol~=false)then self.parent:drawBackgroundBox(x-1, y-1, 1, 1, self.bgColor) end + self.parent:drawForegroundBox(x-1, y-1, 1, 1, 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, borderColors["top"]) - self.parent:drawForegroundBox(x, y-1, w, 1, self.parent.bgColor) + if(bgCol~=false)then self.parent:drawBackgroundBox(x, y-1, w, 1, self.bgColor) end + self.parent:drawForegroundBox(x, y-1, 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, borderColors["right"]) + if(bgCol~=false)then self.parent:drawForegroundBox(x+w, y-1, 1, 1, self.bgColor) end + self.parent:drawBackgroundBox(x+w, y-1, 1, 1, borderColors["right"]) end if(borderColors["right"]~=false)then self.parent:drawTextBox(x+w, y, 1, h, "\149") - self.parent:drawForegroundBox(x+w, y, 1, h, borderColors["right"]) + if(bgCol~=false)then self.parent:drawForegroundBox(x+w, y, 1, h, self.bgColor) end + 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, "\129") - self.parent:drawForegroundBox(x+w, y+h, 1, 1, borderColors["right"]) + self.parent:drawTextBox(x+w, y+h, 1, 1, "\133") + if(bgCol~=false)then self.parent:drawForegroundBox(x+w, y+h, 1, 1, self.bgColor) end + self.parent:drawBackgroundBox(x+w, y+h, 1, 1, borderColors["right"]) end if(borderColors["bottom"]~=false)then - self.parent:drawTextBox(x, y+h, w, 1, "\131") - self.parent:drawForegroundBox(x, y+h, w, 1, borderColors["bottom"]) + self.parent:drawTextBox(x, y+h, w, 1, "\143") + if(bgCol~=false)then self.parent:drawForegroundBox(x, y+h, w, 1, self.bgColor) end + self.parent:drawBackgroundBox(x, y+h, w, 1, borderColors["bottom"]) end if(borderColors["bottom"]~=false)and(borderColors["left"]~=false)then - self.parent:drawTextBox(x-1, y+h, 1, 1, "\130") - self.parent:drawForegroundBox(x-1, y+h, 1, 1, borderColors["left"]) + self.parent:drawTextBox(x-1, y+h, 1, 1, "\138") + if(bgCol~=false)then self.parent:drawForegroundBox(x-1, y+h, 1, 1, self.bgColor) end + self.parent:drawBackgroundBox(x-1, y+h, 1, 1, borderColors["left"]) end end draw = false @@ -570,15 +584,41 @@ return function(name) onScroll = function(self, ...) - for _,v in pairs(table.pack(...))do - if(type(v)=="function")then - self:registerEvent("mouse_scroll", v) - end + for _,v in pairs(table.pack(...))do + if(type(v)=="function")then + self:registerEvent("mouse_scroll", v) end - if(self.parent~=nil)then - self.parent:addEvent("mouse_scroll", self) - activeEvents["mouse_scroll"] = true + 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; @@ -588,12 +628,14 @@ return function(name) self:registerEvent("mouse_drag", v) end end - self.parent:addEvent("mouse_drag", self) - activeEvents["mouse_drag"] = true - self.parent:addEvent("mouse_click", self) - activeEvents["mouse_click"] = true - self.parent:addEvent("mouse_up", self) - activeEvents["mouse_up"] = true + if(self.parent~=nil)then + self.parent:addEvent("mouse_drag", self) + activeEvents["mouse_drag"] = true + self.parent:addEvent("mouse_click", self) + activeEvents["mouse_click"] = true + self.parent:addEvent("mouse_up", self) + activeEvents["mouse_up"] = true + end return self end; @@ -706,6 +748,7 @@ return function(name) isCoordsInObject = function(self, x, y) if(isVisible)and(isEnabled)then + if(x==nil)or(y==nil)then return false end local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) local w, h = self:getSize() if (objX <= x) and (objX + w > x) and (objY <= y) and (objY + h > y) then @@ -749,7 +792,7 @@ return function(name) 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 val = eventSystem:sendEvent("mouse_drag", self, "mouse_drag", button, dX, dY, dragStartX-x, dragStartY-y, x, y) local objX, objY = self:getAbsolutePosition(self:getAnchorPosition()) dragStartX, dragStartY = x, y if(val~=nil)then return val end @@ -779,6 +822,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 diff --git a/Basalt/libraries/basaltDraw.lua b/Basalt/libraries/basaltDraw.lua index 62ce41e..778ac9d 100644 --- a/Basalt/libraries/basaltDraw.lua +++ b/Basalt/libraries/basaltDraw.lua @@ -181,7 +181,7 @@ return function(drawTerm) isBlinking = terminal.getCursorBlink() end terminal.setCursorBlink(false) - if(mirrorTerm~=nil)then terminal.setCursorBlink(false) end + if(mirrorTerm~=nil)then mirrorTerm.setCursorBlink(false) end for n = 1, height do terminal.setCursorPos(1, n) terminal.blit(cacheT[n], cacheFG[n], cacheBG[n]) diff --git a/Basalt/libraries/basaltLogs.lua b/Basalt/libraries/basaltLogs.lua index 4edcd5a..0d3945f 100644 --- a/Basalt/libraries/basaltLogs.lua +++ b/Basalt/libraries/basaltLogs.lua @@ -3,7 +3,7 @@ local logFileName = "basaltLog.txt" local defaultLogType = "Debug" -fs.delete(logDir~="" and logDir.."/"..logFileName or logFileName) +--fs.delete(logDir~="" and logDir.."/"..logFileName or logFileName) local mt = { __call = function(_,text, typ) diff --git a/Basalt/libraries/basaltMon.lua b/Basalt/libraries/basaltMon.lua new file mode 100644 index 0000000..820e997 --- /dev/null +++ b/Basalt/libraries/basaltMon.lua @@ -0,0 +1,199 @@ +-- Right now this doesn't support scroll(n) +-- Because this lbirary is mainly made for basalt - it doesn't need scroll support, maybe i will add it in the future + +local tHex = { + [colors.white] = "0", + [colors.orange] = "1", + [colors.magenta] = "2", + [colors.lightBlue] = "3", + [colors.yellow] = "4", + [colors.lime] = "5", + [colors.pink] = "6", + [colors.gray] = "7", + [colors.lightGray] = "8", + [colors.cyan] = "9", + [colors.purple] = "a", + [colors.blue] = "b", + [colors.brown] = "c", + [colors.green] = "d", + [colors.red] = "e", + [colors.black] = "f", +} + +local type,len,rep,sub = type,string.len,string.rep,string.sub + + +return function (monitorNames) + local monitors = {} + for k,v in pairs(monitorNames)do + monitors[k] = {} + for a,b in pairs(v)do + local mon = peripheral.wrap(b) + if(mon==nil)then + error("Unable to find monitor "..b) + end + monitors[k][a] = mon + monitors[k][a].name = b + end + end + + + local x,y,monX,monY,monW,monH,w,h = 1,1,1,1,0,0,0,0 + local blink,scale = false,1 + local fg,bg = colors.white,colors.black + + + local function calcSize() + local maxW,maxH = 0,0 + for k,v in pairs(monitors)do + local _maxW,_maxH = 0,0 + for a,b in pairs(v)do + local nw,nh = b.getSize() + _maxW = _maxW + nw + _maxH = nh > _maxH and nh or _maxH + end + maxW = maxW > _maxW and maxW or _maxW + maxH = maxH + _maxH + end + w,h = maxW,maxH + end + calcSize() + + local function calcPosition() + local relY = 0 + local mX,mY = 0,0 + for k,v in pairs(monitors)do + local relX = 0 + local _mh = 0 + for a,b in pairs(v)do + local mw,mh = b.getSize() + if(x-relX>=1)and(x-relX<=mw)then + mX = a + end + b.setCursorPos(x-relX, y-relY) + relX = relX + mw + if(_mh=1)and(y-relY<=_mh)then + mY = k + end + relY = relY + _mh + end + monX,monY = mX,mY + end + calcPosition() + + local function call(f, ...) + local t = {...} + return function() + for k,v in pairs(monitors)do + for a,b in pairs(v)do + b[f](table.unpack(t)) + end + end + end + end + + local function cursorBlink() + call("setCursorBlink", false)() + if not(blink)then return end + if(monitors[monY]==nil)then return end + local mon = monitors[monY][monX] + if(mon==nil)then return end + mon.setCursorBlink(blink) + end + + local function blit(text, tCol, bCol) + if(monitors[monY]==nil)then return end + local mon = monitors[monY][monX] + if(mon==nil)then return end + mon.blit(text, tCol, bCol) + local mW, mH = mon.getSize() + if(len(text)+x>mW)then + local monRight = monitors[monY][monX+1] + if(monRight~=nil)then + monRight.blit(text, tCol, bCol) + monX = monX + 1 + x = x + len(text) + end + end + calcPosition() + end + + return { + clear = call("clear"), + + setCursorBlink = function(_blink) + blink = _blink + cursorBlink() + end, + + getCursorBlink = function() + return blink + end, + + getCursorPos = function() + return x, y + end, + + setCursorPos = function(newX,newY) + x, y = newX, newY + calcPosition() + cursorBlink() + end, + + setTextScale = function(_scale) + call("setTextScale", _scale)() + calcSize() + calcPosition() + scale = _scale + end, + + getTextScale = function() + return scale + end, + + blit = function(text,fgCol,bgCol) + blit(text,fgCol,bgCol) + end, + + write = function(text) + text = tostring(text) + local l = len(text) + blit(text, rep(tHex[fg], l), rep(tHex[bg], l)) + end, + + getSize = function() + return w,h + end, + + setBackgroundColor = function(col) + call("setBackgroundColor", col)() + bg = col + end, + + setTextColor = function(col) + call("setTextColor", col)() + fg = col + end, + + calculateClick = function(name, xClick, yClick) + local relY = 0 + for k,v in pairs(monitors)do + local relX = 0 + local maxY = 0 + for a,b in pairs(v)do + local wM,hM = b.getSize() + if(b.name==name)then + return xClick + relX, yClick + relY + end + relX = relX + wM + if(hM > maxY)then maxY = hM end + end + relY = relY + maxY + end + return xClick, yClick + end, + + } +end \ No newline at end of file diff --git a/Basalt/libraries/process.lua b/Basalt/libraries/process.lua index 2de4672..8a7248e 100644 --- a/Basalt/libraries/process.lua +++ b/Basalt/libraries/process.lua @@ -7,9 +7,17 @@ function process:new(path, window, ...) local newP = setmetatable({ path = path }, { __index = self }) newP.window = window newP.processId = processId + if(type(path)=="string")then newP.coroutine = coroutine.create(function() shell.execute(path, table.unpack(args)) end) + elseif(type(path)=="function")then + newP.coroutine = coroutine.create(function() + path(table.unpack(args)) + end) + else + return + end processes[processId] = newP processId = processId + 1 return newP @@ -22,7 +30,6 @@ function process:resume(event, ...) self.filter=nil end local ok, result = coroutine.resume(self.coroutine, event, ...) - self.window = term.current() if ok then self.filter = result else diff --git a/Basalt/main.lua b/Basalt/main.lua index baac265..a6f0104 100644 --- a/Basalt/main.lua +++ b/Basalt/main.lua @@ -2,17 +2,18 @@ local basaltEvent = require("basaltEvent")() local Frame = require("Frame") local theme = require("theme") local utils = require("utils") +local log = require("basaltLogs") local uuid = utils.uuid local createText = utils.createText - +local count = utils.tableCount +local moveThrottle = 300 local baseTerm = term.current() -local version = "1.6.0" -local debugger = true +local version = "1.6.2" local projectDirectory = fs.getDir(table.pack(...)[2] or "") -local activeKey, frames, monFrames, variables, schedules = {}, {}, {}, {}, {} +local activeKey, frames, monFrames, monGroups, variables, schedules = {}, {}, {}, {}, {}, {} local mainFrame, activeFrame, focusedObject, updaterActive local basalt = {} @@ -73,12 +74,19 @@ local bInstance = { end, getMonitorFrame = function(name) - return monFrames[name] + return monFrames[name] or monGroups[name][1] end, - setMonitorFrame = function(name, frame) + setMonitorFrame = function(name, frame, isGroupedMon) if(mainFrame == frame)then mainFrame = nil end - monFrames[name] = frame + if(isGroupedMon)then + monGroups[name] = {frame, sides} + else + monFrames[name] = frame + end + if(frame==nil)then + monGroups[name] = nil + end end, getBaseTerm = function() @@ -144,6 +152,25 @@ local function drawFrames() v:draw() v:updateTerm() end + for _,v in pairs(monGroups)do + v[1]:draw() + v[1]:updateTerm() + end +end + +local stopped, moveX, moveY = nil, nil, nil +local moveTimer = nil +local function mouseMoveEvent(stp, x, y) + stopped, moveX, moveY = stopped, 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 function basaltUpdateEvent(event, p1, p2, p3, p4) @@ -161,15 +188,25 @@ local function basaltUpdateEvent(event, p1, p2, p3, p4) elseif (event == "mouse_scroll") then mainFrame:scrollHandler(p1, p2, p3, p4) activeFrame = mainFrame + elseif (event == "mouse_move") then + mouseMoveEvent(p1, p2, p3) end end + if(event == "monitor_touch") then if(monFrames[p1]~=nil)then monFrames[p1]:mouseHandler(1, p2, p3, 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) + end + end end + + if(event == "char")then if(activeFrame~=nil)then activeFrame:charHandler(p1) @@ -193,9 +230,13 @@ local function basaltUpdateEvent(event, p1, p2, p3, p4) if(updaterActive==false)then return end end end - if(event~="mouse_click")and(event~="mouse_up")and(event~="mouse_scroll")and(event~="mouse_drag")and(event~="key")and(event~="key_up")and(event~="char")and(event~="terminate")then - for k, v in pairs(frames) do - v:eventHandler(event, p1, p2, p3, p4) + if(event~="mouse_click")and(event~="mouse_up")and(event~="mouse_scroll")and(event~="mouse_drag")and(event~="mouse_move")and(event~="key")and(event~="key_up")and(event~="char")and(event~="terminate")then + if(event=="timer")and(p1~=moveTimer)then + for k, v in pairs(frames) do + v:eventHandler(event, p1, p2, p3, p4) + end + else + moveHandlerTimer() end end handleSchedules(event, p1, p2, p3, p4) @@ -222,6 +263,19 @@ 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, + autoUpdate = function(isActive) updaterActive = isActive if(isActive==nil)then updaterActive = true end diff --git a/Basalt/objects/Animation.lua b/Basalt/objects/Animation.lua index 0ea75e4..48d9d97 100644 --- a/Basalt/objects/Animation.lua +++ b/Basalt/objects/Animation.lua @@ -134,25 +134,28 @@ return function(name) local function predefinedLerp(v1,v2,d,t,get,set,typ,self) + local obj = _OBJ local x,y local name = "" - if(_OBJ.parent~=nil)then name = _OBJ.parent:getName() end - name = name.._OBJ:getName() + if(obj.parent~=nil)then name = obj.parent:getName() end + name = name..obj:getName() addAnimationPart(t+0.05, function() if(typ~=nil)then if(activeAnimations[typ]==nil)then activeAnimations[typ] = {} end if(activeAnimations[typ][name]~=nil)then - activeAnimations[typ][name]:cancel() + if(activeAnimations[typ][name]~=self)then + activeAnimations[typ][name]:cancel() + end end activeAnimations[typ][name] = self end - x,y = get(_OBJ) + x,y = get(obj) end) for n=0.05,d+0.01,0.05 do addAnimationPart(t+n, function() local _x = math.floor(lerp.lerp(x, v1, lerp[mode](n / d))+0.5) local _y = math.floor(lerp.lerp(y, v2, lerp[mode](n / d))+0.5) - set(_OBJ, _x,_y) + set(obj, _x,_y) if(typ~=nil)then if(n>=d-0.01)then if(activeAnimations[typ][name]==self)then @@ -427,7 +430,7 @@ return function(name) if (animations[index].t > 0) then timerObj = os.startTimer(animations[index].t) else - onPlay() + onPlay(self) end else self:animationDoneHandler() diff --git a/Basalt/objects/Image.lua b/Basalt/objects/Image.lua index 24ff76e..b4d62f7 100644 --- a/Basalt/objects/Image.lua +++ b/Basalt/objects/Image.lua @@ -170,16 +170,16 @@ return function(name) 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 + for i = 1, math.min(shrinkedImage.height, h) 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]) + self.parent:setText(obx, oby + i - 1, tI:sub(1,w)) + self.parent:setFG(obx, oby + i - 1, tC[i]:sub(1,w)) + self.parent:setBG(obx, oby + i - 1, bC[i]:sub(1,w)) 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]) + self.parent:setText(obx, oby + i - 1, tI[2]:sub(1,w)) + self.parent:setFG(obx, oby + i - 1, tC[i]:sub(1,w)) + self.parent:setBG(obx, oby + i - 1, bC[i]:sub(1,w)) end end else diff --git a/Basalt/objects/Input.lua b/Basalt/objects/Input.lua index 654481c..a54fb9c 100644 --- a/Basalt/objects/Input.lua +++ b/Basalt/objects/Input.lua @@ -61,7 +61,7 @@ return function(name) textX = tostring(val):len() + 1 wIndex = math.max(1, textX-self:getWidth()+1) local obx, oby = self:getAnchorPosition() - self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self.height/2), self.fgColor) + self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor) end end self:updateDraw() @@ -179,13 +179,15 @@ return function(name) local obx, oby = self:getAnchorPosition() local val = tostring(base.getValue()) local cursorX = (textX <= val:len() and textX - 1 or val:len()) - (wIndex - 1) - - if (cursorX > self.x + w - 1) then - cursorX = self.x + w - 1 + + local inpX = self:getX() + if (cursorX > inpX + w - 1) then + cursorX = inpX + w - 1 end if (self.parent ~= nil) then self.parent:setCursor(true, obx + cursorX, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor) end + self:updateDraw() internalValueChange = false return true end @@ -249,11 +251,22 @@ return function(name) wIndex = 1 end end - self.parent:setCursor(true, obx + textX-1, oby+math.max(math.ceil(h/2-1, 1)), self.fgColor) + self.parent:setCursor(true, ax + textX - wIndex, ay+math.max(math.ceil(h/2-1, 1)), self.fgColor) return true end end, + dragHandler = function(self, btn, x, y, xOffset, yOffset) + if(self:isFocused())then + if(self:isCoordsInObject(x, y))then + if(base.dragHandler(self, btn, x, y, xOffset, yOffset))then + return true + end + end + self.parent:removeFocusedObject() + end + end, + eventHandler = function(self, event, paste, p2, p3, p4) if(base.eventHandler(self, event, paste, p2, p3, p4))then if(event=="paste")then @@ -332,6 +345,9 @@ return function(name) self.parent:writeText(obx, oby + (n - 1), text, bCol, fCol) end end + if(self:isFocused())then + self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor) + end end end end, @@ -344,6 +360,7 @@ return function(name) self.parent:addEvent("key", self) self.parent:addEvent("char", self) self.parent:addEvent("other_event", self) + self.parent:addEvent("mouse_drag", self) end end, } diff --git a/Basalt/objects/Textfield.lua b/Basalt/objects/Textfield.lua index c9c59ba..2516e01 100644 --- a/Basalt/objects/Textfield.lua +++ b/Basalt/objects/Textfield.lua @@ -596,6 +596,10 @@ return function(name) self.parent:setBG(obx, oby + n - 1, bg) self.parent:setFG(obx, oby + n - 1, fg) end + if(self:isFocused())then + local anchx, anchy = self:getAnchorPosition() + self.parent:setCursor(true, anchx + textX - wIndex, anchy + textY - hIndex, self.fgColor) + end end end end,