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
This commit is contained in:
Robert Jelic
2022-09-05 23:00:38 +02:00
parent a3291544ac
commit cf4f15e659
5 changed files with 290 additions and 27 deletions

View File

@@ -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)

View File

@@ -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])

View File

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

View File

@@ -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)

View File

@@ -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