From cf4f15e6598718edc1a181e2a3df1a313e49b499 Mon Sep 17 00:00:00 2001 From: Robert Jelic <36573031+NoryiE@users.noreply.github.com> Date: Mon, 5 Sep 2022 23:00:38 +0200 Subject: [PATCH] added multimonitor support - cursor fix @input - now you are able to add bigger monitors - still in beta Some features are still missing: checking if monitors are connected/disconnected, resizing by destroying the blocks --- Basalt/Frame.lua | 79 ++++++++++--- Basalt/libraries/basaltDraw.lua | 2 +- Basalt/libraries/basaltMon.lua | 199 ++++++++++++++++++++++++++++++++ Basalt/main.lua | 29 ++++- Basalt/objects/Input.lua | 8 +- 5 files changed, 290 insertions(+), 27 deletions(-) create mode 100644 Basalt/libraries/basaltMon.lua diff --git a/Basalt/Frame.lua b/Basalt/Frame.lua index c5be088..532db2f 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 @@ -522,8 +524,10 @@ return function(name, parent, pTerm, basalt) 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 @@ -534,11 +538,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) @@ -642,25 +650,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 @@ -717,8 +747,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 @@ -752,7 +792,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) 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/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/main.lua b/Basalt/main.lua index 28fc5b3..7944b16 100644 --- a/Basalt/main.lua +++ b/Basalt/main.lua @@ -5,15 +5,16 @@ local utils = require("utils") local log = require("basaltLogs") local uuid = utils.uuid local createText = utils.createText +local count = utils.tableCount local baseTerm = term.current() -local version = "1.6.1" +local version = "1.6.2" local debugger = true 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 = {} @@ -74,12 +75,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() @@ -145,6 +153,10 @@ local function drawFrames() v:draw() v:updateTerm() end + for _,v in pairs(monGroups)do + v[1]:draw() + v[1]:updateTerm() + end end local function basaltUpdateEvent(event, p1, p2, p3, p4) @@ -169,8 +181,15 @@ local function basaltUpdateEvent(event, p1, p2, p3, p4) 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) diff --git a/Basalt/objects/Input.lua b/Basalt/objects/Input.lua index 3512b07..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,7 +179,7 @@ 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) - + local inpX = self:getX() if (cursorX > inpX + w - 1) then cursorX = inpX + w - 1 @@ -251,7 +251,7 @@ return function(name) wIndex = 1 end end - self.parent:setCursor(true, obx + textX - wIndex, 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, @@ -346,7 +346,7 @@ return function(name) end end if(self:isFocused())then - self.parent:setCursor(true, obx + textX - wIndex, oby+math.max(math.ceil(self:getHeight()/2-1, 1)), self.fgColor) + self.parent:setCursor(true, obx + textX - wIndex, oby+math.floor(self:getHeight()/2), self.fgColor) end end end