Created
February 23, 2020 23:48
-
-
Save watsuprico/a3ac9f9b1b5afefdc1a2c0c9d2491421 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Windowed (API/Program) | |
For ComputerCraft | |
Free for use. :^) (But please do keep this here) | |
If you make any modifications that make this program better please tell me and send a copy. If your mod is good I'll add it to the newest update ;^) | |
v1.0 (7/5/16)-(REDO 7/7/16)-(7/11/16) | |
v2.0 (Complete redo, 4/4/17 (For RitoOS 2.0.12)) | |
]]-- | |
--[[ | |
Windows[ID].posX = int // Where the top X of the window is | |
Windows[ID].posY = int // Where the top Y of the window is | |
Windows[ID].width = int // The width of the window | |
Windows[ID].height = int // The height of the window | |
Windows[ID].borderless = bool // The the window have a border? | |
Windows[ID].canResize = bool // Can the window be resized? | |
Windows[ID].visible = bool // Is the window minimized to the task bar? (If Windowed.disallowHiding is true, then this can't be true if Windows[ID].visibleInTaskbar is true) | |
Windows[ID].visibleInTaskbar = bool // Is the window visible in the taskbar? | |
Windows[ID].windowBorder // This is the term object of the window border | |
Windows[ID].controlWindow // This is what the program outputs to | |
Windows[ID].secureKey = {} // This is used to verify the identity of windows | |
Window[ID].adminKey = {} // This is to check if the window has administrator privilege | |
]] | |
local masterNative = term.native() | |
local masterCurrent = term.current() | |
local oTermCurrent = term.current | |
local oTermColor = term.isColor | |
--[[|| Setup for sandboxing ||]] | |
local nativeShutdown = os.shutdown -- We use this to shutdown later, (We have to change os.shutdown to just close the window that called it... same for rebooting) | |
local nativeReboot = os.reboot | |
local nativeRedirect = term.redirect | |
local nativeCurrent = term.current | |
local nativePullEventRaw = os.pullEventRaw -- Security | |
-- I want power events to just close the Windows, but I don't know the ID yet. | |
os.shutdown = nil | |
os.reboot = nil | |
--[[|| Table definitions ||]]-- | |
local Windows = {} | |
local WindowedS = {["version"]="1.0"} -- This table holds all our settings, keys, term objects, etc | |
WindowedS.keys = {} -- Key mappings | |
WindowedS.default = {} | |
WindowedS.adminKeys = {} -- We check if the Window is administrator level by comparing a table that is different for every window. | |
WindowedS.windowKeys = {} -- We have to check the key to something the window can't access | |
Windowed = {} -- For the API part | |
local color = {} | |
color.taskbar = {} | |
color.windows = {} | |
local taskbar = {} | |
taskbar.buttons = {} | |
taskbar.menu = {} | |
-- [[|| Strings ||]]-- | |
taskbar.buttons.menuTitle = "M" -- What the left taskbar button is labeled as (Like "Start" in Windows) | |
taskbar.menu.shutdownText = "Shutdown" -- This is how the buttons for the different actions appear in the taskbar menu | |
taskbar.menu.restartText = "Restart" | |
taskbar.menu.shellText = "Shell" | |
taskbar.menu.exitText = "Exit" -- This SHOULD exit the program. I would add a catch so if the program exits whatever called it will logout the user. | |
--[[|| Locations / Sizes ||]]-- | |
WindowedS.posX, WindowedS.posY = 1,1 | |
WindowedS.widthOffset, WindowedS.heightOffset = 0,0 | |
WindowedS.width, WindowedS.height = masterNative.getSize() -- Notice! Updated on term_resize (use the offsets) | |
WindowedS.width, WindowedS.height = WindowedS.width+WindowedS.widthOffset, WindowedS.height+WindowedS.heightOffset | |
--Default window settings | |
WindowedS.default.width, WindowedS.default.height = 30,13 | |
WindowedS.default.posX, WindowedS.default.posY = 2,2 | |
--Taskbar | |
taskbar.posX, taskbar.posY = WindowedS.posX, WindowedS.posY -- The location of the taskbar. I recommend not changing this. See onTop to change the location of the taskbar. | |
taskbar.widthOffset, taskbar.heightOffset = 0, 0 -- The offsets used when generating the width / height of the taskbar. I also have not tested the height offset, but I know most things do not use it. | |
taskbar.width, taskbar.height = WindowedS.width+taskbar.widthOffset, 1+taskbar.heightOffset -- Height should not be changed! It has unknown effects | Width is updated when the taskbar is drawn, use the off set instead | |
taskbar.onTop = false -- Where the taskbar is located. TRUE = top, FALSE = bottom. The positions update around this. | |
--Taskbar widths | |
taskbar.buttons.menuWidth = string.len(taskbar.buttons.menuTitle)+3 -- Used below | |
taskbar.buttons.windowsWidth = (taskbar.width-(taskbar.buttons.menuWidth+10))/1 -- This defines how much space is allocated per window in the taskbar. | |
taskbar.menu.posX, taskbar.menu.width = 1, 10 -- Width will need to be the longest string + 2 | |
taskbar.menu.posY, taskbar.menu.height = 1,6 | |
if not taskbar.onTop then taskbar.menu.posY = (taskbar.posY+WindowedS.height-1)-taskbar.menu.height end | |
--Taskbar menu items locations | |
taskbar.menu.shutdownY = 2 -- The location of 'Shutdown' on the menu (1. this is only used when checking where you click; 2. you have to manually change the menu layout )^: ) (Also, pretend this is based of the top left *1,1*) (Based of the taskbar.menu.posY) | |
taskbar.menu.restartY = 3 | |
taskbar.menu.shellY = 4 | |
taskbar.menu.exitY = 5 | |
--[[|| Key shortcut mapping ||]]-- | |
-- Key map: computercraft.info/wiki/images/8/81/CC-Keyboard-Charcodes.png | |
WindowedS.keys.super = 184 -- RAlt | Press and hold to use the below keyboard shortcuts | |
WindowedS.keys.fullScreen = 200 -- Up | Press to enter full screen on the active window | |
WindowedS.keys.normalScreen = 208 -- Down | Press to exit full screen on the active window | |
WindowedS.keys.close = 211 -- Del | Press to close the active window | |
WindowedS.keys.closeAll = 207 --End | Press to close every window | |
WindowedS.keys.menu = 50 -- M | Press to open the menu (Can't navigate with keyboard shortcuts yet!) | |
WindowedS.keys.switchWindow = 16 -- Q | Like ALT+TAB in Windows, switch to a different window | |
WindowedS.keys.runShell = 31 -- S | Open a shell prompt | |
WindowedS.keys.compatibilityMode = 46 -- C | Enter compatibility mode on the active window (Fullscreen + no title bar) | |
WindowedS.keys.exitLoop = 18 -- E | Exit the event listener loop (close the program) | |
WindowedS.keys.moveWindow = 157 -- Right CTRL | Hold this and the super key to use the arrow keys to move the active window | |
WindowedS.shellLocation = "/rom/programs/shell" -- When you use the key board shortcut or the shell button in the taskbar menu | |
WindowedS.useBackgroundImage = false -- I would keep this disabled. (Enabled will force the background to redraw every time a window is moved, created, or removed. (It'll flicker like hell.)) | |
WindowedS.backgroundImage = "zlog" -- If a background is enabled then this is the image loaded | |
WindowedS.backgroundColor = colors.lightBlue | |
WindowedS.displayClock = true -- Show the clock in the far right | |
WindowedS.eventUpdates = 0 -- 0 | Update nothing . 1 | Update active window . 2 | Update all | |
WindowedS.allowCompatibilityMode = true -- Allow windows to enter compatibility mode ((Fullscreen + no title bar)) | |
WindowedS.showWindowID = true -- Show the ID of the window in the window title | |
--Security | |
WindowedS.bypassKeyCheck = true -- If enabled then any window can modify other window's properties | |
WindowedS.randomness = 0xFFFF -- The max a key a be (math.random(0, <this setting>)) Doesn't have to be HEX. | |
WindowedS.keyLength = 100 -- The normal key length that every window uses | |
WindowedS.adminKeyLength = 150 -- The administrator key length for windows that have administrator privilege | |
-- [[|| Functions ||]]-- | |
taskbar.menu.shutdown = nativeShutdown -- Called when the user clicks "Shutdown" in the menu | |
taskbar.menu.restart = nativeReboot -- Like above just for restart | |
--[[|| Colors ||]]-- | |
--Taskbar colors | |
color.taskbar.menuButtonBackground = colors.gray -- Used in the menu too | |
color.taskbar.menuButtonText = colors.white | |
color.taskbar.background = colors.lightGray | |
color.taskbar.text = colors.white | |
color.taskbar.textActive = colors.white -- Used on the active window | |
color.taskbar.backgroundActive = colors.gray | |
--Top bar (title bar) of Windows | |
color.windows.titleBarText = colors.white | |
color.windows.titleBarTextActive = colors.white -- When the window is currently active | |
color.windows.titleBarBackground = colors.lightGray | |
color.windows.titleBarBackgroundActive = colors.gray -- When the window is currently active | |
--Window backgrounds | |
color.windows.borderBackgroundColor = colors.lightGray | |
color.windows.borderBackgroundColorActive = colors.gray -- When the window is currently active | |
--Window buttons | |
color.windows.closeButtonText = colors.white | |
color.windows.closeButtonTextActive = colors.white -- When you click the close button | |
color.windows.closeButtonBackground = colors.red | |
color.windows.closeButtonBackgroundActive = colors.orange -- When you click the close button | |
color.windows.minimizeText = colors.white -- The background is the title-bar background. (Also used for maximize button) | |
color.windows.resizeTab = colors.green | |
color.windows.resizeTabActive = colors.orange -- When you click and are resizing a window | |
if not term.isColor() then -- No color on non-advance computers | |
color.windows.closeButtonBackground = colors.black -- I have this here, but you can't click it on non-advance computers anyways :^\ | |
color.windows.closeButtonBackgroundActive = colors.gray | |
color.windows.resizeTab = colors.gray | |
color.windows.resizeTabActive = colors.black | |
WindowedS.backgroundColor = colors.white -- We can't have this being a color on non-advance computers | |
end | |
--[[|| Term Objects ||]]-- | |
WindowedS.term = window.create(masterNative,WindowedS.posX,WindowedS.posY,WindowedS.width,WindowedS.height,true) -- We dump the taskbar, windows, etc in here. | |
if taskbar.onTop then | |
WindowedS.windowArea = window.create(WindowedS.term,WindowedS.posX,taskbar.posY+1,WindowedS.width,WindowedS.height-taskbar.height,true) -- All the windows are located in this term object | |
WindowedS.taskbarArea = window.create(WindowedS.term,taskbar.posX,taskbar.posY,taskbar.width,taskbar.height,true) -- The taskbar is located in this term object | |
else WindowedS.windowArea = window.create(WindowedS.term,WindowedS.posX,1,WindowedS.width,WindowedS.height-taskbar.height,true) WindowedS.taskbarArea = window.create(WindowedS.term,taskbar.posX,taskbar.posY+WindowedS.height-1,taskbar.width,taskbar.height,true) end | |
WindowedS.taskbarMenuArea = window.create(WindowedS.windowArea,taskbar.menu.posX,taskbar.menu.posY,taskbar.menu.width,taskbar.menu.height,false) -- The taskbar menu | |
WindowedS.windowTrap = window.create(WindowedS.term, -1,-1,1,1,false) -- Dump output here if anything else. Output shouldn't go here unless something is messed up. | |
-- I want nothing to escape a window's control area | |
term.native = function() | |
return WindowedS.windowTrap | |
end | |
-- Simple declares | |
taskbar.menuOpened = false | |
WindowedS.windowArea.setCursorBlink(false) | |
WindowedS.taskbarArea.setCursorBlink(false) | |
WindowedS.taskbarMenuArea.setCursorBlink(false) | |
-- Message box | |
local function drawAlertBox(title, message1, message2, message3, allowButton, denyButton, highLevel, textBox) | |
WindowedS.drawingBox = true | |
local X,Y = masterNative.getSize() | |
local X,Y = X,Y -- calibrate | |
local posX = math.floor(X/5)-3 | |
local posY = math.floor(Y/3) | |
local sizeX = math.floor(X/1.5)+6 | |
local sizeY = math.floor(Y/2) | |
if title == nil or message1 == nil then return false end | |
local message2 = message2 or "" | |
local message3 = message3 or "" | |
local textBoxText = "" local hidenText = true local hideButton = "Show" local text = "" | |
local buttonAllowX, buttonAllowY = math.floor((sizeX/2)-(string.len(allowButton)+3)+1), math.floor(sizeY-1) | |
local buttonDenyX, buttonDenyY = math.floor((sizeX/2)+1)+1, math.floor(sizeY-1) | |
if highLevel then | |
BoxBG = window.create(masterNative,1,1,X,Y,true) | |
BoxBG.setBackgroundColor(colors.lightBlue) | |
BoxBG.clear() | |
Box = window.create(masterNative,posX,posY,sizeX,sizeY,true) | |
WindowedS.term.setVisible(false) | |
else | |
Box = window.create(masterNative,posX,posY,sizeX,sizeY,true) | |
end | |
local oldtopbarBG, oldBG = colors.black, colors.gray | |
local function drawBox(Box, topbarBG, BG, textBoxText, hidenText, hideButton, selection) | |
topbarBG = topbarBG or oldtopbarBG | |
BG = BG or oldBG | |
--Title bar | |
Box.setTextColor(colors.white) Box.setBackgroundColor(BG) Box.clear() Box.setBackgroundColor(topbarBG) Box.setCursorPos(1,1) Box.clearLine() | |
Box.setCursorPos(math.floor((sizeX/2)-(string.len(title)/2)+1),1) | |
Box.write(title .. "\n") | |
Box.setBackgroundColor(BG) | |
-- Message | |
Box.setCursorPos(1,3) if (string.len(message1)<sizeX) then Box.setCursorPos(math.floor((sizeX/2)-(string.len(message1)/2)+1),3) end | |
Box.write(message1) | |
Box.setCursorPos(1,4) if (string.len(message2)<sizeX) then Box.setCursorPos(math.floor((sizeX/2)-(string.len(message2)/2)+1),4) end | |
Box.write(message2) | |
Box.setCursorPos(1,5) | |
if not textBox then if (string.len(message3)<sizeX) then Box.setCursorPos(math.floor((sizeX/2)-(string.len(message3)/2)+1),5) end Box.write(message3) else | |
Box.setCursorPos(2,5) Box.setBackgroundColor(colors.blue) local f=2 while f < sizeX do Box.write(" ") f=f+1 end Box.setCursorPos(2,5) | |
local text = "" | |
if string.len(textBoxText) < sizeX-2 and string.len(textBoxText) ~= 0 then text = string.sub(textBoxText, 0, string.len(textBoxText)) | |
else text = string.sub(textBoxText, math.abs(sizeX-2)*-1, string.len(textBoxText)) Box.setTextColor(colors.lightGray) end | |
if hidenText then text=text:gsub(".","*") end | |
Box.write(text) Box.setTextColor(colors.white) | |
Box.setCursorPos(math.floor((sizeX/2)-(string.len(hideButton)/2)), 6) if hidenText then Box.setBackgroundColor(colors.red) else Box.setBackgroundColor(colors.green) end | |
Box.write(" "..hideButton.." ") | |
end | |
--Buttons | |
if allowButton ~= nil and allowButton ~= "" then | |
Box.setCursorPos(buttonAllowX,buttonAllowY) Box.setBackgroundColor(colors.green) | |
if selection == "left" then Box.write(">"..allowButton.."<") else Box.write(" "..allowButton.." ") end | |
end | |
if denyButton ~= nil and denyButton ~= "" then | |
Box.setCursorPos(buttonDenyX,buttonDenyY) Box.setBackgroundColor(colors.red) | |
if selection == "right" then Box.write(">"..denyButton.."<") else Box.write(" "..denyButton.." ") end | |
end | |
Box.setBackgroundColor(BG) | |
oldtopbarBG = topbarBG | |
oldBG = BG | |
end | |
drawBox(Box, colors.black, colors.gray, textBoxText, hidenText, hideButton, "left") | |
local selection = "left" | |
while true do | |
local e, button = os.pullEventRaw() | |
if e == "key" and button == 203 then | |
selection = "left" | |
drawBox(Box, nil, nil, textBoxText, hidenText, hideButton, selection) | |
elseif e == "key" and button == 205 then | |
selection = "right" | |
drawBox(Box, nil, nil, textBoxText, hidenText, hideButton, selection) | |
elseif e == "key" and textBox and button == keys.backspace then | |
if string.len(textBoxText) >= 1 then textBoxText = string.sub(textBoxText,1,string.len(textBoxText)-1) end | |
drawBox(Box, nil, nil, textBoxText, hidenText, hideButton, selection) | |
elseif e == "key" and textBox and button == keys.delete then | |
textBoxText = "" | |
drawBox(Box, nil, nil, textBoxText, hidenText, hideButton, selection) | |
elseif e == "key" and button == keys.enter then | |
if background then BoxBG.setVisible(false) else Box.setVisible(false) end Box = nil BoxBG = nil drawBox = nil WindowedS.term.setVisible(true) WindowedS.term.redraw() | |
break | |
elseif e == "char" and textBox then | |
textBoxText = textBoxText..button | |
drawBox(Box, nil, nil, textBoxText, hidenText, hideButton, selection) | |
end -- What event? | |
end -- Main while | |
local a | |
if selection == "left" then a = true else a = false end | |
WindowedS.drawingBox = false | |
if textBox then return a, textBoxText else return a end | |
end | |
--End | |
-- Taskbar | |
local function makeString(len) | |
local string="" | |
for a=0, len do | |
string=string.." " | |
end | |
return string | |
end | |
local function drawTaskbar() | |
taskbar.width, taskbar.height = WindowedS.width+taskbar.widthOffset, 1+taskbar.heightOffset | |
if not taskbar.onTop then WindowedS.taskbarArea.reposition(taskbar.posX,taskbar.posY+WindowedS.height-1,taskbar.width,taskbar.height) | |
else WindowedS.taskbarArea.reposition(taskbar.posX,taskbar.posY,taskbar.width,taskbar.height) end | |
WindowedS.taskbarArea.setBackgroundColor(color.taskbar.background) WindowedS.taskbarArea.setTextColor(color.taskbar.text) WindowedS.taskbarArea.clear() | |
WindowedS.taskbarArea.setCursorPos(1,1) WindowedS.taskbarArea.setBackgroundColor(color.taskbar.menuButtonBackground) WindowedS.taskbarArea.setTextColor(color.taskbar.menuButtonText) | |
WindowedS.taskbarArea.write(" "..taskbar.buttons.menuTitle.." ") | |
WindowedS.taskbarArea.setBackgroundColor(color.taskbar.background) WindowedS.taskbarArea.setTextColor(color.taskbar.text) WindowedS.taskbarArea.write("|") | |
local x=string.len(" "..taskbar.buttons.menuTitle.." |") | |
local a=0 for _ in pairs(Windows) do if Windows[_] ~= nil then a=a+1 end end | |
local correct=0 if WindowedS.displayClock then correct=string.len("| "..textutils.formatTime(os.time(), false).." ") end | |
taskbar.buttons.windowsWidth = math.floor((taskbar.width-(string.len(" "..taskbar.buttons.menuTitle.." |")+correct))/a) | |
for ID in pairs(Windows) do if Windows[ID] ~= nil then if Windows[ID].visibleInTaskbar or not Windows[ID].visible then | |
if Windows[ID].priorityLevel == 0 and Windows[ID].visible then WindowedS.taskbarArea.setTextColor(color.taskbar.textActive) WindowedS.taskbarArea.setBackgroundColor(color.taskbar.backgroundActive) | |
else WindowedS.taskbarArea.setBackgroundColor(color.taskbar.background) WindowedS.taskbarArea.setTextColor(color.taskbar.text) end | |
local title = Windows[ID].title or "Program" | |
if Windows[ID].compatibilityMode then title = "{C} "..title end | |
local x=x or 0 | |
if string.len(title)+2 > taskbar.buttons.windowsWidth then | |
WindowedS.taskbarArea.write(string.sub(title,1,taskbar.buttons.windowsWidth-2).."..") | |
Windows[ID].taskbarStartX = x x=x+string.len(string.sub(title,1,taskbar.buttons.windowsWidth-2).."..") Windows[ID].taskbarEndX=x | |
else | |
WindowedS.taskbarArea.write(" "..title.." ") | |
Windows[ID].taskbarStartX = x | |
x=x+string.len(" "..title.." ") | |
Windows[ID].taskbarEndX = x | |
end | |
end end end | |
WindowedS.taskbarArea.setBackgroundColor(color.taskbar.background) WindowedS.taskbarArea.setTextColor(color.taskbar.text) | |
if WindowedS.displayClock then WindowedS.taskbarArea.setCursorPos(taskbar.width-9,1) WindowedS.taskbarArea.write("| "..textutils.formatTime(os.time(), false).."") end | |
WindowedS.taskbarArea.redraw() | |
end | |
local function drawTaskbarMenu() | |
if taskbar.menuOpened then | |
-- Draw the menu | |
WindowedS.taskbarMenuArea.setCursorPos(1,1) WindowedS.taskbarMenuArea.setBackgroundColor(color.taskbar.menuButtonBackground) WindowedS.taskbarMenuArea.setTextColor(color.taskbar.menuButtonText) | |
WindowedS.taskbarMenuArea.clear() | |
WindowedS.taskbarMenuArea.setCursorPos(1,taskbar.menu.shutdownY) WindowedS.taskbarMenuArea.write(" "..taskbar.menu.shutdownText.." ") | |
WindowedS.taskbarMenuArea.setCursorPos(1,taskbar.menu.restartY) WindowedS.taskbarMenuArea.write(" "..taskbar.menu.restartText.." ") | |
WindowedS.taskbarMenuArea.setCursorPos(1,taskbar.menu.shellY) WindowedS.taskbarMenuArea.write(" "..taskbar.menu.shellText.." ") | |
WindowedS.taskbarMenuArea.setCursorPos(1,taskbar.menu.exitY) WindowedS.taskbarMenuArea.write(" "..taskbar.menu.exitText.." ") | |
WindowedS.taskbarMenuArea.setVisible(true) | |
WindowedS.taskbarMenuArea.redraw() | |
else | |
WindowedS.taskbarMenuArea.setVisible(false) | |
WindowedS.taskbarMenuArea.redraw() | |
end | |
end | |
-- End taskbar | |
-- Window area (play pound) | |
local function drawWindowArea() | |
if taskbar.onTop then | |
WindowedS.windowArea.reposition(WindowedS.posX,taskbar.posY+1,WindowedS.width,WindowedS.height-taskbar.height) | |
else | |
WindowedS.windowArea.reposition(WindowedS.posX,(taskbar.posY+WindowedS.height)-(WindowedS.height),WindowedS.width,WindowedS.height-taskbar.height) | |
end | |
if WindowedS.useBackgroundImage then | |
local prv = term.current() | |
term.redirect(WindowedS.windowArea) | |
local ok = pcall(function() paintutils.drawImage(paintutils.loadImage(WindowedS.backgroundImage), 1, 1) end) | |
term.redirect(prv) | |
if not ok then | |
WindowedS.windowArea.setBackgroundColor(WindowedS.backgroundColor) | |
WindowedS.windowArea.clear() | |
end | |
else | |
WindowedS.windowArea.setBackgroundColor(WindowedS.backgroundColor) | |
WindowedS.windowArea.clear() | |
end | |
WindowedS.windowArea.redraw() | |
end | |
-- End window area | |
-- Window functions | |
local function windowsOpened() | |
local a=0 | |
for _ in pairs(Windows) do if Windows[_] ~= nil then a=a+1 end end | |
return a | |
end | |
local function findFreeWindowID() | |
local a=0 | |
for _ in pairs(Windows) do if _ > a then a=_ end end -- Finds the highest ID in use | |
for b=0, a do if Windows[b] == nil then return b end end -- If there's an ID not in use between the highest and 0, return it | |
return a+1 -- Return the highest+1 | |
end | |
local function getFocused() | |
local a=0 | |
for k in pairs(Windows) do if Windows[k] ~= nil then if Windows[k].priorityLevel == 0 then return k end a=k end end | |
return nil | |
end | |
local function priorityLevel(pl) for k in pairs(Windows) do if Windows[k] ~= nil then if Windows[k].priorityLevel == pl then return k end end end end | |
local function makeAdminKey(ID) | |
WindowedS.adminKey[ID] = {} | |
for k=0, WindowedS.adminKeyLength do WindowedS.adminKey[k] = math.random(0, WindowedS.radnomness) end | |
end | |
local function redrawWindow(ID) -- Redraws the border, topbar, and etc | |
if Windows[ID] == nil then return end | |
if not Windows[ID].controlWindow then return end | |
if Windows[ID].compatibilityMode then | |
Windows[ID].windowBorder.reposition(1,1,WindowedS.width,WindowedS.height-1) | |
Windows[ID].controlWindow.reposition(1,1,WindowedS.width,WindowedS.height-1) | |
Windows[ID].controlWindow.redraw() | |
elseif not Windows[ID].borderless and Windows[ID].windowBorder ~= nil then | |
if Windows[ID].fullScreen then | |
Windows[ID].windowBorder.reposition(Windows[ID].posX,Windows[ID].posY,WindowedS.width,WindowedS.height-1) | |
Windows[ID].controlWindow.reposition(1,2,WindowedS.width,WindowedS.height-2) | |
else | |
Windows[ID].windowBorder.reposition(Windows[ID].posX,Windows[ID].posY,Windows[ID].width,Windows[ID].height) | |
Windows[ID].controlWindow.reposition(2,2,Windows[ID].width-2,Windows[ID].height-2) | |
end | |
Windows[ID].windowBorder.setBackgroundColor(color.windows.borderBackgroundColor) local borderColor = color.windows.borderBackgroundColor | |
if getFocused() == ID and not taskbar.menuOpened then Windows[ID].windowBorder.setBackgroundColor(color.windows.borderBackgroundColorActive) borderColor = color.windows.borderBackgroundColorActive end | |
Windows[ID].windowBorder.clear() | |
Windows[ID].windowBorder.setBackgroundColor(color.windows.titleBarBackground) Windows[ID].windowBorder.setTextColor(color.windows.titleBarText) | |
if getFocused() == ID and not taskbar.menuOpened then Windows[ID].windowBorder.setBackgroundColor(color.windows.titleBarBackgroundActive) Windows[ID].windowBorder.setTextColor(color.windows.titleBarTextActive) end | |
Windows[ID].windowBorder.setCursorPos(1,1) | |
Windows[ID].windowBorder.clearLine() | |
local title = Windows[ID].title or "" | |
if WindowedS.showWindowID then title = title .. " {"..ID.."}" end | |
local len = string.len(title) | |
local width = Windows[ID].windowBorder.getSize() | |
if len > width-3 then | |
Windows[ID].windowBorder.write(string.sub(title,1,width-5).."..") | |
else Windows[ID].windowBorder.write(title) end | |
Windows[ID].windowBorder.setCursorPos(width,1) | |
Windows[ID].windowBorder.setBackgroundColor(color.windows.titleBarBackground) Windows[ID].windowBorder.setTextColor(color.windows.titleBarText) | |
if getFocused() == ID and not taskbar.menuOpened then Windows[ID].windowBorder.setBackgroundColor(color.windows.titleBarBackgroundActive) Windows[ID].windowBorder.setTextColor(color.windows.titleBarTextActive) end | |
Windows[ID].windowBorder.setCursorPos(width-2,1) | |
if term.isColor() then | |
Windows[ID].windowBorder.setTextColor(color.windows.minimizeText) Windows[ID].windowBorder.write("-") if Windows[ID].fullScreen then Windows[ID].windowBorder.write("v") else Windows[ID].windowBorder.write("^") end | |
Windows[ID].windowBorder.setBackgroundColor(color.windows.closeButtonBackground) Windows[ID].windowBorder.setTextColor(color.windows.closeButtonText) Windows[ID].windowBorder.write("x") | |
if Windows[ID].canResize == true then | |
Windows[ID].windowBorder.setCursorPos(width, Windows[ID].height) | |
Windows[ID].windowBorder.setBackgroundColor(color.windows.resizeTab) | |
if Windows[ID].resizing then Windows[ID].windowBorder.setBackgroundColor(color.windows.resizeTabActive) end Windows[ID].windowBorder.setTextColor(borderColor) | |
Windows[ID].windowBorder.write(" ") | |
end | |
end | |
if Windows[ID].visible then Windows[ID].windowBorder.setVisible(true) else Windows[ID].windowBorder.setVisible(false) end | |
Windows[ID].windowBorder.redraw() | |
Windows[ID].controlWindow.setVisible(true) | |
Windows[ID].controlWindow.redraw() | |
else | |
if Windows[ID].fullScreen then | |
Windows[ID].windowBorder.reposition(1,1,WindowedS.width,WindowedS.height-1) | |
Windows[ID].controlWindow.reposition(1,1,WindowedS.width,WindowedS.height-1) | |
else | |
Windows[ID].windowBorder.reposition(Windows[ID].posX,Windows[ID].posY,Windows[ID].width,Windows[ID].height) | |
Windows[ID].controlWindow.reposition(1,1,Windows[ID].width,Windows[ID].height) | |
end | |
if Windows[ID].visible then Windows[ID].windowBorder.setVisible(true) else Windows[ID].windowBorder.setVisible(false) end | |
Windows[ID].windowBorder.redraw() | |
Windows[ID].controlWindow.setVisible(true) | |
Windows[ID].controlWindow.redraw() | |
end | |
end | |
local function redrawWindows() | |
local b=0 | |
for ID in pairs(Windows) do if Windows[ID] ~= nil then if Windows[ID].priorityLevel > b then b=Windows[ID].priorityLevel end end end | |
for a=0, b do redrawWindow(priorityLevel(b-a)) end | |
end | |
local function redrawAll() | |
WindowedS.width, WindowedS.height = masterNative.getSize() | |
WindowedS.width, WindowedS.height = WindowedS.width+WindowedS.widthOffset, WindowedS.height+WindowedS.heightOffset | |
taskbar.posX, taskbar.posY = WindowedS.posX, WindowedS.posY | |
drawWindowArea() | |
redrawWindows() | |
--WindowedS.windowArea.redraw() | |
drawTaskbar() | |
drawTaskbarMenu() | |
end | |
local function drawAllWindows() | |
redrawWindows() | |
end | |
local function setFocus(ID) | |
if Windows[ID]~=nil then if Windows[ID].priorityLevel==0 then return end end | |
local oID=getFocused() | |
for k in pairs(Windows) do if Windows[k] ~= nil then if k == ID then Windows[k].priorityLevel = 0 else Windows[k].priorityLevel = Windows[k].priorityLevel+1 end end end | |
redrawWindow(oID) | |
redrawWindow(ID) | |
end | |
local function create(posX, posY, width, height, title, canResize, borderless, visibleInTaskbar, visible) | |
local ID = findFreeWindowID() | |
Windows[ID] = {} | |
WindowedS.windowKeys[ID] = {} | |
WindowedS.windowKeys[ID].key = {} | |
WindowedS.adminKeys[ID] = {} | |
WindowedS.adminKeys[ID].key = {} | |
Windows[ID].secureKey = {} | |
math.randomseed(os.clock()/2) for _=0, WindowedS.keyLength do WindowedS.windowKeys[ID].key[_] = math.random(0, WindowedS.randomness) Windows[ID].secureKey[_] = WindowedS.windowKeys[ID].key[_] end | |
math.randomseed(os.clock()*2) for _=0, WindowedS.keyLength do WindowedS.adminKeys[ID].key[_] = math.random(0, WindowedS.randomness) end | |
Windows[ID].posX = posX or WindowedS.default.posX | |
Windows[ID].posY = posY or WindowedS.default.posY | |
Windows[ID].width = width or WindowedS.default.width | |
Windows[ID].height = height or WindowedS.default.height | |
Windows[ID].title = title or "" | |
Windows[ID].canResize = canResize or true | |
Windows[ID].borderless = borderless or false | |
Windows[ID].visibleInTaskbar = visibleInTaskbar or true | |
Windows[ID].visible = visible or true | |
Windows[ID].fullScreen = false | |
Windows[ID].compatibilityMode = false | |
setFocus(ID) | |
if Windows[ID].borderless then | |
Windows[ID].windowBorder = window.create(WindowedS.windowArea, Windows[ID].posX,Windows[ID].posY,Windows[ID].width,Windows[ID].height,true) -- So if they want to disable borderless mode. | |
Windows[ID].controlWindow = window.create(Windows[ID].windowBorder, 1,1,Windows[ID].width,Windows[ID].height,true) | |
else | |
Windows[ID].windowBorder = window.create(WindowedS.windowArea, Windows[ID].posX,Windows[ID].posY,Windows[ID].width,Windows[ID].height,true) | |
Windows[ID].controlWindow = window.create(Windows[ID].windowBorder, 2,2,Windows[ID].width-2,Windows[ID].height-2,true) | |
end | |
drawTaskbar() | |
redrawWindow(ID) | |
return ID | |
end | |
local function remove(ID) | |
if Windows[ID] == nil then return end | |
for k in pairs(Windows) do | |
if Windows[k] ~= nil then | |
if k ~= ID then | |
Windows[k].priorityLevel = Windows[k].priorityLevel-1 | |
end | |
end | |
end | |
term.setCursorBlink(false) | |
Windows[ID]=nil | |
WindowedS.adminKeys[ID] = nil | |
redrawAll() | |
end | |
local function removeAll() | |
local b=0 | |
for ID in pairs(Windows) do if Windows[ID] ~= nil then if Windows[ID].priorityLevel > b then b=Windows[ID].priorityLevel end end end | |
for a=0, b do | |
ID = priorityLevel(b-a) | |
if Windows[ID] ~= nil then | |
term.setCursorBlink(false) | |
Windows[ID]=nil | |
WindowedS.adminKeys[ID] = nil | |
sleep(0.1) | |
end | |
end | |
redrawAll() | |
end | |
-- End window functions | |
redrawAll() | |
-- Window management | |
local function pushEvent(ID, Event, ...) | |
if Windows[ID] == nil then return end -- Nil protection | |
if Windows[ID].event == nil or Windows[ID].event == Event or Windows[ID].event == "terminate" then | |
term.redirect(Windows[ID].controlWindow) | |
local ok, result = coroutine.resume(Windows[ID].coroutine, Event, ...) | |
if ok then if Windows[ID] == nil then return end Windows[ID].event = result else printError(result) end | |
if Windows[ID].coroutine == "dead" then remove(ID) end | |
end | |
end | |
local function runNew(env, program, ...) | |
local args = { ... } | |
local ID=create() | |
Windows[ID].title=fs.getName(program) | |
local WindowEnvSetup={} | |
WindowEnvSetup.Windowed=Windowed -- Inject our API | |
WindowEnvSetup.Windowed.ID=ID | |
WindowEnvSetup.Windowed.version=WindowedS.version | |
WindowEnvSetup.Windowed.properties=Windows[ID] | |
WindowEnvSetup.Windowed.redrawAll=redrawAll | |
WindowEnvSetup.term=term | |
WindowEnvSetup.term.native=function() return Windows[ID].controlWindow end | |
WindowEnvSetup.os=os | |
WindowEnvSetup.os.shutdown=function() remove(ID) redrawAll() end | |
WindowEnvSetup.os.reboot=function() remove(ID) redrawAll() end | |
--setmetatable(WindowEnvSetup, {__index=_ENV}) -- This will inject everything | |
Windows[ID].coroutine=coroutine.create(function() os.run(WindowEnvSetup, program, table.unpack(args)) Windows[ID].title=Windows[ID].title.." [closed]" redrawAll() sleep(1) remove(ID) redrawAll() end) | |
Windows[ID].event = nil | |
redrawAll() | |
pushEvent(ID) | |
return ID | |
end | |
function Windowed.getFocused() | |
return getFocused() | |
end | |
function Windowed.title(ID) | |
return Windows[ID].title | |
end | |
function Windowed.getWindowProperties(ID, key) | |
if Windows[ID] == nil then return false, "Invalid window ID" end | |
if not WindowedS.bypassKeyCheck then if key ~= nil and type(key) == "table" then for k,v in pairs(key) do if WindowedS.adminKey[ID].key[k] ~= key[k] then return false, "Invalid key" end end else return false, "No key" end end | |
return Windows[ID] | |
end | |
function Windowed.setWindowProperties(ID, key, properties) | |
if Windows[ID] == nil then return false, "Invalid window ID" end | |
if not WindowedS.bypassKeyCheck then if key ~= nil and type(key) == "table" then for k,v in pairs(key) do if WindowedS.adminKey[ID].key[k] ~= key[k] then return false, "Invalid key" end end else return false, "No key" end end | |
if type(properties) ~= "table" then return false, "Properties need to be in a table." end | |
Windows[ID] = properties | |
end | |
function Windowed.requestAdmin(ID, windowKey) | |
if Windows[ID] == nil then return false, "Invalid window ID" end | |
if Windows[ID].adminKey ~= nil then return false, "You already have the key" end | |
if not WindowedS.bypassKeyCheck then if windowKey ~= nil and type(windowKey) == "table" then for k,v in pairs(windowKey) do if WindowedS.windowKeys[ID].key[k] ~= key[k] then return false, "Invalid key" end end else return false, "No key table" end end | |
if drawAlertBox("Administrator privilege",Windows[ID].title.." is requesting", "administrator privilege. Allow?","(They can modify windows with this)","Allow","Deny",true,false) then | |
Windows[ID].adminKey = {} | |
for k in pairs(WindowedS.adminKeys) do Windows[ID].adminKey[k] = WindowedS.adminKeys[ID].key[k] end | |
return true | |
else | |
return false, "User denied." | |
end | |
end | |
function Windowed.new(posX, posY, width, height, title, resizable, borderless, visible, visibleInTaskbar, env, path, ...) | |
local prv = term.current() | |
local ID = runNew(env, path, ...) | |
Windows[ID].posX = posX or Windows[ID].posX | |
Windows[ID].posY = posY or Windows[ID].posY | |
Windows[ID].width = width or Windows[ID].width | |
Windows[ID].height = height or Windows[ID].height | |
Windows[ID].title = title or Windows[ID].title | |
Windows[ID].borderless = borderless or Windows[ID].borderless | |
Windows[ID].visible, Windows[ID].visibleInTaskbar = visible, visibleInTaskbar or Windows[ID].visible, Windows[ID].visibleInTaskbar | |
term.redirect(prv) | |
redrawAll() | |
return ID | |
end | |
function Windowed.getCount() | |
return windowsOpened() | |
end | |
runNew({}, "/rom/programs/shell") | |
--create() | |
-- Run processes | |
local cor = coroutine.running() | |
local exitLoop = true | |
local superKey = false | |
while exitLoop do -- I'm not going to indent this | |
-- Get the event | |
local tEventData = { os.pullEventRaw() } | |
local sEvent = tEventData[1] | |
if sEvent == "term_resize" then | |
redrawAll() | |
for ID in pairs(Windows) do | |
if Windows[ID] ~= nil then | |
pushEvent(ID, "term_resize" ) | |
end | |
end | |
elseif sEvent == "key" or sEvent == "char" or sEvent == "key_up" then | |
local key, held = tEventData[2], tEventData[3] | |
if sEvent == "key" and key == WindowedS.keys.super and held and not WindowedS.drawingBox then | |
local a=0 | |
local oldTitle = "" | |
local ID = getFocused() | |
if Windows[getFocused()] ~= nil then oldTitle = Windows[ID].title Windows[ID].title = "{K} " .. oldTitle redrawWindow(ID) drawTaskbar() end | |
local taskbarFix = taskbar.height | |
if not taskbar.onTop then taskbarFix = 0 end | |
while true do | |
local event, key, held = os.pullEventRaw() | |
superKey = true | |
key = key or "0" | |
if event ~= "key" and event ~= "key_up" and event ~= "char" then break | |
elseif event == "key" and key == WindowedS.keys.super then | |
elseif event == "key_up" and key == WindowedS.keys.super then break | |
elseif Windows[ID] ~= nil and event == "key" and key == WindowedS.keys.fullScreen then | |
if not Windows[ID].fullScreen then Windows[ID].oWidth = Windows[ID].width Windows[ID].oHeight = Windows[ID].height Windows[ID].oPosX = Windows[ID].posX Windows[ID].oPosY = Windows[ID].posY | |
Windows[ID].width = WindowedS.width Windows[ID].height = WindowedS.height-1 Windows[ID].posX = 1 Windows[ID].posY = 1+taskbarFix Windows[ID].fullScreen = true redrawWindow(ID) end pushEvent(ID, "term_resize") | |
elseif Windows[ID] ~= nil and event == "key" and key == WindowedS.keys.normalScreen then | |
if Windows[ID].fullScreen then Windows[ID].width = Windows[ID].oWidth Windows[ID].height = Windows[ID].oHeight Windows[ID].posX = Windows[ID].oPosX Windows[ID].posY = Windows[ID].oPosY | |
Windows[ID].fullScreen = false redrawAll() end pushEvent(ID, "term_resize") | |
elseif Windows[ID] ~= nil and event == "key" and key == WindowedS.keys.close then | |
remove(ID) | |
redrawAll() | |
elseif Windows[ID] ~= nil and event == "key" and key == WindowedS.keys.closeAll then | |
removeAll() | |
elseif event == "key" and key == WindowedS.keys.menu then | |
-- Open the menu | |
if taskbar.menuOpened then taskbar.menuOpened = false else taskbar.menuOpened = true end drawTaskbarMenu() | |
redrawAll() | |
elseif Windows[ID] ~= nil and event == "key" and key == WindowedS.keys.switchWindow then | |
local a=0 | |
for k in pairs(Windows) do if Windows[k] ~= nil then if Windows[k].priorityLevel > a then a=Windows[k].priorityLevel end end end | |
setFocus(priorityLevel(a)) | |
Windows[ID].title = oldTitle | |
redrawWindow(ID) | |
ID = getFocused() | |
if Windows[ID] ~= nil then oldTitle = Windows[ID].title Windows[ID].title = "{K} " .. oldTitle redrawWindow(ID) drawTaskbar() end | |
drawTaskbar() | |
redrawWindow(ID) | |
elseif event == "key" and key == WindowedS.keys.runShell then | |
if Windows[ID] ~= nil then Windows[ID].title = oldTitle end | |
runNew({},WindowedS.shellLocation) | |
setFocus(ID) | |
elseif Windows[ID] ~= nil and event == "key" and key == WindowedS.keys.compatibilityMode and WindowedS.allowCompatibilityMode then | |
if Windows[ID] ~= nil then Windows[ID].title = oldTitle end | |
if Windows[ID].compatibilityMode then Windows[ID].compatibilityMode = false | |
else Windows[ID].compatibilityMode = true end | |
redrawAll() | |
pushEvent(ID, "term_resize") | |
elseif event == "key" and key == WindowedS.keys.moveWindow and Windows[ID] ~= nil then | |
local oTitle = Windows[ID].title | |
Windows[ID].title = "{M} "..oldTitle | |
redrawAll() | |
local breakThis = false | |
while true do | |
local event, key, held = os.pullEventRaw() | |
if event == "key_up" and key == WindowedS.keys.moveWindow then break | |
elseif event == "key_up" and key == WindowedS.super then breakThis = true break | |
elseif event == "key" and key == 205 then -- right | |
if Windows[ID].posX+Windows[ID].width+1 < WindowedS.width+2 then Windows[ID].posX = Windows[ID].posX+1 end | |
elseif event == "key" and key == 203 then -- Left | |
if Windows[ID].posX-1 > WindowedS.posX-1 then Windows[ID].posX = Windows[ID].posX-1 end | |
elseif event == "key" and key == 200 then -- Up | |
if Windows[ID].posY-1 > WindowedS.posY-1 then Windows[ID].posY = Windows[ID].posY-1 end | |
elseif event == "key" and key == 208 then -- Down | |
if Windows[ID].posY+Windows[ID].height+1 < WindowedS.height+1 then Windows[ID].posY = Windows[ID].posY+1 end | |
end | |
drawWindowArea() | |
drawAllWindows() | |
end | |
if breakThis then os.queueEvent("key_up", WindoedS.keys.super) end | |
Windows[ID].title = oTitle | |
redrawAll() | |
elseif event == "key" and held and key == WindowedS.keys.exitLoop then exitLoop = false break end | |
redrawWindow(ID) | |
end | |
superKey = false | |
if Windows[ID] ~= nil then Windows[ID].title = oldTitle redrawAll() end | |
elseif Windows[getFocused()] ~= nil then | |
pushEvent(getFocused(), table.unpack(tEventData)) | |
end | |
elseif sEvent == "paste" or sEvent == "terminate" then | |
if Windows[getFocused()] ~= nil then pushEvent( getFocused(), table.unpack( tEventData ) ) end | |
elseif Windows[getFocused()] ~= nil and sEvent == "mouse_click" or sEvent == "mouse_up" or sEvent == "mouse_scroll" or sEvent == "mouse_drag" then | |
local button, x, y = tEventData[2], tEventData[3], tEventData[4] | |
local a=0 | |
for k in pairs(Windows) do if Windows[k] ~= nil then if Windows[k].priorityLevel > a then a=Windows[k].priorityLevel end end end | |
local taskbarFix = taskbar.height if not taskbar.onTop then taskbarFix = 0 end | |
local taskbarY = taskbar.posY if not taskbar.onTop then taskbarY = taskbar.posY+WindowedS.height-1 end | |
-- Get which one was clicked | |
if sEvent == "mouse_click" then | |
local b=0 while b<a+1 do | |
local ID = priorityLevel(b) | |
if Windows[ID] ~= nil then | |
if taskbar.menuOpened and x >= taskbar.menu.posX and x < taskbar.menu.posX+taskbar.menu.width and y >= taskbar.menu.posY and y < taskbar.menu.posY+taskbar.menu.height then | |
break -- Clicked the menu | |
elseif Windows[ID].compatibilityMode or Windows[ID].fullScreen and y ~= taskbarY then | |
taskbar.menuOpened = false setFocus(ID) break | |
elseif Windows[ID].visible and x >= Windows[ID].posX and x < Windows[ID].posX+Windows[ID].width and y >= Windows[ID].posY+taskbarFix and y < Windows[ID].posY+Windows[ID].height+taskbarFix then | |
taskbar.menuOpened = false setFocus(ID) break | |
else taskbar.menuOpened = false end | |
end | |
b=b+1 | |
end end | |
local ID = getFocused() | |
local border = true | |
if Windows[ID] ~= nil and not taskbar.menuOpened then | |
if Windows[ID].compatibilityMode or Windows[ID].borderless then border = false end | |
local farRight = Windows[ID].posX+Windows[ID].width-3 | |
if not Windows[ID].visibleInTaskbar then farRight = Windows[ID].posX+Windows[ID].width-2 end | |
if not Windows[ID].borderless and sEvent == "mouse_up" and button == 1 and dragging then | |
dragging = false | |
draggingResize = false | |
Windows[ID].resizing = false | |
redrawWindow(ID) | |
elseif sEvent == "mouse_drag" and not Windows[ID].compatibilityMode and not Windows[ID].borderless and dragging and not draggingResize then | |
pcall(function() local moveX, moveY = x-Windows[ID].xCorrect, y-taskbarFix | |
maxX, maxY = WindowedS.windowArea.getSize() | |
if moveX+Windows[ID].width >= maxX+2 or moveX <= 0 then moveX = Windows[ID].posX end | |
if moveY == taskbar.posY and taskbar.onTop then moveY = Windows[ID].posY elseif moveY >= WindowedS.height and not taskbar.onTop then moveY = Windows[ID].posY end | |
if moveX ~= oMoveX or moveY ~= oMoveY then -- Something moved | |
Windows[ID].posX = moveX | |
Windows[ID].posY = moveY | |
if Windows[ID].fullScreen then Windows[ID].xCorrect = 0 Windows[ID].posX = x Windows[ID].width = Windows[ID].oWidth Windows[ID].height = Windows[ID].oHeight end | |
drawWindowArea() | |
drawAllWindows() | |
if Windows[ID].fullScreen then pushEvent(ID, "term_resize") Windows[ID].fullScreen = false end | |
end | |
local oMoveX, oMoveY = moveX, moveY end) | |
elseif sEvent == "mouse_drag" and not Windows[ID].fullScreen and border and draggingResize then | |
pcall(function() local resizeX, resizeY = x-Windows[ID].posX, y-Windows[ID].posY-taskbarFix | |
maxX, maxY = WindowedS.windowArea.getSize() | |
if resizeX >= maxX+2 or resizeX <= 4 then resizeX = Windows[ID].width-1 end if resizeY >= maxY+2-taskbarFix or resizeY <=2 then resizeY = Windows[ID].height-1 end | |
if resizeY <= 2 and taskbar.onTop then resizeY = Windows[ID].height-1 -- I have no idea how this will ever be called... | |
elseif resizeY >= WindowedS.height-1 and not taskbar.onTop then resizeY = Windows[ID].height-1 end | |
if resizeX ~= oResizeX or resizeY ~= oResizeY then -- Something resized | |
Windows[ID].fullScreen = false | |
Windows[ID].width = resizeX+1 | |
Windows[ID].height = resizeY+1 | |
drawWindowArea() | |
drawAllWindows() | |
pushEvent(ID, "term_resize") | |
end | |
local oResizeX, oResizeY = resizeX, resizeY end) | |
elseif border and not dragging and Windows[ID].visible and sEvent == "mouse_click" and button == 1 and x >= Windows[ID].posX and x < farRight and y == Windows[ID].posY+taskbarFix then | |
-- Clicked the title bar, probably going to drag it around | |
Windows[ID].xCorrect = x-Windows[ID].posX -- How far the mouse click was from the far left of the title bar | |
dragging=true | |
elseif border and not Windows[ID].fullScreen and not dragging and Windows[ID].canResize and Windows[ID].visible and sEvent == "mouse_click" and button == 1 and x == Windows[ID].posX+Windows[ID].width-1 and y == Windows[ID].posY+Windows[ID].height+taskbarFix-1 then | |
-- Resizing | |
dragging = true -- So I don't have to add "and not draggingResize" to every if line | |
draggingResize = true | |
Windows[ID].resizing = true | |
redrawWindow(ID) | |
elseif border and not dragging and Windows[ID].visible and sEvent == "mouse_up" and button == 1 and Windows[ID].visibleInTaskbar and x == Windows[ID].width+Windows[ID].posX-3 and y == Windows[ID].posY+taskbarFix then | |
-- Minimize | |
Windows[ID].visible = false | |
redrawWindow(ID) | |
redrawAll() | |
redrawWindows() | |
elseif border and not dragging and Windows[ID].visible and sEvent == "mouse_up" and button == 1 and x == Windows[ID].width+Windows[ID].posX-2 and y == Windows[ID].posY+taskbarFix then | |
-- Fullscreen | |
if not Windows[ID].fullScreen then | |
Windows[ID].oWidth = Windows[ID].width | |
Windows[ID].oHeight = Windows[ID].height | |
Windows[ID].oPosX = Windows[ID].posX | |
Windows[ID].oPosY = Windows[ID].posY | |
Windows[ID].width = WindowedS.width | |
Windows[ID].height = WindowedS.height-1 | |
Windows[ID].posX = 1 | |
Windows[ID].posY = 1+taskbarFix | |
Windows[ID].fullScreen = true | |
redrawWindow(ID) | |
pushEvent(ID, "term_resize") | |
elseif Windows[ID].fullScreen then | |
Windows[ID].width = Windows[ID].oWidth | |
Windows[ID].height = Windows[ID].oHeight | |
Windows[ID].posX = Windows[ID].oPosX | |
Windows[ID].posY = Windows[ID].oPosY | |
Windows[ID].fullScreen = false | |
redrawAll() | |
pushEvent(ID, "term_resize") | |
end | |
elseif border and not dragging and Windows[ID].visible and sEvent == "mouse_up" and button == 1 and x == Windows[ID].posX+Windows[ID].width-1 and y == Windows[ID].posY+taskbarFix then | |
-- Close | |
remove(ID) | |
redrawAll() | |
elseif border and not Windows[ID].fullScreen and not dragging and Windows[ID].visible and x >= Windows[ID].posX+1 and x < Windows[ID].width+Windows[ID].posX-1 and y > Windows[ID].posY+taskbarFix and y < Windows[ID].posY+Windows[ID].height-1+taskbarFix then | |
-- Clicked the control area | |
pushEvent(ID, sEvent, button, x-(Windows[ID].posX), (y)-(Windows[ID].posY+taskbarFix)) | |
elseif not border and not Windows[ID].compatibilityMode and x >= Windows[ID].posX and x < Windows[ID].width+Windows[ID].posX and y >= Windows[ID].posY+taskbarFix and y < Windows[ID].height+Windows[ID].posY+taskbarFix then | |
-- Clicked inside the borderless control area | |
pushEvent(ID, sEvent, button, x-Windows[ID].posX, (y)-Windows[ID].posY-taskbarFix) | |
elseif Windows[ID].fullScreen and not dragging and Windows[ID].visible and x >= Windows[ID].posX and x < Windows[ID].width+Windows[ID].posX and y > Windows[ID].posY+taskbarFix and y < Windows[ID].posY+Windows[ID].height-1+taskbarFix then | |
-- Clicked a control area in full screen mode | |
pushEvent(ID, sEvent, button, x-Windows[ID].posX+1, (y)-Windows[ID].posY-taskbarFix) | |
elseif Windows[ID].compatibilityMode and not dragging and Windows[ID].visible and y ~= taskbarY then | |
-- Clicked a window in compatibility mode | |
pushEvent(ID, sEvent, button, x, y-taskbarFix) | |
elseif x >= taskbar.posX and x < taskbar.posX+taskbar.width and y == taskbarY then | |
-- Somewhere on the taskbar was clicked. | |
if x >= taskbar.posX and x < taskbar.posX+taskbar.buttons.menuWidth and sEvent == "mouse_up" then | |
-- Menu button clicked | |
if taskbar.menuOpened then taskbar.menuOpened = false else taskbar.menuOpened = true end redrawAll() | |
elseif x > taskbar.buttons.menuWidth and x < taskbar.posX+(taskbar.width-10) then | |
-- Clicked a window | |
for kID in pairs(Windows) do if Windows[kID] ~= nil then if x > taskbar.posX+Windows[kID].taskbarStartX-1 and x < taskbar.posX+Windows[kID].taskbarEndX then -- Clicked this window. | |
Windows[kID].visible = true setFocus(kID) redrawAll() | |
end end end | |
else menuOpened = false end | |
elseif sEvent == "mouse_up" and taskbar.menuOpened and x >= taskbar.menu.posX and x < taskbar.menu.posX+taskbar.menu.width-1 and y >= taskbar.menu.posY and y < taskbar.menu.posY+taskbar.menu.height then | |
-- Menu clicked | |
local taskbarFixer = 0 | |
if not taskbar.onTop then taskbarFixer = -1 end | |
if y == taskbar.menu.shutdownY+taskbar.menu.posY+taskbarFixer then | |
taskbar.menu.shutdown() | |
taskbar.menuOpened = false | |
elseif y == taskbar.menu.restartY+taskbar.menu.posY+taskbarFixer then | |
taskbar.menu.restart() | |
taskbar.menuOpened = false | |
elseif y == taskbar.menu.shellY+taskbar.menu.posY+taskbarFixer then | |
runNew({},WindowedS.shellLocation) | |
taskbar.menuOpened = false | |
redrawAll() | |
elseif y == taskbar.menu.exitY+taskbar.menu.posY+taskbarFixer then | |
exitLoop = false | |
redrawAll() | |
end | |
end | |
elseif x >= taskbar.posX and x < taskbar.posX+taskbar.width and y == taskbarY then | |
-- Somewhere on the taskbar was clicked. | |
if x >= taskbar.posX and x < taskbar.posX+taskbar.buttons.menuWidth and sEvent == "mouse_up" then | |
-- Menu button clicked | |
if taskbar.menuOpened then taskbar.menuOpened = false else taskbar.menuOpened = true end redrawAll() | |
elseif x > taskbar.buttons.menuWidth and x < taskbar.posX+(taskbar.width-10) then | |
taskbar.menuOpened = false | |
-- Clicked a window | |
for kID in pairs(Windows) do if Windows[kID] ~= nil then if x > taskbar.posX+Windows[kID].taskbarStartX-1 and x < taskbar.posX+Windows[kID].taskbarEndX then -- Clicked this window. | |
Windows[kID].visible = true setFocus(kID) redrawAll() | |
end end end | |
else taskbar.menuOpened = false end | |
elseif sEvent == "mouse_up" and taskbar.menuOpened and x >= taskbar.menu.posX and x < taskbar.menu.posX+taskbar.menu.width-1 and y >= taskbar.menu.posY and y < taskbar.menu.posY+taskbar.menu.height then | |
-- Menu clicked | |
local taskbarFixer = 0 | |
if not taskbar.onTop then taskbarFixer = -1 end | |
if y == taskbar.menu.shutdownY+taskbar.menu.posY+taskbarFixer then | |
taskbar.menu.shutdown() | |
taskbar.menuOpened = false | |
elseif y == taskbar.menu.restartY+taskbar.menu.posY+taskbarFixer then | |
taskbar.menu.restart() | |
taskbar.menuOpened = false | |
elseif y == taskbar.menu.shellY+taskbar.menu.posY+taskbarFixer then | |
runNew({},WindowedS.shellLocation) | |
taskbar.menuOpened = false | |
redrawAll() | |
elseif y == taskbar.menu.exitY+taskbar.menu.posY+taskbarFixer then | |
exitLoop = false | |
redrawAll() | |
end | |
end | |
elseif Windows[getFocused()] ~= nil then | |
-- Other event (go to all programs) | |
pcall(function() for ID in pairs(Windows) do | |
if Windows[ID] ~= nil then | |
pushEvent(ID, table.unpack( tEventData ) ) | |
end | |
end end) | |
--redrawAll() | |
end | |
if WindowedS.eventUpdates == 1 then redrawWindow(getFocused()) elseif WindowedS.eventUpdates == 2 then redrawAll() end | |
end | |
term.native = function() | |
return masterNative | |
end | |
term.current = oTermCurrent | |
os.reboot = nativeReboot | |
os.shutdown = nativeShutdown | |
term.redirect(masterCurrent) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment