Advertisement
Piorjade

CC miniOS

Oct 23rd, 2016
1,662
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.19 KB | None | 0 0
  1. --[[
  2.  
  3.                 miniOS
  4.  
  5.     As the name already says, this OS is not
  6.     a real "OS", like you'd expect it to be.
  7.  
  8.     I think you can call it a window manager
  9.  
  10.     ~Piorjade
  11. ]]--
  12.  
  13. --[[
  14.             Variables
  15.         (and minimal thread API)           
  16. ]]
  17. tasks = {}
  18. windows = {}
  19. selected = ""
  20.  
  21. --define the thread api
  22. local thread = {}
  23.  
  24. function thread.new(path)
  25.     if not fs.exists(path) or fs.isDir(path) then
  26.         return nil
  27.     end
  28.     local self = {}
  29.     --load the file as function
  30.     self.func, err = loadfile(path)
  31.     if not self.func then
  32.         return false, err
  33.     end
  34.     --create a new enviroment for the file and put it in there
  35.     self.env = {}
  36.     setmetatable(self.env, {})
  37.     local function _copy(a, b)
  38.         for k, v in pairs(a) do
  39.             b[k] = v
  40.         end
  41.     end
  42.     _copy(_G, self.env)
  43.     setfenv(self.func, self.env)
  44.     --defines variables
  45.     if not tasks[path] then
  46.         self.path = path
  47.     else
  48.         local kek = path
  49.         local nkek = kek
  50.         local counter = 1
  51.         repeat
  52.             nkek = kek..tostring(counter)
  53.             counter = counter+1
  54.         until not tasks[nkek]
  55.         self.path = nkek
  56.     end
  57.     self.task = coroutine.create(self.func)
  58.     self.dead = false
  59.     self.paused = false
  60.     self.filter = nil
  61.     self.invisible = false
  62.     --define resume function (--> runs the file)
  63.     function self.resume(...)
  64.         local fst = {...}
  65.         if self.filter == nil and not self.paused or fst[1] == self.filter and not self.paused then
  66.             local ok, err = coroutine.resume(self.task, unpack(fst))
  67.             if ok then
  68.                 local stat = coroutine.status(self.task)
  69.                 if stat == "dead" then
  70.                     self.dead = true
  71.                 else
  72.                     self.filter = err
  73.                 end
  74.             else
  75.                 self.dead = true
  76.                 printError(err)
  77.             end
  78.         end
  79.     end
  80.     tasks[self.path] = self
  81.     --create a new window for the file
  82.     --xA/yA = top left corner, xO/yO = bottom right corner
  83.     local maxX, maxY = term.getSize()
  84.     windows[self.path] = {}
  85.     windows[self.path]['xA'] = 1
  86.     windows[self.path]['yA'] = 1
  87.     windows[self.path]['xO'] = maxX
  88.     windows[self.path]['yO'] = maxY
  89.     windows[self.path]['w'] = window.create(oldTerm, 1, 1, maxX, maxY)
  90.     windows[self.path]['w'].setBackgroundColor(colors.gray)
  91.     windows[self.path]['w'].setTextColor(colors.black)
  92.     windows[self.path]['w'].clear()
  93.     windows[self.path]['w'].setTextColor(colors.red)
  94.     windows[self.path]['w'].setCursorPos(maxX, 1)
  95.     windows[self.path]['w'].write("O")
  96.     windows[self.path]['w'].setTextColor(colors.yellow)
  97.     windows[self.path]['w'].setCursorPos(maxX-1, 1)
  98.     windows[self.path]['w'].write("O")
  99.     windows[self.path]['w'].setTextColor(colors.green)
  100.     windows[self.path]['w'].setCursorPos(maxX-2, 1)
  101.     windows[self.path]['w'].write("O")
  102.     windows[self.path]['uw'] = window.create(windows[self.path]['w'], 2, 2, maxX-2, maxY-2)
  103.     if #selected > 0 then
  104.         --windows[selected]['w'].setVisible(false)
  105.     end
  106.     selected = self.path
  107.     return true
  108. end
  109.  
  110. --[[
  111.         functions
  112. ]]
  113. local function clear(bg, fg)
  114.     term.setCursorPos(1,1)
  115.     term.setBackgroundColor(bg)
  116.     term.setTextColor(fg)
  117.     term.clear()
  118. end
  119.  
  120. local function redrawWindows()
  121.    
  122.     for each, task in pairs(tasks) do
  123.         if not task.dead and not task.invisible then
  124.             windows[task.path]['w'].redraw()
  125.             windows[task.path]['uw'].redraw()
  126.         end
  127.     end
  128.     if #selected > 0 and not tasks[selected].invisible then
  129.         windows[selected]['w'].redraw()
  130.         windows[selected]['uw'].redraw()
  131.     end
  132. end
  133.  
  134. local function drawSys()
  135.     clear(colors.lightBlue, colors.black)
  136.     local textBox = window.create(oldTerm, 1, 1, 20, 1, false)
  137.     textBox.setBackgroundColor(colors.gray)
  138.     textBox.setTextColor(colors.lime)
  139.     textBox.clear()
  140.     local evt = {}
  141.    
  142.     --start loop
  143.     while true do
  144.        
  145.         evt = {os.pullEventRaw()}
  146.         local event, button, x, y = unpack(evt)
  147.  
  148.         if event == "key" and button == keys.f1 then
  149.             textBox.setVisible(true)
  150.             term.redirect(textBox)
  151.             clear(colors.gray, colors.lime)
  152.             term.write("Path: ")
  153.             local oprint = _G.print
  154.             _G.print = function(t)
  155.                 return term.write(t)
  156.             end
  157.             local e = read()
  158.             _G.print = oprint
  159.             term.redirect(oldTerm)
  160.             textBox.setVisible(false)
  161.             clear(colors.lightBlue, colors.black)
  162.             thread.new(e)
  163.         elseif event == "mouse_click" then
  164.             if button == 1 then
  165.                 if #selected > 0 and x == windows[selected]['xO'] and y == windows[selected]['yA'] then
  166.                     --close a window
  167.                     tasks[selected].dead = true
  168.                     --table.insert(queueRemove, selected)
  169.                     tasks[selected] = nil
  170.                     windows[selected] = nil
  171.                     selected = ""
  172.                     clear(colors.lightBlue, colors.black)
  173.                     redrawWindows()
  174.                 elseif #selected > 0 and x == windows[selected]['xO']-1 and y == windows[selected]['yA'] then
  175.                     --maximize a window
  176.                     local maxX, maxY = term.getSize()
  177.                     windows[selected]['w'].reposition(1, 1, maxX, maxY)
  178.                     windows[selected]['uw'].reposition(2, 2, maxX-2, maxY-2)
  179.                     windows[selected]['xA'] = 1
  180.                     windows[selected]['yA'] = 1
  181.                     windows[selected]['xO'] = maxX
  182.                     windows[selected]['yO'] = maxY
  183.                     windows[selected]['w'].setBackgroundColor(colors.gray)
  184.                     windows[selected]['w'].setTextColor(colors.black)
  185.                     windows[selected]['w'].clear()
  186.                     windows[selected]['w'].setTextColor(colors.red)
  187.                     windows[selected]['w'].setCursorPos(maxX, 1)
  188.                     windows[selected]['w'].write("O")
  189.                     windows[selected]['w'].setTextColor(colors.yellow)
  190.                     windows[selected]['w'].setCursorPos(maxX-1, 1)
  191.                     windows[selected]['w'].write("O")
  192.                     windows[selected]['w'].setTextColor(colors.green)
  193.                     windows[selected]['w'].setCursorPos(maxX-2, 1)
  194.                     windows[selected]['w'].write("O")
  195.                     clear(colors.lightBlue, colors.black)
  196.                     redrawWindows()
  197.                 elseif #selected > 0 and x == windows[selected]['xO']-2 and y == windows[selected]['yA'] then
  198.                     --minimize a window
  199.                     tasks[selected].invisible = true
  200.                     windows[selected]['w'].setVisible(false)
  201.                     selected = ""
  202.                     clear(colors.lightBlue, colors.black)
  203.                     redrawWindows()
  204.                 elseif #selected > 0 and x == windows[selected]['xO'] and y == windows[selected]['yO'] then
  205.                     --resize the window
  206.                     local nevt = {}
  207.                     local cx = x
  208.                     local cy = y
  209.                     local width, height = 1,1
  210.                     repeat
  211.                         nevt = {os.pullEvent()}
  212.                         if nevt[1] == "mouse_drag" and nevt[3] >= windows[selected]['xA']+2 and nevt[4] >= windows[selected]['yA']+2 then
  213.                             width = windows[selected]['xO']-windows[selected]['xA']+1
  214.                             height = windows[selected]['yO']-windows[selected]['yA']+1
  215.  
  216.                             if width >= 3 and height >= 3 then
  217.                                 windows[selected]['xO'] = nevt[3]
  218.                                 windows[selected]['yO'] = nevt[4]
  219.                                 local maxX = windows[selected]['xO']
  220.                                 local maxY = windows[selected]['yO']
  221.                                 width = windows[selected]['xO']-windows[selected]['xA']+1
  222.                                 height = windows[selected]['yO']-windows[selected]['yA']+1
  223.                                 windows[selected]['w'].reposition(windows[selected]['xA'], windows[selected]['yA'], width, height)
  224.                                 windows[selected]['uw'].reposition(2, 2, width-2, height-2)
  225.                                 windows[selected]['w'].setBackgroundColor(colors.gray)
  226.                                 windows[selected]['w'].setTextColor(colors.black)
  227.                                 windows[selected]['w'].clear()
  228.                                 windows[selected]['w'].setTextColor(colors.red)
  229.                                 windows[selected]['w'].setCursorPos(width, 1)
  230.                                 windows[selected]['w'].write("O")
  231.                                 windows[selected]['w'].setTextColor(colors.yellow)
  232.                                 windows[selected]['w'].setCursorPos(width-1, 1)
  233.                                 windows[selected]['w'].write("O")
  234.                                 windows[selected]['w'].setTextColor(colors.green)
  235.                                 windows[selected]['w'].setCursorPos(width-2, 1)
  236.                                 windows[selected]['w'].write("O")
  237.                                 clear(colors.lightBlue, colors.black)
  238.                                 redrawWindows()
  239.                             end
  240.                         end
  241.                     until nevt[1] == "mouse_up"
  242.                     clear(colors.lightBlue, colors.black)
  243.                     redrawWindows()
  244.                 elseif #selected > 0 and x >= windows[selected]['xA'] and x <= windows[selected]['xO']-2 and y == windows[selected]['yA'] then
  245.                     --move the window
  246.                     local nevt = {}
  247.                     local abstand = x-windows[selected]['xA']
  248.                     local width, height = windows[selected]['w'].getSize()
  249.                     local cx = x
  250.                     local cy = y
  251.                     repeat
  252.                         nevt = {os.pullEvent()}
  253.                        
  254.                         if nevt[1] == "mouse_drag" then
  255.                             windows[selected]['xA'] = nevt[3]-abstand
  256.                             windows[selected]['yA'] = nevt[4]
  257.                             windows[selected]['xO'] = windows[selected]['xA']+width-1
  258.                             windows[selected]['yO'] = windows[selected]['yA']+height-1
  259.                             windows[selected]['w'].reposition(windows[selected]['xA'], windows[selected]['yA'], width, height)
  260.                             clear(colors.lightBlue, colors.black)
  261.                             redrawWindows()
  262.                         end
  263.                     until nevt[1] == "mouse_up"
  264.                     clear(colors.lightBlue, colors.black)
  265.                     redrawWindows()
  266.                 else
  267.                     if #selected > 0 then
  268.                         for each, window in pairs(windows) do
  269.                             if x < windows[selected]['xA'] or y > windows[selected]['yO'] or x > windows[selected]['xO'] or y < windows[selected]['yA'] then
  270.                                 if x >= window.xA and x <= window.xO and y >= window.yA and y <= window.yO then
  271.                                     --windows[selected]['w'].setVisible(false)
  272.                                     selected = each
  273.                                     --windows[selected]['w'].setVisible(true)
  274.                                     break
  275.                                 end
  276.                             end
  277.                         end
  278.                     else
  279.                         for each, window in pairs(windows) do
  280.                             if x >= window.xA and x <= window.xO and y >= window.yA and y <= window.yO then
  281.                                 selected = each
  282.                                 --windows[selected]['w'].setVisible(true)
  283.                                 break
  284.                             end
  285.                         end
  286.                     end
  287.                     clear(colors.lightBlue, colors.black)
  288.                     redrawWindows()
  289.                 end
  290.             end
  291.         end
  292.     end
  293. end
  294. --[[
  295.         code
  296. ]]
  297. --catch the original terminal (for orientation)
  298. oldTerm = term.current()
  299. queueRemove = {}
  300. --list every event that should only be passed to the selected window
  301. ll = {
  302.     "key",
  303.     "char",
  304.     "mouse_click",
  305.     "mouse_down",
  306.     "mouse_drag"
  307. }
  308. parallel.waitForAll(
  309.     function()
  310.         drawSys()
  311.     end,
  312.     function()
  313.         local evt = {}
  314.         while true do
  315.             for task, a in pairs(tasks) do
  316.                 --resume all non-selected windows
  317.                 if not a.dead and not a.path == selected then
  318.                     local found = false
  319.                     --check if the current event is one of the listed. if yes, don't resume
  320.                     for _, a in ipairs(ll) do
  321.                         if evt[1] == a then
  322.                             found = true
  323.                             break
  324.                         else
  325.                             found = false
  326.                         end
  327.                     end
  328.                     if not found then
  329.                         term.redirect(windows[a.path]['uw'])
  330.                         a.resume(unpack(evt))
  331.                         term.redirect(oldTerm)
  332.                     end
  333.                 end
  334.             end
  335.             if tasks[selected] then
  336.                 if not tasks[selected].dead then
  337.                     if evt[1] == "mouse_click" or evt[1] == "mouse_up" or evt[1] == "mouse_down" or evt[1] == "mouse_drag" then
  338.                         if evt[3] > windows[selected]['xA'] and evt[3] < windows[selected]['xO'] and evt[4] > windows[selected]['yA'] and evt[4] < windows[selected]['yO'] then
  339.                             evt[3] = evt[3]-windows[selected]['xA']
  340.                             evt[4] = evt[4]-windows[selected]['yA']
  341.                             term.redirect(windows[selected]['uw'])
  342.                             tasks[selected].resume(unpack(evt))
  343.                             term.redirect(oldTerm)
  344.                         else
  345.                             term.redirect(windows[selected]['uw'])
  346.                             tasks[selected].resume({})
  347.                             term.redirect(oldTerm)
  348.                         end
  349.                     else
  350.                         term.redirect(windows[selected]['uw'])
  351.                         tasks[selected].resume(unpack(evt))
  352.                         term.redirect(oldTerm)
  353.                     end
  354.                 end
  355.             end
  356.             for each, entry in ipairs(queueRemove) do
  357.                 tasks[entry] = nil
  358.                 windows[entry] = nil
  359.                 table.remove(queueRemove, each)
  360.  
  361.             end
  362.             evt = {os.pullEventRaw()}
  363.         end
  364.     end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement