mirror of
https://github.com/LDDestroier/CC/
synced 2024-11-08 19:09:58 +00:00
Add files via upload
This commit is contained in:
parent
914c549ee7
commit
279fc3b7c3
285
windont/windont-shell.lua
Normal file
285
windont/windont-shell.lua
Normal file
@ -0,0 +1,285 @@
|
||||
local windont = require "windont"
|
||||
windont.default.alwaysRender = false
|
||||
|
||||
local scr_x, scr_y = term.getSize()
|
||||
local keysDown = {}
|
||||
|
||||
local instances = {}
|
||||
local knownNames = {
|
||||
["rom/programs/shell.lua"] = "CraftOS Shell",
|
||||
["rom/programs/edit.lua"] = "Edit",
|
||||
["rom/programs/gps.lua"] = "GPS",
|
||||
["rom/programs/shutdown.lua"] = "Shutdown",
|
||||
["rom/programs/monitor.lua"] = "Monitor Redirect",
|
||||
["rom/programs/emu.lua"] = "Emu (CCEmuX)",
|
||||
["rom/programs/exit.lua"] = "Goodbye!",
|
||||
["rom/programs/lua.lua"] = "Lua Interpreter",
|
||||
|
||||
["rom/programs/fun/adventure.lua"] = "Adventure",
|
||||
["rom/programs/fun/worm.lua"] = "Worm",
|
||||
["rom/programs/fun/dj.lua"] = "DJ",
|
||||
["rom/programs/fun/hello.lua"] = "Hello world!",
|
||||
|
||||
["rom/programs/turtle/dance.lua"] = "Dance!",
|
||||
["rom/programs/turtle/craft.lua"] = "Craft",
|
||||
["rom/programs/turtle/excavate.lua"] = "Excavate",
|
||||
["rom/programs/turtle/refuel.lua"] = "Refueling...",
|
||||
["rom/programs/turtle/go.lua"] = "Go (Turtle)",
|
||||
["rom/programs/turtle/turn.lua"] = "Turn (Turtle)",
|
||||
|
||||
["rom/programs/http/pastebin.lua"] = "Pastebin",
|
||||
["rom/programs/http/wget.lua"] = "Wget",
|
||||
|
||||
["rom/programs/pocket/falling.lua"] = "Falling",
|
||||
|
||||
["rom/programs/rednet/chat.lua"] = "Chat",
|
||||
["rom/programs/rednet/repeat.lua"] = "Rednet Repeat",
|
||||
|
||||
["rom/programs/command/exec.lua"] = "Exec (Command)",
|
||||
["rom/programs/command/commands.lua"] = "Commands",
|
||||
}
|
||||
|
||||
-- events that can only be passed if the instance is focused
|
||||
local FocusEvents = {
|
||||
["mouse_click"] = true,
|
||||
["mouse_drag"] = true,
|
||||
["mouse_up"] = true,
|
||||
["key"] = true,
|
||||
["key_up"] = true,
|
||||
["char"] = true,
|
||||
["monitor_touch"] = true,
|
||||
["paste"] = true,
|
||||
-- mouse_scroll is intentionally excluded
|
||||
}
|
||||
|
||||
-- events that must have their XY values altered according to the position of the window
|
||||
local CoordinateEvents = {
|
||||
["mouse_click"] = {3, 4},
|
||||
["mouse_drag"] = {3, 4},
|
||||
["mouse_up"] = {3, 4},
|
||||
["mouse_scroll"] = {3, 4}
|
||||
}
|
||||
|
||||
local desktop = windont.newWindow(1, 1, scr_x, scr_y, {
|
||||
backColor = "9"
|
||||
})
|
||||
local overlay = windont.newWindow(1, 1, scr_x, scr_y, {
|
||||
backColor = "-"
|
||||
})
|
||||
desktop.redraw()
|
||||
|
||||
local newInstance = function(x, y, width, height, program, pName, addBorder)
|
||||
local output = {}
|
||||
if addBorder then
|
||||
output.mainWindow = windont.newWindow(x, y, width, height + 1, {
|
||||
baseTerm = desktop,
|
||||
alwaysRender = false,
|
||||
backColor = "7"
|
||||
})
|
||||
output.termWindow = windont.newWindow(1, 2, width, height, {
|
||||
baseTerm = output.mainWindow,
|
||||
alwaysRender = true,
|
||||
})
|
||||
else
|
||||
output.mainWindow = windont.newWindow(x, y, width + 2, height + 2, {
|
||||
baseTerm = desktop,
|
||||
alwaysRender = false,
|
||||
backColor = "7"
|
||||
})
|
||||
output.termWindow = windont.newWindow(2, 2, width, height, {
|
||||
baseTerm = output.mainWindow,
|
||||
alwaysRender = true,
|
||||
})
|
||||
end
|
||||
|
||||
local mw = output.mainWindow -- contains the titlebar, and is the base terminal for termWindow
|
||||
local tw = output.termWindow -- contains the program's terminal output
|
||||
|
||||
-- pausing will probably be implemented later
|
||||
output.paused = false
|
||||
output.timeMod = 0
|
||||
output.clockMod = 0
|
||||
output.timers = {}
|
||||
|
||||
output.alive = true
|
||||
output.focused = true
|
||||
output.title = pName or (type(program) == "string" and (knownNames[fs.combine("", program)] or fs.getName(program))) or tostring(program)
|
||||
output.writeTitleBar = function()
|
||||
mw.setCursorPos(1, 1)
|
||||
if output.focused then
|
||||
mw.setTextColor(colors.white)
|
||||
else
|
||||
mw.setTextColor(colors.lightGray)
|
||||
end
|
||||
mw.setBackgroundColor(colors.gray)
|
||||
mw.clearLine()
|
||||
|
||||
if #output.title <= (mw.meta.width - 4) then
|
||||
mw.write(output.title) -- write full title
|
||||
else
|
||||
mw.write(output.title:sub(1, mw.meta.width - 7) .. "...") -- draw abreviated title
|
||||
end
|
||||
mw.setCursorPos(mw.meta.width - 3, 1)
|
||||
mw.write(" \22\94\215") -- minimize / maximize / close
|
||||
end
|
||||
|
||||
if type(program) == "string" then
|
||||
output.main = function()
|
||||
tw.clear()
|
||||
return shell.run(program)
|
||||
end
|
||||
elseif type(program) == "function" then
|
||||
output.main = program
|
||||
end
|
||||
|
||||
--local env = {}
|
||||
--setmetatable(env, {__index = _G})
|
||||
--setfenv(output.main, env)
|
||||
|
||||
output.coroutine = coroutine.create(output.main)
|
||||
output.cFilter = nil
|
||||
|
||||
for i = 1, #instances do
|
||||
instances[i].focused = false
|
||||
end
|
||||
|
||||
table.insert(instances, 1, output)
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
local render = function()
|
||||
local wins = {}
|
||||
for i = 1, #instances do
|
||||
wins[i] = instances[i].mainWindow
|
||||
end
|
||||
windont.render({force = true}, table.unpack(wins))
|
||||
windont.render({}, overlay, desktop)
|
||||
end
|
||||
|
||||
local instanceBoxCheck = function(i, x, y)
|
||||
return (
|
||||
x < 1 or x > instances[i].termWindow.meta.width or
|
||||
y < 1 or y > instances[i].termWindow.meta.height
|
||||
)
|
||||
end
|
||||
|
||||
local resumeInstance = function(i, _evt, isCoordinateEvent)
|
||||
local evt = {}
|
||||
for k,v in pairs(_evt) do
|
||||
evt[k] = v
|
||||
end
|
||||
if CoordinateEvents[evt[1]] then
|
||||
evt[3] = evt[3] - instances[i].mainWindow.meta.x + instances[i].termWindow.meta.x
|
||||
evt[4] = evt[4] - instances[i].mainWindow.meta.y + instances[i].mainWindow.meta.y - 1
|
||||
isCoordinateEvent = true
|
||||
end
|
||||
repeat
|
||||
if (isCoordinateEvent and not instanceBoxCheck(i, evt[3], evt[4])) then
|
||||
break
|
||||
end
|
||||
oldTerm = term.redirect(instances[i].termWindow)
|
||||
success, result = coroutine.resume(instances[i].coroutine, table.unpack(evt))
|
||||
term.redirect(oldTerm)
|
||||
if success then
|
||||
instances[i].cFilter = result
|
||||
else
|
||||
instances[i].alive = false
|
||||
end
|
||||
until true
|
||||
end
|
||||
|
||||
local main = function()
|
||||
|
||||
newInstance(3, 3, 20, 10, "rom/programs/shell.lua", nil)
|
||||
newInstance(8, 5, 20, 10, "rom/programs/shell.lua", nil)
|
||||
|
||||
local evt, success, result, oldTerm
|
||||
local cx, cy
|
||||
local isCoordinateEvent
|
||||
local usedCoordinateEvent
|
||||
local usingUI = false -- if true, cannot send events to instances. Only set to true when interacting with the UI
|
||||
-- handles input system
|
||||
local keyTimer = os.startTimer(0.05)
|
||||
|
||||
while true do
|
||||
evt = {coroutine.yield()}
|
||||
if evt[1] == "key" and not evt[3] then
|
||||
keysDown[evt[2]] = 0
|
||||
elseif evt[1] == "key_up" then
|
||||
keysDown[evt[2]] = nil
|
||||
end
|
||||
if evt[1] == "timer" and evt[2] == keyTimer then
|
||||
keyTimer = os.startTimer(0.05)
|
||||
for k,v in pairs(keysDown) do
|
||||
keysDown[k] = v + 0.05
|
||||
end
|
||||
|
||||
-- move windows with arrow keys (for now)
|
||||
if keysDown[keys.right] then
|
||||
desktop.clear()
|
||||
instances[1].mainWindow.reposition(instances[1].mainWindow.meta.x + 1, instances[1].mainWindow.meta.y)
|
||||
end
|
||||
if keysDown[keys.left] then
|
||||
desktop.clear()
|
||||
instances[1].mainWindow.reposition(instances[1].mainWindow.meta.x - 1, instances[1].mainWindow.meta.y)
|
||||
end
|
||||
if keysDown[keys.up] then
|
||||
desktop.clear()
|
||||
instances[1].mainWindow.reposition(instances[1].mainWindow.meta.x, instances[1].mainWindow.meta.y - 1)
|
||||
end
|
||||
if keysDown[keys.down] then
|
||||
desktop.clear()
|
||||
instances[1].mainWindow.reposition(instances[1].mainWindow.meta.x, instances[1].mainWindow.meta.y + 1)
|
||||
end
|
||||
else
|
||||
usedCoordinateEvent = false
|
||||
isCoordinateEvent = false
|
||||
for i = 1, #instances do
|
||||
instances[i].writeTitleBar()
|
||||
if (not usingUI) and (instances[i].cFilter == evt[1] or instances[i].cFilter == "terminate" or (not instances[i].cFilter)) then
|
||||
if (instances[i].focused or not FocusEvents[evt[1]]) then
|
||||
resumeInstance(i, evt, isCoordinateEvent)
|
||||
if CoordinateEvents[evt[1]] then
|
||||
usedCoordinateEvent = true
|
||||
end
|
||||
else
|
||||
if (not instances[i].focused) and (evt[1] == "mouse_click") then
|
||||
if not usedCoordinateEvent then
|
||||
instances[i].focused = true
|
||||
instances[1].focused = false
|
||||
resumeInstance(1, evt, isCoordinateEvent)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- check for dead instances
|
||||
for i = #instances, 1, -1 do
|
||||
if not instances[i].alive then
|
||||
if instances[i].focused then
|
||||
if instances[i - 1] then
|
||||
instances[i - 1].focused = true
|
||||
elseif instances[i + 1] then
|
||||
instances[i + 1].focused = true
|
||||
end
|
||||
end
|
||||
table.remove(instances, i)
|
||||
desktop.clear()
|
||||
end
|
||||
end
|
||||
|
||||
-- make sure the focused window is on top
|
||||
for i = 1, #instances do
|
||||
if instances[i].focused then
|
||||
instances[i], instances[1] = instances[1], instances[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
render()
|
||||
end
|
||||
end
|
||||
|
||||
main()
|
Loading…
Reference in New Issue
Block a user