Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local tArgs = {...}
- if _G.windowShell then
- shell.run("fg", unpack(tArgs))
- return
- end
- term.setBackgroundColor(colors.black)
- term.clear()
- term.redirect(term.native())
- -- Window API --
- local window = {}
- function window.create( parent, nX, nY, nWidth, nHeight, bStartVisible, sExpectedTitle )
- if type( parent ) ~= "table" or
- type( nX ) ~= "number" or
- type( nY ) ~= "number" or
- type( nWidth ) ~= "number" or
- type( nHeight ) ~= "number" or
- (bStartVisible ~= nil and type( bStartVisible ) ~= "boolean") then
- error( "Expected object, number, number, number, number, [boolean]", 2 )
- end
- if parent == term then
- error( "term is not a recommended window parent, try term.current() instead", 2 )
- end
- -- Setup
- local bVisible = (bStartVisible ~= false)
- local sTitle = sExpectedTitle or ""
- local nCursorX = 1
- local nCursorY = 1
- local bCursorBlink = false
- local nTextColor = colors.white
- local nBackgroundColor = colors.black
- local sEmpty = string.rep( " ", nWidth - 2 )
- local tLines = {}
- do
- local tEmpty = { { sEmpty, nTextColor, nBackgroundColor } }
- for y=1,nHeight do
- tLines[y] = tEmpty
- end
- end
- -- Helper functions
- local function updateCursorPos()
- if nCursorX >= 1 and nCursorY >= 1 and
- nCursorX <= nWidth and nCursorY <= nHeight then
- parent.setCursorPos( nX + nCursorX, nY + nCursorY)
- else
- parent.setCursorPos( 0, 0 )
- end
- end
- local function updateCursorBlink()
- parent.setCursorBlink( bCursorBlink )
- end
- local function updateCursorColor()
- parent.setTextColor( nTextColor )
- end
- local function redrawLine( n )
- parent.setCursorPos( nX + 1, nY + n )
- local tLine = tLines[ n ]
- for m=1,#tLine do
- local tBit = tLine[ m ]
- parent.setTextColor( tBit[2] )
- parent.setBackgroundColor( tBit[3] )
- parent.write( tBit[1] )
- end
- parent.setBackgroundColor(colors.blue)
- parent.setCursorPos( nX + (nWidth - 1), nY + nCursorY )
- parent.write(" ")
- end
- local function lineLen( tLine )
- local nLength = 0
- for n=1,#tLine do
- nLength = nLength + string.len( tLine[n][1] )
- end
- return nLength
- end
- local function lineSub( tLine, nStart, nEnd )
- --assert( math.floor(nStart) == nStart )
- --assert( math.floor(nEnd) == nEnd )
- --assert( nStart >= 1 )
- --assert( nEnd >= nStart )
- --assert( nEnd <= lineLen( tLine ) )
- local tSubLine = {}
- local nBitStart = 1
- for n=1,#tLine do
- local tBit = tLine[n]
- local sBit = tBit[1]
- local nBitEnd = math.min(nBitStart + string.len( sBit ) - 1)
- if nBitEnd >= nStart and nBitStart <= nEnd then
- if nBitStart >= nStart and nBitEnd <= nEnd then
- -- Include bit wholesale
- table.insert( tSubLine, tBit )
- --assert( lineLen( tSubLine ) == (math.min(nEnd, nBitEnd) - nStart + 1) )
- elseif nBitStart < nStart and nBitEnd <= nEnd then
- -- Include end of bit
- table.insert( tSubLine, {
- string.sub( sBit, nStart - nBitStart + 1 ),
- tBit[2], tBit[3]
- } )
- --assert( lineLen( tSubLine ) == (math.min(nEnd, nBitEnd) - nStart + 1) )
- elseif nBitStart >= nStart and nBitEnd > nEnd then
- -- Include beginning of bit
- table.insert( tSubLine, {
- string.sub( sBit, 1, nEnd - nBitStart + 1 ),
- tBit[2], tBit[3]
- } )
- --assert( lineLen( tSubLine ) == (math.min(nEnd, nBitEnd) - nStart + 1) )
- else
- -- Include middle of bit
- table.insert( tSubLine, {
- string.sub( sBit, nStart - nBitStart + 1, nEnd - nBitStart + 1 ),
- tBit[2], tBit[3]
- } )
- --assert( lineLen( tSubLine ) == (math.min(nEnd, nBitEnd) - nStart + 1) )
- end
- end
- nBitStart = nBitEnd + 1
- end
- --assert( lineLen( tSubLine ) == (nEnd - nStart + 1) )
- return tSubLine
- end
- local function lineJoin( tLine1, tLine2 )
- local tNewLine = {}
- if tLine1[#tLine1][2] == tLine2[1][2] and
- tLine1[#tLine1][3] == tLine2[1][3] then
- -- Merge middle bits
- for n=1,#tLine1-1 do
- table.insert( tNewLine, tLine1[n] )
- end
- table.insert( tNewLine, {
- tLine1[#tLine1][1] .. tLine2[1][1],
- tLine2[1][2], tLine2[1][3]
- } )
- for n=2,#tLine2 do
- table.insert( tNewLine, tLine2[n] )
- end
- --assert( lineLen( tNewLine ) == lineLen(tLine1) + lineLen(tLine2) )
- else
- -- Just concatenate
- for n=1,#tLine1 do
- table.insert( tNewLine, tLine1[n] )
- end
- for n=1,#tLine2 do
- table.insert( tNewLine, tLine2[n] )
- end
- --assert( lineLen( tNewLine ) == lineLen(tLine1) + lineLen(tLine2) )
- end
- return tNewLine
- end
- local function redraw()
- -- Draw window contents.
- for n=1,nHeight - 2 do
- redrawLine( n )
- end
- -- Draw Top and Bottom borders
- local lineStr = string.rep(" ", nWidth)
- parent.setBackgroundColor(colors.blue)
- parent.setTextColor(colors.white)
- parent.setCursorPos( nX, nY )
- parent.write(lineStr)
- parent.setCursorPos( nX, nY )
- parent.write(sTitle or "window")
- parent.setCursorPos( nX + (nWidth - 2), nY)
- parent.write("_")
- parent.setBackgroundColor(colors.red)
- parent.setCursorPos( nX + (nWidth - 1), nY)
- parent.write("X")
- parent.setBackgroundColor(colors.blue)
- parent.setCursorPos( nX, nY + nHeight - 1 )
- parent.write(lineStr)
- -- Draw Left and Right borders
- parent.setBackgroundColor(colors.blue)
- for y=1, nHeight - 2 do
- parent.setCursorPos( nX, nY + y )
- parent.write(" ")
- parent.setCursorPos( nX + (nWidth - 1), nY + y )
- parent.write(" ")
- end
- parent.setCursorPos( nX + (nWidth - 1), nY + nHeight - 1 )
- parent.setTextColor(colors.white)
- parent.write("/")
- end
- local window = {}
- -- Terminal implementation
- function window.write( sText )
- local nLen = string.len( string.sub(sText, 0, nWidth - 2) )
- local nStart = nCursorX
- local nEnd = nStart + nLen - 1
- if nCursorY >= 1 and nCursorY <= nHeight - 2 then
- -- Work out where to put new line
- --assert( math.floor(nStart) == nStart )
- --assert( math.floor(nEnd) == nEnd )
- if nStart <= (nWidth - 2) and nEnd >= 1 then
- -- Construct new line
- local tLine = tLines[ nCursorY ]
- if nStart == 1 and nEnd == (nWidth - 2) then
- -- Exactly replace line
- tLine = {
- { sText, nTextColor, nBackgroundColor }
- }
- --assert( lineLen( tLine ) == nWidth )
- elseif nStart <= 1 and nEnd >= (nWidth - 2) then
- -- Overwrite line with subset
- tLine = {
- { string.sub( sText, 1 - nStart + 1, (nWidth - 2) - nStart + 1 ), nTextColor, nBackgroundColor }
- }
- --assert( lineLen( tLine ) == nWidth )
- elseif nStart <= 1 then
- -- Overwrite beginning of line
- tLine = lineJoin(
- { { string.sub( sText, 1 - nStart + 1 ), nTextColor, nBackgroundColor } },
- lineSub( tLine, nEnd + 1, (nWidth - 2) )
- )
- --assert( lineLen( tLine ) == nWidth )
- elseif nEnd >= nWidth - 2 then
- -- Overwrite end of line
- tLine = lineJoin(
- lineSub( tLine, 1, nStart - 1 ),
- { { string.sub( sText, 1, (nWidth - 2) - nStart + 1 ), nTextColor, nBackgroundColor } }
- )
- --assert( lineLen( tLine ) == nWidth )
- else
- -- Overwrite middle of line
- tLine = lineJoin(
- lineJoin(
- lineSub( tLine, 1, nStart - 1 ),
- { { sText, nTextColor, nBackgroundColor } }
- ),
- lineSub( tLine, nEnd + 1, (nWidth - 2) )
- )
- --assert( lineLen( tLine ) == nWidth )
- end
- -- Destroy text outside the window region that should not be there
- for k=nWidth - 2, #tLine do
- table.remove(tLine, nWidth)
- end
- -- Store and redraw new line
- tLines[ nCursorY ] = tLine
- if bVisible then
- redrawLine( nCursorY )
- end
- end
- end
- -- Move and redraw cursor
- nCursorX = nEnd + 1
- if bVisible then
- updateCursorColor()
- updateCursorPos()
- end
- end
- function window.clear()
- local tEmpty = { { sEmpty, nTextColor, nBackgroundColor } }
- for y=1,nHeight do
- tLines[y] = tEmpty
- end
- if bVisible then
- redraw()
- updateCursorColor()
- updateCursorPos()
- end
- end
- function window.clearLine()
- if nCursorY >= 1 and nCursorY <= nHeight then
- tLines[ nCursorY ] = { { sEmpty, nTextColor, nBackgroundColor } }
- if bVisible then
- redrawLine( nCursorY )
- updateCursorColor()
- updateCursorPos()
- end
- end
- end
- function window.getCursorPos()
- return nCursorX, nCursorY
- end
- function window.setCursorPos( x, y )
- nCursorX = math.floor( x )
- nCursorY = math.floor( y )
- if bVisible then
- updateCursorPos()
- end
- end
- function window.setCursorBlink( blink )
- bCursorBlink = blink
- if bVisible then
- updateCursorBlink()
- end
- end
- function window.isColor()
- return parent.isColor()
- end
- function window.isColour()
- return parent.isColor()
- end
- local function setTextColor( color )
- if not parent.isColor() then
- if color ~= colors.white and color ~= colors.black then
- error( "Color not supported", 3 )
- end
- end
- nTextColor = color
- if bVisible then
- updateCursorColor()
- end
- end
- function window.setTextColor( color )
- setTextColor( color )
- end
- function window.setTextColour( color )
- setTextColor( color )
- end
- function window.getTextColor()
- return nTextColor
- end
- function window.getTextColour()
- return nTextColor
- end
- local function setBackgroundColor( color )
- if not parent.isColor() then
- if color ~= colors.white and color ~= colors.black then
- error( "Colour not supported", 3 )
- end
- end
- nBackgroundColor = color
- end
- function window.setBackgroundColor( color )
- setBackgroundColor( color )
- end
- function window.setBackgroundColour( color )
- setBackgroundColor( color )
- end
- function window.getBackgroundColor()
- return nBackgroundColor
- end
- function window.getBackgroundColour()
- return nBackgroundColor
- end
- function window.getSize()
- return nWidth - 2, nHeight - 2
- end
- function window.scroll( n )
- if n ~= 0 then
- local tNewLines = {}
- local tEmpty = { { sEmpty, nTextColor, nBackgroundColor } }
- for newY=1,nHeight do
- local y = newY + n
- if y >= 1 and y <= nHeight then
- tNewLines[newY] = tLines[y]
- else
- tNewLines[newY] = tEmpty
- end
- end
- tLines = tNewLines
- if bVisible then
- redraw()
- updateCursorColor()
- updateCursorPos()
- end
- end
- end
- -- Other functions
- function window.setVisible( bVis )
- if bVisible ~= bVis then
- bVisible = bVis
- if bVisible then
- window.redraw()
- end
- end
- end
- function window.redraw()
- if bVisible then
- redraw()
- updateCursorBlink()
- updateCursorColor()
- updateCursorPos()
- end
- end
- function window.restoreCursor()
- if bVisible then
- updateCursorBlink()
- updateCursorColor()
- updateCursorPos()
- end
- end
- function window.getPosition()
- return nX, nY
- end
- function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight )
- nX = nNewX
- nY = nNewY
- if nNewWidth and nNewHeight then
- sEmpty = string.rep( " ", nNewWidth )
- local tNewLines = {}
- local tEmpty = { { sEmpty, nTextColor, nBackgroundColor } }
- for y=1,nNewHeight do
- if y > nHeight then
- tNewLines[y] = tEmpty
- else
- if nNewWidth == nWidth then
- tNewLines[y] = tLines[y]
- elseif nNewWidth < nWidth then
- tNewLines[y] = lineSub( tLines[y], 1, nNewWidth )
- else
- tNewLines[y] = lineJoin( tLines[y], { { string.sub( sEmpty, nWidth + 1, nNewWidth ), nTextColor, nBackgroundColor } } )
- end
- end
- end
- nWidth = nNewWidth
- nHeight = nNewHeight
- tLines = tNewLines
- end
- if bVisible then
- window.redraw()
- end
- end
- -- Priviate functions not actually available.
- function window.getTitle()
- return sTitle
- end
- function window.setTitle(sNewTitle)
- sTitle = sNewTitle
- end
- if bVisible then
- window.redraw()
- end
- return window
- end
- -- Set up arguments
- _G.windowShell = true
- -- Setup process switching
- local parentTerm = term.current()
- local w,h = parentTerm.getSize()
- local tProcesses = {}
- local nCurrentProcess = nil
- local nRunningProcess = nil
- local bShowMenu = false
- local bWindowsResized = false
- local menuMainTextColor, menuMainBgColor, menuOtherTextColor, menuOtherBgColor
- if parentTerm.isColor() then
- menuMainTextColor, menuMainBgColor = colors.black, colors.white
- menuOtherTextColor, menuOtherBgColor = colors.black, colors.lightGray
- else
- menuMainTextColor, menuMainBgColor = colors.white, colors.black
- menuOtherTextColor, menuOtherBgColor = colors.black, colors.white
- end
- local function redrawScreen()
- parentTerm.setBackgroundColor(colors.black)
- parentTerm.clear()
- parentTerm.setCursorPos(1, h)
- parentTerm.setBackgroundColor(menuOtherBgColor)
- parentTerm.clearLine()
- for k, tProcess in pairs(tProcesses) do
- tProcess.window.redraw()
- end
- redrawMenu()
- end
- local function selectProcess( n )
- if nCurrentProcess ~= n then
- if nCurrentProcess then
- local tOldProcess = tProcesses[ nCurrentProcess ]
- end
- nCurrentProcess = n
- if nCurrentProcess then
- local tNewProcess = tProcesses[ nCurrentProcess ]
- tNewProcess.bInteracted = true
- tNewProcess.window.setVisible(true)
- end
- end
- end
- local function setProcessTitle( n, sTitle )
- tProcesses[ n ].sTitle = sTitle
- tProcesses[ n ].window.setTitle(sTitle)
- end
- local function resumeProcess( nProcess, sEvent, ... )
- local tProcess = tProcesses[ nProcess ]
- if tProcess then
- local sFilter = tProcess.sFilter
- if sFilter == nil or sFilter == sEvent or sEvent == "terminate" then
- local nPreviousProcess = nRunningProcess
- nRunningProcess = nProcess
- term.redirect( tProcess.terminal )
- local ok, result = coroutine.resume( tProcess.co, sEvent, ... )
- tProcess.terminal = term.current()
- if ok then
- tProcess.sFilter = result
- else
- printError( result )
- end
- nRunningProcess = nPreviousProcess
- end
- end
- end
- local function launchProcess( tProgramEnv, sProgramPath, ... )
- local tProgramArgs = { ... }
- local nProcess = #tProcesses + 1
- local tProcess = {}
- tProcess.sTitle = fs.getName( sProgramPath )
- if bShowMenu then
- tProcess.window = window.create( parentTerm, math.min(#tProcesses + 1, w), math.min(#tProcesses + 1, h - 12), 32, 12, false, tProcess.sTitle )
- else
- tProcess.window = window.create( parentTerm, 1, 1, w, h, false, tProcess.sTitle )
- end
- tProcess.co = coroutine.create( function()
- os.run( tProgramEnv, sProgramPath, unpack( tProgramArgs ) )
- if not tProcess.bInteracted then
- term.setCursorBlink( false )
- print( "Press any key to continue" )
- os.pullEvent( "char" )
- end
- end )
- tProcess.sFilter = nil
- tProcess.terminal = tProcess.window
- tProcess.bInteracted = false
- tProcesses[ nProcess ] = tProcess
- resumeProcess( nProcess )
- return nProcess
- end
- local function cullProcess( nProcess )
- local tProcess = tProcesses[ nProcess ]
- if tProcess then
- if coroutine.status( tProcess.co ) == "dead" then
- if nCurrentProcess == nProcess then
- selectProcess( nil )
- end
- table.remove( tProcesses, nProcess )
- if nCurrentProcess == nil then
- if nProcess > 1 then
- selectProcess( nProcess - 1 )
- elseif #tProcesses > 0 then
- selectProcess( 1 )
- end
- end
- return true
- end
- return false
- end
- end
- local function killProcess( nProcess )
- if nCurrentProcess == nProcess then
- selectProcess( nil )
- end
- table.remove( tProcesses, nProcess )
- if nCurrentProcess == nil then
- if nProcess > 1 then
- selectProcess( nProcess - 1 )
- elseif #tProcesses > 0 then
- selectProcess( 1 )
- end
- end
- redrawScreen()
- return true
- end
- local function cullProcesses()
- local culled = false
- for n=#tProcesses,1,-1 do
- culled = culled or cullProcess( n )
- end
- return culled
- end
- -- Setup the main menu
- function redrawMenu()
- if bShowMenu then
- -- Draw menu
- parentTerm.setCursorPos( 1, h )
- parentTerm.setBackgroundColor( menuOtherBgColor )
- parentTerm.clearLine()
- for n=1,#tProcesses do
- if n == nCurrentProcess then
- parentTerm.setTextColor( menuMainTextColor )
- parentTerm.setBackgroundColor( menuMainBgColor )
- else
- parentTerm.setTextColor( menuOtherTextColor )
- parentTerm.setBackgroundColor( menuOtherBgColor )
- end
- parentTerm.write( " " .. tProcesses[n].sTitle .. " " )
- end
- -- Put the cursor back where it should be
- local tProcess = tProcesses[ nCurrentProcess ]
- if tProcess then
- tProcess.window.restoreCursor()
- end
- end
- end
- local redrawMenu = redrawMenu
- local function resizeWindows()
- local windowY, windowHeight
- if bShowMenu then
- windowY = 2
- windowHeight = h-2
- else
- windowY = 1
- windowHeight = h
- end
- for n=1,#tProcesses do
- local tProcess = tProcesses[n]
- local window = tProcess.window
- local x,y = tProcess.window.getCursorPos()
- if y > windowHeight then
- tProcess.window.scroll( y - windowHeight )
- tProcess.window.setCursorPos( x, windowHeight )
- end
- --tProcess.window.reposition( 4, windowY, w - 4, windowHeight )
- end
- bWindowsResized = true
- end
- local function setMenuVisible( bVis )
- if bShowMenu ~= bVis then
- bShowMenu = bVis
- resizeWindows()
- redrawMenu()
- end
- end
- local multishell = {}
- function multishell.getFocus()
- return nCurrentProcess
- end
- function multishell.setFocus( n )
- if n >= 1 and n <= #tProcesses then
- selectProcess( n )
- redrawMenu()
- return true
- end
- return false
- end
- function multishell.getTitle( n )
- if n >= 1 and n <= #tProcesses then
- return tProcesses[n].sTitle
- end
- return nil
- end
- function multishell.setTitle( n, sTitle )
- if n >= 1 and n <= #tProcesses then
- setProcessTitle( n, sTitle )
- redrawMenu()
- end
- end
- function multishell.getCurrent()
- return nRunningProcess
- end
- function multishell.launch( tProgramEnv, sProgramPath, ... )
- local previousTerm = term.current()
- setMenuVisible(true)
- local nResult = launchProcess( tProgramEnv, sProgramPath, ... )
- redrawMenu()
- term.redirect( previousTerm )
- return nResult
- end
- function multishell.getCount()
- return #tProcesses
- end
- -- Begin
- parentTerm.clear()
- setMenuVisible( true )
- selectProcess( launchProcess( {
- ["shell"] = shell,
- ["multishell"] = multishell,
- }, unpack(tArgs) or "/rom/programs/shell" ) )
- -- Since the native terminal is bugged we must trigger a term_resize event.
- os.queueEvent("term_resize")
- -- Run processes
- while #tProcesses > 0 do
- -- Get the event
- local tEventData = { os.pullEventRaw() }
- local sEvent = tEventData[1]
- if sEvent == "term_resize" then
- -- Resize event
- w,h = parentTerm.getSize()
- resizeWindows()
- redrawScreen()
- elseif sEvent == "char" or sEvent == "key" or sEvent == "paste" or sEvent == "terminate" then
- -- Keyboard event
- -- Passthrough to current process
- resumeProcess( nCurrentProcess, unpack( tEventData ) )
- if cullProcess( nCurrentProcess ) then
- setMenuVisible( true )
- redrawScreen()
- end
- if tProcesses[nCurrentProcess] then
- if tProcesses[nCurrentProcess].rsX or tProcesses[nCurrentProcess].dragX then
- if tProcesses[nCurrentProcess].rsX then resumeProcess( nCurrentProcess, "term_resize") end
- tProcesses[nCurrentProcess].dragX, tProcesses[nCurrentProcess].dragY = nil, nil
- tProcesses[nCurrentProcess].rsX, tProcesses[nCurrentProcess].rsY = nil, nil
- redrawScreen()
- end
- end
- elseif sEvent == "mouse_click" then
- -- Click event
- local button, x, y = tEventData[2], tEventData[3], tEventData[4]
- if tProcesses[nCurrentProcess].rsX or tProcesses[nCurrentProcess].dragX then
- if tProcesses[nCurrentProcess].rsX then resumeProcess( nCurrentProcess, "term_resize") end
- tProcesses[nCurrentProcess].dragX, tProcesses[nCurrentProcess].dragY = nil, nil
- tProcesses[nCurrentProcess].rsX, tProcesses[nCurrentProcess].rsY = nil, nil
- end
- if bShowMenu and y == h then
- -- Switch process
- local tabStart = 1
- for n=1,#tProcesses do
- tabEnd = tabStart + string.len( tProcesses[n].sTitle ) + 1
- if x >= tabStart and x <= tabEnd then
- selectProcess( n )
- redrawMenu()
- break
- end
- tabStart = tabEnd + 1
- end
- else
- -- Passthrough to current process
- local nX, nY = tProcesses[nCurrentProcess].window.getPosition()
- local nWidth, nHeight = tProcesses[nCurrentProcess].window.getSize()
- if x >= nX and x <= nX + nWidth + 2 then
- if y == nY then
- if x == nX + nWidth + 1 then
- killProcess( nCurrentProcess )
- elseif x == nX + nWidth then
- tProcesses[nCurrentProcess].window.setVisible( false )
- tProcesses[nCurrentProcess].hidden = true
- redrawScreen()
- for k, tProcess in pairs(tProcesses) do
- if not tProcesses[nCurrentProcess].hidden then
- selectProcess( k )
- end
- end
- else
- tProcesses[nCurrentProcess].dragX, tProcesses[nCurrentProcess].dragY = x - nX, y - nY
- end
- else
- tProcesses[nCurrentProcess].dragX, tProcesses[nCurrentProcess].dragY = nil, nil
- end
- if x > nX + nWidth and x < nX + nWidth + 2 and y > nY + nHeight and y < nY + nHeight + 2 then
- tProcesses[nCurrentProcess].oldWidth, tProcesses[nCurrentProcess].oldHeight = nWidth, nHeight
- tProcesses[nCurrentProcess].rsX, tProcesses[nCurrentProcess].rsY = x - nX - 1, y - nY - 1
- elseif tProcesses[nCurrentProcess] then
- if tProcesses[nCurrentProcess].rsX then
- if tProcesses[nCurrentProcess].rsX then resumeProcess( nCurrentProcess, "term_resize") end
- tProcesses[nCurrentProcess].dragX, tProcesses[nCurrentProcess].dragY = nil, nil
- tProcesses[nCurrentProcess].rsX, tProcesses[nCurrentProcess].rsY = nil, nil
- redrawScreen()
- end
- end
- else
- for k, tProcess in pairs(tProcesses) do
- local nX, nY = tProcess.window.getPosition()
- local nWidth, nHeight = tProcess.window.getSize()
- if x >= nX and x <= nX + nWidth + 2 and y > nY and y < nY + nHeight then
- selectProcess( k )
- redrawScreen()
- end
- end
- end
- resumeProcess( nCurrentProcess, sEvent, button, x - nX or 0, y - nY or 0 )
- if cullProcess( nCurrentProcess ) then
- setMenuVisible( true )
- redrawMenu()
- end
- end
- elseif sEvent == "mouse_drag" or sEvent == "mouse_scroll" then
- -- Other mouse event
- local p1, x, y = tEventData[2], tEventData[3], tEventData[4]
- if not (bShowMenu and y == h) then
- -- Passthrough to current process
- local nX, nY = tProcesses[nCurrentProcess].window.getPosition()
- if tProcesses[nCurrentProcess].dragX then
- -- Drag the window
- local dragX, dragY = tProcesses[nCurrentProcess].dragX, tProcesses[nCurrentProcess].dragY
- local nWidth, nHeight = tProcesses[nCurrentProcess].window.getSize()
- tProcesses[nCurrentProcess].window.reposition( x - dragX, y - dragY, nWidth + 2, nHeight + 2 )
- if #tProcesses < 8 then
- if tProcesses[nCurrentProcess].rsX then resumeProcess( nCurrentProcess, "term_resize") end
- redrawScreen()
- end
- redrawMenu()
- elseif tProcesses[nCurrentProcess] then
- if tProcesses[nCurrentProcess].rsX then
- -- Resize the window
- local dragX, dragY = tProcesses[nCurrentProcess].rsX, tProcesses[nCurrentProcess].rsY
- local nWidth, nHeight = tProcesses[nCurrentProcess].window.getSize()
- local oldWidth, oldHeight = tProcesses[nCurrentProcess].oldWidth, tProcesses[nCurrentProcess].oldHeight
- tProcesses[nCurrentProcess].window.reposition( nX, nY, math.max(oldWidth + 1 + (x - dragX) - nX, 8), math.max(oldHeight + 1 + (y - dragY) - nY, 4))
- redrawMenu()
- if #tProcesses < 8 then
- if tProcesses[nCurrentProcess].rsX then resumeProcess( nCurrentProcess, "term_resize") end
- redrawScreen()
- end
- else
- resumeProcess( nCurrentProcess, sEvent, p1, (x - nX) or 0, (y - nY) or 0 )
- end
- end
- if cullProcess( nCurrentProcess ) then
- setMenuVisible( true )
- redrawMenu()
- end
- end
- else
- if tProcesses[nCurrentProcess].rsX or tProcesses[nCurrentProcess].dragX then
- resumeProcess( nCurrentProcess, "term_resize")
- tProcesses[nCurrentProcess].dragX, tProcesses[nCurrentProcess].dragY = nil, nil
- tProcesses[nCurrentProcess].rsX, tProcesses[nCurrentProcess].rsY = nil, nil
- redrawScreen()
- end
- -- Other event
- -- Passthrough to all processes
- local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event
- for n=1,nLimit do
- resumeProcess( n, unpack( tEventData ) )
- end
- if cullProcesses() then
- setMenuVisible( true )
- redrawScreen()
- end
- end
- if bWindowsResized then
- -- Pass term_resize to all processes
- local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event
- for n=1,nLimit do
- resumeProcess( n, "term_resize" )
- end
- bWindowsResized = false
- if cullProcesses() then
- setMenuVisible( true )
- redrawScreen()
- end
- end
- end
- -- Shutdown
- term.redirect( parentTerm )
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- term.setCursorPos(1, 1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement