King0fGamesYami

[WIP]windowManager

Nov 16th, 2017
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.40 KB | None | 0 0
  1. --install blittle
  2. if not fs.exists( "stitch" ) then
  3.     local h = http.get( 'https://pastebin.com/raw/CTrVdFK9' )
  4.     if not h then
  5.         error( "Failure to install stitch from 'CTrVdFK9'", 0 )
  6.     end
  7.     local data = h.readAll()
  8.     h.close()
  9.     local file = fs.open( "stitch", "w" )
  10.     file.write( data )
  11.     file.close()
  12. end
  13. --install statemachine
  14. if not fs.exists( "statemachine" ) then
  15.     local h = http.get( "https://pastebin.com/raw/3qe1iUQc" )
  16.     if not h then
  17.         error( "Failure to install state machine from '3qe1iUQc'", 0 )
  18.     end
  19.     local data = h.readAll()
  20.     h.close()
  21.     local file = fs.open( "statemachine", "w" )
  22.     file.write( data )
  23.     file.close()
  24. end
  25.  
  26. --load statemachine
  27. if not statemachine then
  28.     os.loadAPI( "statemachine" )
  29. end
  30.  
  31. --menu stuff
  32. function menu( title, ... )
  33.     --edit the background color to make the GUI more unique
  34.         term.setBackgroundColor( colors.black )
  35.         local debug = false --#turn to true to see what it's thinking
  36.         local tArgs = { ... }
  37.         local pages = {[1]={}}
  38.         for i = 1, #tArgs, 1 do
  39.                 if #pages[ #pages ] == 7 then
  40.                         pages[ #pages + 1 ] = {}
  41.                 end
  42.                 pages[ #pages ][ #pages[#pages] + 1 ] = tArgs[ i ]
  43.         end
  44.         local maxLen = 0
  45.         for k, v in ipairs( tArgs ) do
  46.                 if #v > maxLen then maxLen = #v end
  47.         end
  48.         local maxx, maxy = term.getSize()
  49.         if maxLen > maxx - 20 then
  50.                 error( 'largest string is too large', 2 )
  51.         end
  52.         local centerx = math.ceil( maxx/2 )
  53.         local centery
  54.         local yValue = {}
  55.         local page = 1
  56.         local selected = math.ceil( #pages[ page ] / 2 )
  57.         local function render()
  58.                 local tbl = pages[ page ]
  59.                 centery = (maxy/2) - #tbl/2
  60.                 term.clear()
  61.                 term.setCursorPos( centerx - #title/2 + 1, 2 )
  62.                 term.write( title )
  63.                 for i = 1, #tbl do
  64.                         term.setCursorPos( centerx - (#tbl[i]/2), centery + i )
  65.                         yValue[ i ] = centery + i
  66.                         term.write( tbl[ i ] )
  67.                 end
  68.                 if pages[ page - 1 ] then
  69.                         term.setCursorPos( 3, centery + #tbl/2 + 1 )
  70.                         term.write( "previous" )
  71.                 end
  72.                 if pages[ page + 1 ] then
  73.                         term.setCursorPos( maxx - 5, centery + #tbl/2 + 1 )
  74.                         term.write( "next" )
  75.                 end
  76.                 local str = "(" .. page .. "/" .. #pages .. ")"
  77.                 term.setCursorPos( centerx - (#str/2), maxy )
  78.                 term.write( str )
  79.         end
  80.         while true do
  81.                 render()
  82.                 if debug then
  83.                         term.setCursorPos( 1, 1 )
  84.                         term.write( selected )
  85.                         term.setCursorPos( 1, 2 )
  86.                         term.write( page )
  87.                 end
  88.                 if term.isColor() then
  89.                         term.setTextColor( colors.yellow )
  90.                 end
  91.                 if selected == "previous" and not pages[ page - 1 ] then
  92.                         selected = math.ceil( #pages[ page ]/2 )
  93.                 elseif selected == "next" and not pages[ page + 1 ] then
  94.                         selected = math.ceil( #pages[ page ]/2 )
  95.                 end
  96.                 if type( selected ) == "number" then
  97.                         term.setCursorPos( centerx - (#pages[page][selected]/2) - 3, yValue[ selected ] )
  98.                         term.write( "[" )
  99.                         term.setCursorPos( centerx + (#pages[page][selected]/2) + 2, yValue[ selected ] )
  100.                         term.write( "]" )
  101.                 elseif selected == "previous" then
  102.                         term.setCursorPos( 1, centery + #pages[ page ]/2 + 1 )
  103.                         term.write( "[" )
  104.                         term.setCursorPos( 12, centery + #pages[ page ]/2 + 1 )
  105.                         term.write( "]" )
  106.                 elseif selected == "next" then
  107.                         term.setCursorPos( maxx - 7, centery + #pages[ page ]/2 + 1 )
  108.                         term.write( "[" )
  109.                         term.setCursorPos( maxx, centery + #pages[ page ]/2 + 1 )
  110.                         term.write( "]" )
  111.                 end
  112.                 if term.isColor() then
  113.                         term.setTextColor( colors.white )
  114.                 end
  115.                 local event, key = os.pullEvent( "key" )
  116.                 local old = selected
  117.                 if key == 200 and type( selected ) == "number" and pages[ page ][ selected - 1 ] then
  118.                         selected = selected - 1
  119.                 elseif key == 208 and type( selected ) == "number" and pages[ page ][ selected + 1 ] then
  120.                         selected = selected + 1
  121.                 elseif key == 28 then
  122.                         if type( selected ) == "number" then
  123.                                 return pages[ page ][ selected ]
  124.                         elseif selected == "next" and pages[ page + 1 ] then
  125.                                 page = page + 1
  126.                         elseif selected == "previous" and pages[ page - 1 ] then
  127.                                 page = page - 1
  128.                         end
  129.                 elseif key == 203 then
  130.                         if selected == "next" then
  131.                                 selected = math.ceil( #pages[ page ]/2 )
  132.                         elseif type( selected ) == "number" and pages[ page - 1 ] then
  133.                                 selected = "previous"
  134.                         end
  135.                 elseif key == 205 then
  136.                         if selected == "previous" then
  137.                                 selected = math.ceil( #pages[ page ]/2 )
  138.                         elseif type( selected ) == "number" and pages[ page + 1 ] then
  139.                                 selected = "next"
  140.                         end
  141.                 end
  142.         end
  143. end
  144.  
  145. umenu = statemachine.unblock( menu )
  146.  
  147. local tPrograms = {}
  148.  
  149. local function cleanNils(t)
  150.     local ans = {}
  151.     for _,v in pairs(t) do
  152.         ans[ #ans+1 ] = v
  153.     end
  154.     return ans
  155. end
  156.  
  157. local function addProgram( window, program, monitorName )
  158.     local prgm = {}
  159.     prgm.func = statemachine.unblock( loadfile( program ) )
  160.     prgm.win = window
  161.     prgm.monName = monitorName
  162.     tPrograms[ #tPrograms + 1 ] = prgm
  163. end
  164.  
  165. local tMonitors = {}
  166.  
  167. peripheral.find( "monitor", function( name, object )
  168.     tMonitors[ #tMonitors + 1 ] = name
  169. end )
  170.  
  171. local dofile = function( str )
  172.     local fn = loadfile( str, getfenv() )
  173.     return fn()
  174. end
  175.  
  176. local function extendHorizantal( name1, name2 )
  177.     local stitch = dofile( "stitch" )
  178.     local list = {
  179.         { name1, name2 }
  180.     }
  181.     stitch.setMonitors( list )
  182.     return stitch
  183. end
  184.  
  185. local function extendVertical( name1, name2 )
  186.     local stitch = dofile( "stitch" )
  187.     local list = {
  188.         {name1},
  189.         {name2}
  190.     }
  191.     stitch.setMonitors( list )
  192.     return stitch
  193. end
  194.  
  195. local curTerm = term.current()
  196. local focus = 1
  197. local shift = false
  198. local control = false
  199. local in_window_menu = false
  200. local to_merge = nil
  201.  
  202. local input_events = {
  203.     ["char"] = true,
  204.     ["key"] = true,
  205.     ["key_up"] = true,
  206.     ["paste"] = true,
  207.     ["terminate"] = true,
  208. }
  209.  
  210. local function runMenu()
  211.     local complete, option
  212.     if tPrograms[focus].monName then
  213.         complete, option = umenu( "Options", "Merge Vertically", "Merge Horizantally", "Split", "Exit" )
  214.     else
  215.         complete, option = umenu( "Options", "Split", "Exit" )
  216.     end
  217.     if complete then
  218.         if option == "Split" then
  219.             local w, h = tPrograms[focus].win.getSize()
  220.             w = math.floor( w / 2 )
  221.             h = math.floor( h / 2 )
  222.             local win = window.create(tPrograms[focus].win, 1, 1, w, h )
  223.             addProgram( win, "rom/programs/shell.lua" )
  224.             local win = window.create(tPrograms[focus].win, 1, 1 + h, w, h )
  225.             addProgram( win, "rom/programs/shell.lua" )
  226.             local win = window.create( tPrograms[focus].win, 1 + w, 1, w, h )
  227.             addProgram( win, "rom/programs/shell.lua" )
  228.             local win = window.create( tPrograms[focus].win, 1 + w, 1 + h, w, h )
  229.             addProgram( win, "rom/programs/shell.lua" )
  230.         end
  231.  
  232.         if option == "Merge Vertically" and not to_merge then
  233.             to_merge = tPrograms[ focus ]
  234.         elseif option == "Merge Vertically" and to_merge then
  235.             local win = extendVertical( to_merge.monName, tPrograms[ focus ].monName )
  236.             addProgram( win, "rom/programs/shell.lua" )
  237.             to_merge = nil
  238.         end
  239.  
  240.         if option == "Merge Horizantally" and not to_merge then
  241.             to_merge = tPrograms[ focus ]
  242.         elseif option == "Merge Horizantally" and to_merge then
  243.             local win = extendHorizantal( to_merge.monName, tPrograms[ focus].monName )
  244.             addProgram( win, "rom/programs/shell.lua" )
  245.             to_merge = nil
  246.         end
  247.         tPrograms[focus] = nil
  248.         in_window_menu = false
  249.     end
  250. end
  251.  
  252. statemachine.setLoop( function()
  253.     local event, key = statemachine.pullEvent()
  254.     if event == "terminate" then
  255.         return true
  256.     end
  257.  
  258.     if key == keys.rightShift or key == keys.leftShift then
  259.         if event == "key" then
  260.             shift = true
  261.         elseif event == "key_up" then
  262.             shift = false
  263.         end
  264.     end
  265.  
  266.     if key == keys.rightCtrl or key == keys.leftCtrl then
  267.         if event == "key" then
  268.             control = true
  269.         elseif event == "key_up" then
  270.             control = false
  271.         end
  272.     end
  273.  
  274.     if event == "key" and key == keys.tab then
  275.         if shift then
  276.             --change process
  277.             focus = focus + 1
  278.             if not tPrograms[ focus ] then
  279.                 focus = 1
  280.             end
  281.             --print( "focus is now " .. focus )
  282.         elseif control then
  283.             -- open window control menu
  284.             in_window_menu = true
  285.         end
  286.     end
  287.  
  288.     if #tPrograms == 0 then
  289.         addProgram( curTerm, "rom/programs/shell.lua" )
  290.     end
  291.  
  292.     if input_events[ event ] then
  293.         term.redirect( tPrograms[ focus ].win )
  294.         if in_window_menu then
  295.             runMenu()
  296.         else
  297.             local complete = tPrograms[ focus ].func()
  298.             if complete then
  299.                 tPrograms[ focus ].func = loadfile( "rom/programs/shell.lua" )
  300.             end
  301.         end
  302.     else
  303.         for i = 1, #tPrograms do
  304.             term.redirect( tPrograms[i].win )
  305.             local complete = tPrograms[i].func()
  306.             if complete then
  307.                 tPrograms[ i ].func = loadfile( "rom/programs/shell.lua" )
  308.             end
  309.         end
  310.     end
  311.     tPrograms = cleanNils( tPrograms )
  312.     if not tPrograms[ focus ] then
  313.         focus = 1
  314.     end
  315.     term.redirect( curTerm )
  316. end)
  317.  
  318. addProgram( curTerm, "rom/programs/shell.lua" )
  319.  
  320. peripheral.find( "monitor", function( k, v )
  321.     v.clear()
  322.     v.setCursorPos( 1, 1 )
  323.     addProgram( v, "rom/programs/shell.lua", k )
  324. end )
  325.  
  326. statemachine.run()
Advertisement
Add Comment
Please, Sign In to add comment