Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local component = require("component")
- local event = require("event")
- local term = require("term")
- local gpu = component.gpu
- local computer = require("computer")
- local shell = require("shell")
- local filesystem = require("filesystem")
- local unicode = require("unicode")
- -- Screen setup
- local w, h = gpu.getResolution()
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- gpu.fill(1, 1, w, h, " ")
- -- Window management
- local windows = {}
- local activeWindow = nil
- local draggedWindow = nil
- local resizingWindow = nil
- local dragOffsetX, dragOffsetY = 0, 0
- -- Start Menu
- local startMenuOpen = false
- local startMenuItems = {"File Explorer", "Terminal", "Settings", "Power"}
- -- Processes
- local processes = {}
- local function createWindow(x, y, width, height, title)
- local window = {
- x = x, y = y, width = width, height = height, title = title,
- content = {}, cursorX = 1, cursorY = 1, inputBuffer = "", history = {}, historyIndex = 0,
- minimized = false
- }
- table.insert(windows, window)
- return window
- end
- local function drawWindow(window)
- if window.minimized then
- -- Draw minimized representation
- gpu.setBackground(0x808080)
- gpu.fill(window.x, h, 10, 1, " ")
- gpu.set(window.x, h, window.title:sub(1, 10))
- return
- end
- -- Window border
- gpu.setBackground(0xCCCCCC)
- gpu.fill(window.x, window.y, window.width, window.height, " ")
- gpu.setBackground(0x0000AA)
- gpu.fill(window.x, window.y, window.width, 1, " ")
- gpu.setForeground(0xFFFFFF)
- gpu.set(window.x + 1, window.y, window.title)
- -- Close button
- gpu.setBackground(0xAA0000)
- gpu.set(window.x + window.width - 1, window.y, "X")
- -- Minimize button
- gpu.setBackground(0x00AA00)
- gpu.set(window.x + window.width - 2, window.y, "_")
- -- Content
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- for i, line in ipairs(window.content) do
- gpu.set(window.x + 1, window.y + i, unicode.sub(line, 1, window.width - 2))
- end
- -- Input buffer and cursor for terminal window
- if window == terminalWindow then
- local prompt = "> "
- local inputLine = prompt .. window.inputBuffer
- gpu.setForeground(0xFFFFFF) -- Set text color to white
- gpu.setBackground(0x000000) -- Set background to black
- gpu.fill(window.x + 1, window.y + #window.content + 1, window.width - 2, 1, " ") -- Clear the input line
- gpu.set(window.x + 1, window.y + #window.content + 1, inputLine)
- if computer.uptime() % 1 > 0.5 then -- Blinking cursor
- gpu.set(window.x + #inputLine + 1, window.y + #window.content + 1, "_")
- end
- end
- -- Resize handle
- gpu.setBackground(0x888888)
- gpu.set(window.x + window.width - 1, window.y + window.height - 1, "+")
- end
- local function drawAllWindows()
- gpu.setBackground(0x000088) -- Set a dark blue background
- gpu.fill(1, 1, w, h, " ") -- Clear the screen with the background color
- for _, window in ipairs(windows) do
- drawWindow(window)
- end
- end
- local function drawStartMenu()
- if startMenuOpen then
- gpu.setBackground(0x333333)
- gpu.fill(1, h-10, 20, 10, " ")
- for i, item in ipairs(startMenuItems) do
- gpu.set(2, h-10+i, item)
- end
- end
- end
- local function toggleStartMenu()
- startMenuOpen = not startMenuOpen
- drawAllWindows()
- drawStartMenu()
- end
- -- Terminal functionality
- local terminalWindow = createWindow(1, h - 15, w, 15, "NonoOS Terminal")
- activeWindow = terminalWindow
- local function writeToTerminal(text)
- for line in text:gmatch("[^\r\n]+") do
- table.insert(terminalWindow.content, line)
- end
- while #terminalWindow.content > terminalWindow.height - 2 do
- table.remove(terminalWindow.content, 1)
- end
- end
- local function captureOutput(f, ...)
- local oldWrite = io.write
- local buffer = ""
- io.write = function(...)
- local args = table.pack(...)
- for i = 1, args.n do
- buffer = buffer .. tostring(args[i])
- end
- end
- local result = table.pack(pcall(f, ...))
- io.write = oldWrite
- return buffer, table.unpack(result)
- end
- local function createFileExplorer()
- local window = createWindow(10, 5, 40, 20, "File Explorer")
- window.currentPath = "/"
- local function updateFileList()
- window.content = {}
- for file in filesystem.list(window.currentPath) do
- table.insert(window.content, file)
- end
- end
- updateFileList()
- return window
- end
- local function createSettingsWindow()
- local window = createWindow(20, 5, 40, 20, "Settings")
- window.content = {
- "1. Change background color",
- "2. Toggle start menu",
- "3. Adjust CPU usage calculation"
- }
- return window
- end
- local function executeCommand(command)
- writeToTerminal("> " .. command)
- if command == "exit" then
- return false
- elseif command == "clear" then
- terminalWindow.content = {}
- elseif command == "explorer" then
- createFileExplorer()
- elseif command == "settings" then
- createSettingsWindow()
- elseif command:sub(-4) == ".lua" then
- -- Run .lua files in a new window
- local scriptWindow = createWindow(10, 5, w - 20, h - 10, "Script: " .. command)
- local scriptPath = shell.resolve(command)
- if filesystem.exists(scriptPath) then
- local env = setmetatable({}, {__index = _G})
- env.print = function(...)
- local args = table.pack(...)
- local line = ""
- for i = 1, args.n do
- line = line .. tostring(args[i]) .. "\t"
- end
- table.insert(scriptWindow.content, line)
- end
- local chunk, err = loadfile(scriptPath, "t", env)
- if chunk then
- local process = coroutine.create(chunk)
- table.insert(processes, {co = process, window = scriptWindow})
- else
- table.insert(scriptWindow.content, "Error loading file: " .. tostring(err))
- end
- else
- table.insert(scriptWindow.content, "File not found: " .. command)
- end
- else
- local output, success, result = captureOutput(shell.execute, command)
- writeToTerminal(output)
- if not success then
- writeToTerminal("Error: " .. tostring(result))
- end
- end
- return true
- end
- -- CPU usage measurement
- local cpuUsage = 0
- local lastTime = computer.uptime()
- local function updateCPUUsage(elapsedTime)
- local currentTime = computer.uptime()
- local timeDiff = currentTime - lastTime
- lastTime = currentTime
- -- Calculate CPU usage based on how long the main loop took compared to the event timeout
- cpuUsage = (elapsedTime / timeDiff) * 100
- cpuUsage = math.min(100, math.max(0, cpuUsage))
- end
- -- Task Manager
- local taskManagerWindow = createWindow(w - 30, 1, 30, 7, "Task Manager")
- local function updateTaskManager()
- local totalMemory = computer.totalMemory()
- local freeMemory = computer.freeMemory()
- local usedMemory = totalMemory - freeMemory
- taskManagerWindow.content = {
- string.format("OS: NonoOS"),
- string.format("CPU: %.1f%%", cpuUsage),
- string.format("RAM: %d/%d KB", math.floor(usedMemory / 1024), math.floor(totalMemory / 1024)),
- string.format("Free: %d KB", math.floor(freeMemory / 1024)),
- string.format("Windows: %d", #windows),
- string.format("Processes: %d", #processes)
- }
- for i, process in ipairs(processes) do
- table.insert(taskManagerWindow.content, string.format("Process %d: %s", i, coroutine.status(process.co)))
- end
- end
- local function startResizing(window, x, y)
- resizingWindow = window
- dragOffsetX = window.x + window.width - x
- dragOffsetY = window.y + window.height - y
- end
- local function minimizeWindow(window)
- window.minimized = true
- end
- local function maximizeWindow(window)
- window.x = 1
- window.y = 2
- window.width = w
- window.height = h - 1
- end
- local function runProcesses()
- for i = #processes, 1, -1 do
- local process = processes[i]
- if coroutine.status(process.co) ~= "dead" then
- local ok, result = coroutine.resume(process.co)
- if not ok then
- table.insert(process.window.content, "Process error: " .. tostring(result))
- table.remove(processes, i)
- end
- else
- table.remove(processes, i)
- end
- end
- end
- -- Main loop
- local running = true
- while running do
- local loopStartTime = computer.uptime()
- drawAllWindows()
- drawStartMenu()
- updateTaskManager()
- local eventData = {event.pull(0.05)} -- Reduced timeout for responsiveness
- local eventType = eventData[1]
- local _, x, y = eventData[2], eventData[3], eventData[4]
- if eventType == "touch" then
- if x == 1 and y == h then
- toggleStartMenu()
- else
- local handled = false
- for i = #windows, 1, -1 do
- local window = windows[i]
- if x >= window.x and x < window.x + window.width and
- y >= window.y and y < window.y + window.height then
- if x == window.x + window.width - 1 and y == window.y then
- table.remove(windows, i) -- Close window
- elseif x == window.x + window.width - 2 and y == window.y then
- minimizeWindow(window) -- Minimize window
- elseif x == window.x + window.width - 1 and y == window.y + window.height - 1 then
- startResizing(window, x, y)
- else
- activeWindow = window
- draggedWindow = window
- dragOffsetX = x - window.x
- dragOffsetY = y - window.y
- -- Move window to top
- table.remove(windows, i)
- table.insert(windows, window)
- end
- handled = true
- break
- end
- end
- if not handled and activeWindow == terminalWindow then
- local command = terminalWindow.inputBuffer
- running = executeCommand(command)
- terminalWindow.inputBuffer = ""
- end
- end
- elseif eventType == "drag" then
- if draggedWindow then
- draggedWindow.x = math.max(1, math.min(w - draggedWindow.width, x - dragOffsetX))
- draggedWindow.y = math.max(1, math.min(h - draggedWindow.height, y - dragOffsetY))
- elseif resizingWindow then
- local newWidth = math.max(10, x - resizingWindow.x + dragOffsetX)
- local newHeight = math.max(5, y - resizingWindow.y + dragOffsetY)
- resizingWindow.width = math.min(newWidth, w - resizingWindow.x + 1)
- resizingWindow.height = math.min(newHeight, h - resizingWindow.y + 1)
- end
- elseif eventType == "drop" then
- draggedWindow = nil
- resizingWindow = nil
- elseif eventType == "key_down" then
- if activeWindow == terminalWindow then
- local char, code = eventData[3], eventData[4]
- if char == 13 then -- Enter key
- local command = terminalWindow.inputBuffer
- table.insert(terminalWindow.history, command)
- terminalWindow.historyIndex = #terminalWindow.history + 1
- running = executeCommand(command)
- terminalWindow.inputBuffer = ""
- elseif code == 14 then -- Backspace
- terminalWindow.inputBuffer = unicode.sub(terminalWindow.inputBuffer, 1, -2)
- elseif code == 200 then -- Up arrow (command history)
- if terminalWindow.historyIndex > 1 then
- terminalWindow.historyIndex = terminalWindow.historyIndex - 1
- terminalWindow.inputBuffer = terminalWindow.history[terminalWindow.historyIndex]
- end
- elseif code == 208 then -- Down arrow (command history)
- if terminalWindow.historyIndex < #terminalWindow.history then
- terminalWindow.historyIndex = terminalWindow.historyIndex + 1
- terminalWindow.inputBuffer = terminalWindow.history[terminalWindow.historyIndex]
- elseif terminalWindow.historyIndex == #terminalWindow.history then
- terminalWindow.historyIndex = terminalWindow.historyIndex + 1
- terminalWindow.inputBuffer = ""
- end
- else
- local char = unicode.char(char)
- terminalWindow.inputBuffer = terminalWindow.inputBuffer .. char
- end
- end
- end
- runProcesses()
- local loopEndTime = computer.uptime()
- local elapsedTime = loopEndTime - loopStartTime
- updateCPUUsage(elapsedTime)
- end
- -- Clean up
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- term.clear()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement