Advertisement
LDDestroier

STD-GUI BETA

Jun 10th, 2016
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 45.86 KB | None | 0 0
  1. --[[
  2.     STD Graphical User Interface! (STD-GUI)!
  3.     Made by LDDestroier/EldidiStroyrr (same guy)
  4.  
  5.     This program is a standalone GUI for Super Text Downloader, or STD for short.
  6.     It has category sorting, program searching, smooth scrolling, and run support (not just download)
  7.     This will tell you if you're overwriting a file, so no worry.
  8.  
  9.     As of May 15th (my GOSH DARN birthday) 2016, STD-GUI now lets you install SimSoft applications in the store interface!
  10.     As of Jan 11th 2018, STD-GUI now lets you install Axiom OS applications too!
  11.  
  12.     pastebin get uMZ23APu stdguib
  13.     std PB uMZ23APu stdguib
  14.     std ld stdgui stdgui
  15.  
  16.     This is a beta release. You fool!
  17. --]]
  18.  
  19. --local tsv = term.current().setVisible --comment out if you are debugging
  20.  
  21. local isBeta = false --changes the update URL
  22.  
  23. if not http then --why, you...
  24.     return false, printError("HTTP must be enabled to use STD. Contact an administrator for assistance.")
  25. else
  26.     if not http.checkURL("http://pastebin.com") then
  27.         return false, printError("For some reason, Pastebin.com is whitelisted. Abort.")
  28.     end
  29. end
  30. local scr_x, scr_y = term.getSize()
  31.  
  32. local doDisplayTitle = false
  33. local relativePath = false
  34. local doColorize = true
  35.  
  36. if type(std) ~= "table" then std = {} end
  37.  
  38. local overrideNoOS = false --prevent SimSoft functions, even if it's installed
  39. local isSimSoft = false --special integration into SimSoft!
  40. local isAxiom = false --special integration into Axiom!
  41. std.channel = "STD"
  42. std.prevChannel = std.channel
  43.  
  44. std.channelURLs = { --special pastebin URLs for getting a list of files.
  45.     ["STD"] = "http://pastebin.com/raw/VJuY551Y", --default store list
  46.     ["Discover"] = "http://pastebin.com/raw/9bXfCz6M", --owned by dannysmc95
  47. --  ["OnlineAPPS"] = "http://pastebin.com/raw/g2EnDYLp", --owned by Twijn, but discontinued.
  48.     ["STD-Media"] = "https://pastebin.com/raw/3JZHXTGL", --list of pictures and music
  49. }
  50. local palate
  51. palate = {
  52.     pleasewait = {
  53.         txt = colors.lightGray,
  54.         bg = colors.black,
  55.     },
  56.     store = {
  57.         bg = colors.black,
  58.         txt = colors.white,
  59.         bgchar = " ",
  60.         entrybg = colors.gray,
  61.         entrytxt = colors.white,
  62.         entryasterisk = colors.lightGray,
  63.         closetxt = colors.white,
  64.         closebg = colors.red,
  65.         previewtxt = colors.white,
  66.         previewbg = colors.cyan,
  67.         findbg = colors.white,
  68.         findtxt = colors.black,
  69.         indicatetxt = colors.black,
  70.         indicatebg = colors.white,
  71.         theendtxt = colors.gray,
  72.         scrollbar = {
  73.             knobbg = colors.black,
  74.             knobtxt = colors.gray,
  75.             knobchar = "|",
  76.             barbg = colors.lightGray,
  77.             bartxt = colors.gray,
  78.             barchar = "|",
  79.         }
  80.     },
  81.     item = {
  82.         bg = colors.gray,
  83.         txt = colors.white,
  84.         specialtxt = colors.yellow,
  85.         previewtxt = colors.white,
  86.         previewbg = colors.black,
  87.         forumtxt = colors.lightGray,
  88.         forumbg = colors.gray,
  89.         closetxt = colors.white,
  90.         closebg = colors.red,
  91.         runtxt = colors.white,
  92.         runbg = colors.green,
  93.         downloadtxt = colors.white,
  94.         downloadbg = colors.green,
  95.     },
  96.     menubar = {
  97.         bg = colors.black,
  98.         categorytxt = colors.lightGray,
  99.         categorybg = colors.black,
  100.         channeltxt = colors.lightGray,
  101.         channelbg = colors.black,
  102.         hotkeytxt = colors.gray,
  103.         categorymenu = {
  104.             selecttxt = colors.lightGray,
  105.             selectbg = colors.black,
  106.             bg = colors.black,
  107.             txt = colors.lightGray,
  108.             orbtxt = colors.black,
  109.             cursortxt = colors.black,
  110.             cursorbg = colors.lightGray,
  111.             borderbg = colors.black,
  112.         },
  113.         channelmenu = {
  114.             selecttxt = colors.lightGray,
  115.             selectbg = colors.black,
  116.             bg = colors.lightGray,
  117.             txt = colors.lightGray,
  118.             orbtxt = colors.black,
  119.             cursortxt = colors.black,
  120.             cursorbg = colors.lightGray,
  121.             borderbg = colors.black,
  122.         }
  123.     }
  124. }
  125.  
  126. local getEvents = function(...)
  127.     local output
  128.     while true do
  129.         output = {os.pullEvent()}
  130.         for a = 1, #arg do
  131.             if type(arg[a]) == "boolean" then
  132.                 if doRender == arg[a] then
  133.                     return {}
  134.                 end
  135.             elseif output[1] == arg[a] then
  136.                 return unpack(output)
  137.             end
  138.         end
  139.     end
  140. end
  141.  
  142. local charClear = function(char)
  143.     local cx,cy = term.getCursorPos()
  144.     for y = 1, scr_y do
  145.         term.setCursorPos(1,y)
  146.         term.write(char:sub(1,1):rep(scr_x))
  147.     end
  148.     term.setCursorPos(cx,cy)
  149. end
  150.  
  151. std.channelNames = {}
  152. for k,v in pairs(std.channelURLs) do
  153.     table.insert(std.channelNames,k)
  154. end
  155.  
  156. std.stdList = "."..std.channel:lower().."_list"
  157.  
  158. if (fs.isDir("SimSoft/Data") and fs.isDir("SimSoft/SappS")) and (not overrideNoOS) then --checks if SimSoft is installed
  159.     isSimSoft = true
  160. elseif (fs.isDir("Axiom") and fs.exists("Axiom/sys.axs")) and (not overrideNoOS) then --checks if Axiom is installed
  161.     isAxiom = true
  162. end
  163.  
  164. local cprint = function(txt,y)
  165.     local cX,cY = term.getCursorPos()
  166.     term.setCursorPos(math.ceil(scr_x/2)-math.floor(#txt/2),y or cY)
  167.     term.write(txt)
  168. end
  169.  
  170. local scroll = 1 --one is the loneliest number...weaboo
  171. local scrollX = 1 --to view longer program names
  172. local maxScroll
  173. std.std_version = 101 --to prevent updating to std command line
  174.  
  175. local setMaxScroll = function(catagory)
  176.     local output = 0
  177.     for k,v in pairs(std.storeURLs) do
  178.         if (v.catagory == catagory) or catagory == 0 then
  179.             output = output + 1
  180.         end
  181.     end
  182.     return (output*4)-(scr_y-4)
  183. end
  184. local catag = 0
  185.  
  186. local pleaseWait = function(text)
  187.     term.setBackgroundColor(palate.pleasewait.bg)
  188.     term.setTextColor(palate.pleasewait.txt)
  189.     term.clear()
  190.     cprint(text or "Getting list...please wait",scr_y/2)
  191. end
  192.  
  193. local coolPleaseWait = function()
  194.     local scr_x, scr_y = term.getSize()
  195.     local cols = "f7"
  196.     local length = scr_x/2
  197.     local render = function(col1,col2,prog,forwards)
  198.         term.setCursorPos(1,1)
  199.         local screen = (col1:rep(prog)..col2:rep(length-prog)):rep(scr_x*scr_y):sub(1,(scr_x*scr_y))
  200.         local line
  201.         for a = forwards and 1 or scr_y, forwards and scr_y or 1, forwards and 1 or -1 do
  202.             line = screen:sub((a-1)*scr_x+1,a*scr_x)
  203.             term.setCursorPos(1,a)
  204.             term.blit(("L"):rep(#line),line,line)
  205.         end
  206.     end
  207.     local pos1 = 2
  208.     local pos2 = pos1 - 1
  209.     local forwards = true
  210.     local reverse = false
  211.     while true do
  212.         for a = reverse and length or 1, reverse and 1 or length, reverse and -1 or 1 do
  213.             render(cols:sub(pos1,pos1),cols:sub(pos2,pos2),a,forwards)
  214.             sleep(0.0)
  215.         end
  216.            forwards = not forwards
  217.         reverse = not reverse
  218.         pos1 = (pos1 + 1)
  219.         pos2 = (pos2 + 1)
  220.         if pos1 > #cols then pos1 = 1 end
  221.         if pos2 > #cols then pos2 = 1 end
  222.     end
  223. end
  224.  
  225. local setDefaultColors = function()
  226.     term.setBackgroundColor(palate.store.bg)
  227.     term.setTextColor(palate.store.txt)
  228. end
  229.  
  230. local displayHelp = function(cli)
  231.     local helptext = [[
  232. This is a graphical interface to the STD downloader program.
  233. Use 'stdgui update' to update the list, or use 'F5'.
  234. If you want your program on it, PM LDDestroier on the CC forums.
  235. Hotkeys:
  236.     'Q' quit or back
  237.     'F5' refresh
  238.     'F1' set category
  239.     'F3' set channel
  240.     'F' or 'F6' search
  241.     'F12' update STDGUI
  242.     if normal computer, press 0-9 to select store item
  243. ]]
  244.     if cli then
  245.         return print(helptext)
  246.     else
  247.         setDefaultColors()
  248.         term.clear()
  249.         term.setCursorPos(2,2)
  250.         print(helptext)
  251.         sleep(0)
  252.         print("\nPress a key to go back.")
  253.         os.pullEvent("key")
  254.         return
  255.     end
  256. end
  257.  
  258. local getTableSize = function(tbl)
  259.     local amnt = 0
  260.     for k,v in pairs(tbl) do
  261.         amnt = amnt + 1
  262.     end
  263.     return amnt
  264. end
  265.  
  266. local colors_names = {
  267.     ["0"] = colors.white,
  268.     ["1"] = colors.orange,
  269.     ["2"] = colors.magenta,
  270.     ["3"] = colors.lightBlue,
  271.     ["4"] = colors.yellow,
  272.     ["5"] = colors.lime,
  273.     ["6"] = colors.pink,
  274.     ["7"] = colors.gray,
  275.     ["8"] = colors.lightGray,
  276.     ["9"] = colors.cyan,
  277.     ["a"] = colors.purple,
  278.     ["b"] = colors.blue,
  279.     ["c"] = colors.brown,
  280.     ["d"] = colors.green,
  281.     ["e"] = colors.red,
  282.     ["f"] = colors.black,
  283. }
  284.  
  285. local blit_names = {}
  286. for k,v in pairs(colors_names) do
  287.     blit_names[v] = k
  288. end
  289.  
  290. local codeNames = { --just for checking, not for any translation
  291.     ["r"] = "reset",
  292.     ["{"] = "stopFormatting",
  293.     ["}"] = "startFormatting",
  294. }
  295.  
  296. local explode = function(div,str)
  297.     if (div=='') then return false end
  298.     local pos,arr = 0,{}
  299.     for st,sp in function() return string.find(str,div,pos,true) end do
  300.         table.insert(arr,string.sub(str,pos,st-1))
  301.         pos = sp + 1
  302.     end
  303.     table.insert(arr,string.sub(str,pos))
  304.     return arr
  305. end
  306.  
  307. local blitWrap = function(text,txt,bg)
  308.     local allIssues = ""
  309.     if not text then allIssues = allIssues.."no text, " end
  310.     if not txt then allIssues = allIssues.."no txt, " end
  311.     if not bg then allIssues = allIssues.."no bg, " end
  312.     if not (#text == #txt and #txt == #bg) then allIssues = allIssues.."incongruent lengths" end
  313.     if #allIssues > 0 then error(allIssues) end
  314.     local wordNo = 1
  315.     local words = explode(" ",text)
  316.     local lines = 0
  317.     local scr_x, scr_y = term.getSize()
  318.     local cx,cy
  319.     for a = 1, #text do
  320.         cx,cy = term.getCursorPos()
  321.         if text:sub(a,a) == " " and text:sub(a-1,a-1) ~= " " and a > 1 then
  322.             wordNo = wordNo + 1
  323.             if cx + #words[wordNo] > scr_x then
  324.                 term.setCursorPos(1,cy+1)
  325.                 lines = lines + 1
  326.             end
  327.         end
  328.         cx,cy = term.getCursorPos()
  329.         if text:sub(a,a) == "\n" then
  330.             term.setCursorPos(1,cy+1)
  331.             lines = lines + 1
  332.         elseif not (cx == 1 and text:sub(a,a) == " ") then
  333.             term.blit(text:sub(a,a),txt:sub(a,a),bg:sub(a,a))
  334.         end
  335.         if cx == scr_x then
  336.             term.setCursorPos(1,cy+1)
  337.             lines = lines + 1
  338.         end
  339.     end
  340.     return lines
  341. end
  342.  
  343. local moveOn, textToBlit
  344. textToBlit = function(str,substart,substop)
  345.     local p = 1
  346.     local output = ""
  347.     local txcolorout = ""
  348.     local bgcolorout = ""
  349.     local txcode = "&"
  350.     local bgcode = "~"
  351.     local doFormatting = true
  352.     local usedformats = {}
  353.     local txcol,bgcol = blit_names[term.getTextColor()], blit_names[term.getBackgroundColor()]
  354.     local origTX,origBG = blit_names[term.getTextColor()], blit_names[term.getBackgroundColor()]
  355.     local cx,cy,barestr
  356.     substart = substart or 0
  357.     substop = substop or #str
  358.     if not (substart == 0 and substop == #str) then
  359.         barestr = textToBlit(str)
  360.     else
  361.         if substart < 0 then
  362.             substart = #realstr - substart
  363.         end
  364.         if substop < 0 then
  365.             substop = #realstr - substop
  366.         end
  367.     end
  368.     moveOn = function(tx,bg)
  369.         if p >= substart and p <= substop then
  370.             output = output..str:sub(p,p)
  371.             txcolorout = txcolorout..tx
  372.             bgcolorout = bgcolorout..bg
  373.         end
  374.     end
  375.     while p <= #str do
  376.         if str:sub(p,p) == txcode then
  377.             if colors_names[str:sub(p+1,p+1)] and doFormatting then
  378.                 txcol = str:sub(p+1,p+1)
  379.                 usedformats.txcol = true
  380.                 p = p + 1
  381.             elseif codeNames[str:sub(p+1,p+1)] then
  382.                 if str:sub(p+1,p+1) == "r" and doFormatting then
  383.                     txcol = blit_names[term.getTextColor()]
  384.                     p = p + 1
  385.                 elseif str:sub(p+1,p+1) == "{" and doFormatting then
  386.                     doFormatting = false
  387.                     p = p + 1
  388.                 elseif str:sub(p+1,p+1) == "}" and (not doFormatting) then
  389.                     doFormatting = true
  390.                     p = p + 1
  391.                 else
  392.                     moveOn(txcol,bgcol)
  393.                 end
  394.             else
  395.                 moveOn(txcol,bgcol)
  396.             end
  397.             p = p + 1
  398.         elseif str:sub(p,p) == bgcode then
  399.             if colors_names[str:sub(p+1,p+1)] and doFormatting then
  400.                 bgcol = str:sub(p+1,p+1)
  401.                 usedformats.bgcol = true
  402.                 p = p + 1
  403.             elseif codeNames[str:sub(p+1,p+1)] and (str:sub(p+1,p+1) == "r") and doFormatting then
  404.                 bgcol = blit_names[term.getBackgroundColor()]
  405.                 p = p + 1
  406.             else
  407.                 moveOn(txcol,bgcol)
  408.             end
  409.             p = p + 1
  410.         else
  411.             moveOn(txcol,bgcol)
  412.             p = p + 1
  413.         end
  414.     end
  415.     return output, txcolorout, bgcolorout, usedformats
  416. end
  417.  
  418. local writef = function(txt,noWrite,substart,substop)
  419.     if doColorize then
  420.         local text, textCol, bgCol, usedformats = textToBlit(txt,substart,substop)
  421.         local out = blitWrap(text,textCol,bgCol,noWrite)
  422.         return out, #text, usedformats
  423.     else
  424.         if noWrite then
  425.             local cx,cy = term.getCursorPos()
  426.             return math.floor((cx+#cf(txt))/scr_x), #cf(txt), {} --this is approximate, and might mess up with multiline strings
  427.         else
  428.             return write(txt), #txt, {}
  429.         end
  430.     end
  431. end
  432.  
  433. local printf = function(txt,noWrite)
  434.     return writef(tostring(txt.."\n"),noWrite)
  435. end
  436.  
  437. local function runURL(url, ...)
  438.     local program = http.get(url)
  439.     if not program then return false end
  440.     program = program.readAll()
  441.     local func = loadstring(program)
  442.     setfenv(func, getfenv())
  443.     return func(...)
  444. end
  445.  
  446. local bow = function()
  447.     term.setBackgroundColor(palate.store.findbg)
  448.     term.setTextColor(palate.store.findtxt)
  449. end
  450.  
  451. local strless = function(str,txt,bg)
  452.     local x,y = 0,0
  453.     local str = explode("\n",str or "")
  454.     local render = function()
  455.         term.setBackgroundColor(bg)
  456.         term.setTextColor(txt)
  457.         for i = y+1, (scr_y+y)-1 do
  458.             term.setCursorPos(math.max(1,-x),i-y)
  459.             term.clearLine()
  460.             if str[i] then
  461.                 term.write(str[i]:sub(math.max(1,x+1)))
  462.             end
  463.         end
  464.         term.setCursorPos(1,scr_y)
  465.         term.setBackgroundColor(colors.gray)
  466.         term.setTextColor(colors.white)
  467.         term.clearLine()
  468.         term.write("(Q)uit, Goto (L)ine")
  469.         local ting = "Ln."..math.min(math.max(y+1,0),#str)
  470.         term.setCursorPos((scr_x-#ting)+1,scr_y)
  471.         term.write(ting)
  472.     end
  473.     render()
  474.     maxY = (#str-scr_y)+1
  475.     while true do
  476.         local evt, key, mx, my = os.pullEvent()
  477.         local oldY = y
  478.         local oldX = x
  479.         if evt == "key" then
  480.             if key == keys.up then
  481.                 y = y-1
  482.             elseif key == keys.down then
  483.                 y = y+1
  484.             elseif key == keys.pageUp then
  485.                 y = y-(scr_y-1)
  486.             elseif key == keys.pageDown then
  487.                 y = y+(scr_y-1)
  488.             elseif key == keys.left then
  489.                 x = x-1
  490.             elseif key == keys.right then
  491.                 x = x+1
  492.             elseif key == keys.home then
  493.                 y = 0
  494.             elseif key == keys["end"] then
  495.                 y = maxY
  496.             elseif (key == keys.q) or (key == keys.x) then
  497.                 sleep(0)
  498.                 break
  499.             elseif (key == keys.l) then
  500.                 term.setCursorPos(1,scr_y)
  501.                 term.setBackgroundColor(colors.gray)
  502.                 term.setTextColor(colors.white)
  503.                 term.clearLine()
  504.                 term.write("Line #:")
  505.                 sleep(0)
  506.                 y = (tonumber(read()) or (y+1)) - 1
  507.             end
  508.         elseif evt == "mouse_scroll" then
  509.             y = y + key
  510.         elseif evt == "mouse_click" and key == 1 then
  511.             if my == scr_y and (mx >= 1 and mx <= 11) then
  512.                 sleep(0)
  513.                 break
  514.             end
  515.         end
  516.         if x < 0 then x = 0 end
  517.         if y < 0 then y = 0 end
  518.         if y > maxY then y = maxY end
  519.         if (x ~= oldX) or (y ~= oldY) or (key == keys.l) then
  520.             render()
  521.         end
  522.     end
  523. end
  524. local contentsFile = function(url)
  525.     local prog = http.get(url)
  526.     if prog then return prog.readAll()
  527.     else return false, "could not connect" end
  528. end
  529. local getFile = function(filename,url)
  530.     if fs.isReadOnly(filename) then
  531.         return false, "access denied"
  532.     end
  533.     local prog
  534.     if type(url) == "table" then
  535.         prog = std.contextualGet(url[1])
  536.     else
  537.         prog = http.get(url)
  538.     end
  539.     if not prog then
  540.         return false, "could not connect"
  541.     end
  542.     prog = prog.readAll()
  543.     local fyle = fs.open(filename,"w")
  544.     fyle.write(prog)
  545.     fyle.close()
  546.     return true, fs.getSize(filename)
  547. end
  548. std.getSTDList = function(prevChannel)
  549.     catag = 0
  550.     local url = std.channelURLs[std.channel] --URL of URL list for whatever channel you have selected.
  551.     pleaseWait()
  552.     local contents = http.get(url)
  553.     if not contents then
  554.         if shell then
  555.             print("Couldn't update list!")
  556.         end
  557.         return false, "Couldn't update list!"
  558.     else
  559.         std.storeURLs = {}
  560.         _G.std = std
  561.         local oldENV = _ENV
  562.         local _ENV = {}
  563.         for k,v in pairs(_G) do
  564.             _ENV[k] = v
  565.         end
  566.         local outcome
  567.         if not fs.isReadOnly(std.stdList) then
  568.             local program = contents.readAll()
  569.             local file = fs.open(std.stdList,"w")
  570.             file.writeLine(program)
  571.             file.close()
  572.             outcome = dofile(std.stdList)
  573.         else
  574.             outcome = runURL(url)
  575.         end
  576.         ENV = oldENV
  577.         if outcome == false then
  578.             term.setBackgroundColor(colors.black)
  579.             term.setTextColor(term.isColor() and colors.red or colors.lightGray)
  580.             term.clear()
  581.             cprint("STD channel \""..std.channel.."\" is down right now.",2)
  582.             term.setTextColor(colors.white)
  583.             cprint("Either try again later,",4)
  584.             cprint("contact LDDestroier on the CC forums,",5)
  585.             cprint("or tell the owner of the channel.",6)
  586.             cprint("Press a key to go back.",8)
  587.             term.setTextColor(colors.gray)
  588.             cprint("Sorry bout that!",scr_y)
  589.             std.channel = prevChannel
  590.             sleep(0.1)
  591.             os.pullEvent("char")
  592.             pleaseWait("Changing list...please wait...")
  593.             return std.getSTDList("STD")
  594.         end
  595.         local output
  596.         if not fs.isReadOnly(std.stdList) then
  597.             output = "Downloaded to "..std.stdList
  598.         else
  599.             output = "Got store codes."
  600.         end
  601.         maxScroll = setMaxScroll(catag)
  602.         return true, output
  603.     end
  604. end
  605.  
  606. local cisf = function(str,fin)
  607.     return string.find(str:lower(),fin:lower())
  608. end
  609.  
  610. local clearMostline = function(length,char)
  611.     local pX,pY = term.getCursorPos()
  612.     term.setCursorPos(1,pY)
  613.     term.write(string.rep(char or " ",length or (scr_x-1)))
  614.     term.setCursorPos(pX,pY)
  615. end
  616.  
  617. local dotY
  618. local doScrollBar = false
  619.  
  620. local renderStore = function(list,filter,scrollY,namescroll,fixedDotY,buttonIndicate)
  621.     local fullrend = {}
  622.     local visiblerend = {}
  623.     local amnt = 0
  624.     local output = {}
  625.     local colors_output = {}
  626.     local num = 0
  627.     if tsv then tsv(false) end
  628.     for k,v in pairs(list) do
  629.         if (v.catagory == filter) or filter == 0 then
  630.             table.insert(fullrend,{" &"..blit_names[palate.store.entryasterisk].."*&"..blit_names[palate.store.entrytxt]..v.title,v})
  631.             table.insert(fullrend,{" by &r"..v.creator,v})
  632.             table.insert(fullrend,{" Category: "..std.storeCatagoryNames[v.catagory],v,v.catagory})
  633.             table.insert(fullrend,"nilline")
  634.         end
  635.     end
  636.     table.insert(fullrend,"")
  637.     dotY = fixedDotY or math.floor((scr_y-2)*((scroll-1)/(maxScroll-1)))+2
  638.     for a = scrollY, (scr_y+scrollY)-1 do
  639.         if type(fullrend[a]) == "table" then
  640.             table.insert(visiblerend,fullrend[a][1])
  641.             table.insert(output,fullrend[a][2])
  642.             if fullrend[a][3] then
  643.                 table.insert(colors_output,fullrend[a][3])
  644.             else
  645.                 table.insert(colors_output,false)
  646.             end
  647.         else
  648.             table.insert(visiblerend,fullrend[a])
  649.             table.insert(output,{})
  650.             table.insert(colors_output,false)
  651.         end
  652.     end
  653.     setDefaultColors()
  654.     charClear(palate.store.bgchar)
  655.     for a = 1, #visiblerend do
  656.         term.setCursorPos(2-namescroll,a+1)
  657.         if visiblerend[a] == "nilline" then
  658.             setDefaultColors()
  659.             clearMostline()
  660.         else
  661.             if a < #visiblerend then
  662.                 if term.isColor() then
  663.                     if colors_output[a] then
  664.                         term.setBackgroundColor(std.storeCatagoryColors[colors_output[a]].bg)
  665.                         term.setTextColor(std.storeCatagoryColors[colors_output[a]].txt)
  666.                     else
  667.                         term.setBackgroundColor(palate.store.entrybg)
  668.                         term.setTextColor(palate.store.entrytxt)
  669.                     end
  670.                 else
  671.                     term.setBackgroundColor(colors.gray)
  672.                     term.setTextColor(colors.white)
  673.                 end
  674.                 clearMostline()
  675.                 writef(visiblerend[a])
  676.             else
  677.                 term.setBackgroundColor(palate.store.bg)
  678.                 term.setTextColor(palate.store.theendtxt)
  679.                 cprint("That's them all!")
  680.             end
  681.         end
  682.     end
  683.     local b
  684.     for a = 2, scr_y do
  685.         term.setCursorPos(scr_x,a)
  686.         if a == dotY then
  687.             term.setTextColor(palate.store.scrollbar.knobtxt)
  688.             term.setBackgroundColor(palate.store.scrollbar.knobbg)
  689.             term.write(palate.store.scrollbar.knobchar)
  690.         else
  691.             term.setTextColor(palate.store.scrollbar.bartxt)
  692.             term.setBackgroundColor(palate.store.scrollbar.barbg)
  693.             term.write(palate.store.scrollbar.barchar)
  694.         end
  695.         if buttonIndicate then
  696.             term.setCursorPos(scr_x-4,a)
  697.             term.setBackgroundColor(palate.store.indicatebg)
  698.             term.setTextColor(palate.store.indicatetxt)
  699.             b = (a+1)/4
  700.             if (b == math.floor(b)) and (visiblerend[a] and visiblerend[a] ~= "nilline") then
  701.                 term.write(" "..tostring(b):sub(#tostring(b)).." ")
  702.             end
  703.         end
  704.     end
  705.     if tsv then tsv(true) end
  706.     return output
  707. end
  708.  
  709. local simSoftInstall = function(obj,objname,appname)
  710.     local installSystemName = "STD App Distribution (sad...)"
  711.     appname = appname or objname
  712.     local getFromURL = function(url)
  713.         local cunt
  714.         if type(url) == "table" then
  715.             cunt = std.contextualGet(url[1])
  716.         else
  717.             cunt = http.get(url)
  718.         end
  719.         if not cunt then
  720.             return shit
  721.         else
  722.             if type(url) == "table" then
  723.                 return cunt.readAll(), false
  724.             else
  725.                 return cunt.readAll(), (string.find(url,"://pastebin.com/raw/") and (url:sub(-9):gsub("/","")) or false)
  726.             end
  727.         end
  728.     end
  729.     local mainpath = fs.combine("/SimSoft/SappS",objname)
  730.     local cont,pbcode = getFromURL(obj.url)
  731.     local file = fs.open("\""..fs.combine(mainpath,pbcode or "program").."\"","w")
  732.     file.write(cont)
  733.     file.close()
  734.     local file = fs.open(fs.combine(mainpath,"SappS"),"w")
  735.     file.writeLine(installSystemName)
  736.     file.writeLine("\""..fs.combine(mainpath,pbcode or "program").."\"")
  737.     file.writeLine(appname:sub(1,9))
  738.     file.close()
  739.     return true, "Installed!"
  740. end
  741.  
  742. local getFindList = function(name)
  743.     local output = {}
  744.     for k,v in pairs(std.storeURLs) do
  745.         if cisf(k,name) or cisf(textToBlit(v.title),name) or cisf(textToBlit(v.creator),name) then
  746.             output[k] = v
  747.         end
  748.         if output[k] ~= v and v.keywords then
  749.             for a = 1, #v.keywords do
  750.                 if cisf(v.keywords[a],name) then
  751.                     output[k] = v
  752.                     break
  753.                 end
  754.             end
  755.         end
  756.     end
  757.     return output
  758. end
  759.  
  760. local doFindFunc = function(name)
  761.     scroll = 1
  762.     maxScroll = setMaxScroll(catag)
  763.     renderStore(getFindList(name),catag,scroll,scrollX,_,not term.isColor())
  764.     term.setCursorPos(1,1)
  765.     bow()
  766.     term.clearLine()
  767.     write("Find: ")
  768. end
  769.  
  770. local funcread = function(repchar,rHistory,doFunc,noNewLine)
  771.     local scr_x,scr_y = term.getSize()
  772.     local sx,sy = term.getCursorPos()
  773.     local cursor = 1
  774.     rHistory = rHistory or {}
  775.     local rCursor = #rHistory+1
  776.     local output = ""
  777.     term.setCursorBlink(true)
  778.     while true do
  779.         local evt,key = os.pullEvent()
  780.         local cx,cy = term.getCursorPos()
  781.         if evt == "key" then
  782.             if key == keys.enter then
  783.                 if not noNewLine then
  784.                     write("\n")
  785.                 end
  786.                 term.setCursorBlink(false)
  787.                 return output
  788.             elseif key == keys.left then
  789.                 if cursor-1 >= 1 then
  790.                     cursor = cursor - 1
  791.                 end
  792.             elseif key == keys.right then
  793.                 if cursor <= #output then
  794.                     cursor = cursor + 1
  795.                 end
  796.             elseif key == keys.up then
  797.                 if rCursor > 1 then
  798.                     rCursor = rCursor - 1
  799.                     term.setCursorPos(sx,sy)
  800.                     term.write((" "):rep(#output))
  801.                     output = rHistory[rCursor] or ""
  802.                     cursor = #output+1
  803.                     pleaseDoFunc = true
  804.                 end
  805.             elseif key == keys.down then
  806.                 term.setCursorPos(sx,sy)
  807.                 term.write((" "):rep(#output))
  808.                 if rCursor < #rHistory then
  809.                     rCursor = rCursor + 1
  810.                     output = rHistory[rCursor] or ""
  811.                     cursor = #output+1
  812.                     pleaseDoFunc = true
  813.                 else
  814.                     rCursor = #rHistory+1
  815.                     output = ""
  816.                     cursor = 1
  817.                 end
  818.             elseif key == keys.backspace then
  819.                 if cursor > 1 and #output > 0 then
  820.                     output = output:sub(1,cursor-2)..output:sub(cursor)
  821.                     cursor = cursor - 1
  822.                     pleaseDoFunc = true
  823.                 end
  824.             elseif key == keys.delete then
  825.                 if #output:sub(cursor,cursor) == 1 then
  826.                     output = output:sub(1,cursor-1)..output:sub(cursor+1)
  827.                     pleaseDoFunc = true
  828.                 end
  829.             end
  830.         elseif evt == "char" or evt == "paste" then
  831.             output = output:sub(1,cursor-1)..key..output:sub(cursor+(#key-1))
  832.             cursor = cursor + #key
  833.             pleaseDoFunc = true
  834.         end
  835.         if pleaseDoFunc then
  836.             pleaseDoFunc = false
  837.             if type(doFunc) == "function" then
  838.                 doFunc(output)
  839.             end
  840.             term.setCursorPos(sx,sy)
  841.             local pOut = output
  842.             if #output >= scr_x-(sx-2) then
  843.                 pOut = output:sub((#output+(sx))-scr_x)
  844.             end
  845.             if repchar then
  846.                 term.write(repchar:sub(1,1):rep(#pOut).." ")
  847.             else
  848.                 term.write(pOut.." ")
  849.             end
  850.             local cx,cy = term.getCursorPos()
  851.         end
  852.         term.setCursorPos(sx+cursor-1,cy)
  853.     end
  854. end
  855.  
  856. local prevList
  857. local findPrompt = function()
  858.     local cX,cY = term.getCursorPos()
  859.     sleep(0)
  860.     if prevList then std.storeURLs = prevList end
  861.     doFindFunc("")
  862.     prevList = std.storeURLs
  863.     std.storeURLs = getFindList(funcread(nil,{},doFindFunc,false))
  864.     term.setCursorBlink(false)
  865.     maxScroll = setMaxScroll(catag)
  866. end
  867.  
  868. local displayTitle = function()
  869.     local title = {{},{},{},{},{0,0,0,0,0,1,1,1,1,1,0,0,2,2,2,2,2,2,2,0,2,2,2,2,0,0,32768,},{0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,2,0,0,0,0,0,2,0,2,2,0,32768,},{0,0,0,0,1,0,0,0,0,0,1,0,0,0,2,2,0,0,0,0,2,2,0,0,2,0,32768,},{0,0,0,0,1,1,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,2,0,32768,},{0,0,0,0,0,1,1,1,1,1,0,0,0,0,2,0,0,0,0,2,2,0,0,2,2,0,32768,},{0,0,0,0,0,0,0,0,0,1,0,0,0,2,2,0,0,0,2,2,0,0,2,2,0,0,32768,},{0,0,0,1,1,0,0,0,1,1,0,0,2,2,0,0,0,2,2,0,0,2,2,0,0,32768,1,},{0,0,0,0,1,1,1,1,1,0,0,0,2,0,0,0,2,2,2,2,2,2,0,0,32768,1,1,},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32768,1,1,1,},{0,0,0,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,32768,1,1,1,1}}
  870.     setDefaultColors()
  871.     term.clear()
  872.     paintutils.drawImage(title,-1,1)
  873.     setDefaultColors()
  874.     term.setCursorPos(4,16)
  875.     term.write("STD-GUI "..(isBeta and "Beta" or "Stable"))
  876.     sleep(0)
  877.     local evt
  878.     repeat
  879.         evt = os.pullEvent()
  880.     until evt == "mouse_click" or evt == "key"
  881.     sleep(0)
  882. end
  883.  
  884. local fixDotY
  885.  
  886. local renderStoreItem = function(obj) --now being experimented on...
  887.     if not obj.title then return false end
  888.     local showPostURL = false
  889.     local bruffer
  890.     local scroll = 1
  891.     local doRedraw = true
  892.     local extraLines
  893.     while true do
  894.         bruffer = {
  895.             "",
  896.             " &"..blit_names[palate.item.specialtxt]..obj.title,
  897.             " &"..blit_names[palate.item.txt].."by &"..blit_names[palate.item.specialtxt]..obj.creator,
  898.             " &"..blit_names[palate.item.txt].."Category: "..std.storeCatagoryNames[obj.catagory],
  899.             "",
  900.             "&"..blit_names[palate.item.txt]..obj.description,
  901.         }
  902.         if showPostURL and obj.forumPost then
  903.             local post = " &"..blit_names[palate.item.forumtxt].."~"..blit_names[palate.item.forumbg]..obj.forumPost:gsub("http://www.",""):sub(1,-2)
  904.             table.insert(bruffer,"&8Forum URL: "..post)
  905.         end
  906.         if doRedraw then
  907.             term.setBackgroundColor(palate.item.bg)
  908.             term.clear()
  909.             term.setCursorPos(1,(-scroll)+2)
  910.             extraLines = 0
  911.             for y = 1, #bruffer do
  912.                 if not bruffer[y] then break end
  913.                 extraLines = extraLines + printf(bruffer[y])
  914.             end
  915.            
  916.             term.setCursorPos(1,scr_y)
  917.             if term.isColor() then
  918.                 term.setTextColor(palate.item.closetxt)
  919.                 term.setBackgroundColor(palate.item.closebg)
  920.             else
  921.                 term.setTextColor(colors.black)
  922.                 term.setBackgroundColor(colors.white)
  923.             end
  924.             term.clearLine()
  925.             if term.isColor() then
  926.                 term.write("CLOSE")
  927.             else
  928.                 term.write("(Q) to CLOSE")
  929.             end
  930.             if term.isColor() then
  931.                 term.setTextColor(palate.store.previewtxt)
  932.                 term.setBackgroundColor(palate.store.previewbg)
  933.                 term.setCursorPos((scr_x-16),scr_y)
  934.                 term.write("VIEW")
  935.                 term.setTextColor(palate.item.runtxt)
  936.                 term.setBackgroundColor(palate.item.runbg)
  937.                 term.setCursorPos((scr_x-11),scr_y)
  938.                 term.write("RUN")
  939.             else
  940.                 term.setTextColor(colors.black)
  941.                 term.setBackgroundColor(colors.white)
  942.                 term.setCursorPos((scr_x-22),scr_y)
  943.                 term.write("(V)IEW")
  944.                 term.setTextColor(colors.black)
  945.                 term.setBackgroundColor(colors.white)
  946.                 term.setCursorPos((scr_x-15),scr_y)
  947.                 term.write("(R)UN")
  948.             end
  949.             local txt
  950.             if isSimSoft or isAxiom then
  951.                 if term.isColor() then --yeah yeah, simsoft can't run on normal computers, but axiom can, so shut your cunting trap
  952.                     term.setTextColor(palate.item.downloadtxt)
  953.                     term.setBackgroundColor(palate.item.downloadbg)
  954.                     txt = "INSTALL!"
  955.                 else
  956.                     txt = "(I)NSTALL"
  957.                 end
  958.             else
  959.                 if term.isColor() then
  960.                     term.setTextColor(palate.item.downloadtxt)
  961.                     term.setBackgroundColor(palate.item.downloadbg)
  962.                     txt = "DOWNLOAD"
  963.                 else
  964.                     txt = "(D)OWNLOAD"
  965.                 end
  966.             end
  967.             term.setCursorPos((scr_x-(#txt-1)),scr_y)
  968.             term.write(txt)
  969.             doRedraw = false
  970.         end
  971.         local evt = {getEvents("key","mouse_click","mouse_scroll","term_resize")}
  972.         if evt[1] == "key" then
  973.             if evt[2] == keys.f then
  974.                 showPostURL = not showPostURL
  975.                 doRedraw = true
  976.             elseif evt[2] == keys.d or evt[2] == keys.i or evt[2] == keys.r or evt[2] == keys.q or evt[2] == keys.v then
  977.                 return unpack(evt)
  978.             end
  979.         elseif evt[1] == "mouse_click" then
  980.             if evt[4] == scr_y then
  981.                 return unpack(evt)
  982.             end
  983.         elseif evt[1] == "mouse_scroll" then
  984.             if scroll+evt[2] >= 1 and scroll+evt[2] <= (#bruffer+extraLines)-(scr_y-8) then
  985.                 scroll = scroll + evt[2]
  986.                 doRedraw = true
  987.             end
  988.         elseif evt[1] == "term_resize" then
  989.             doRedraw = true
  990.             scr_x,scr_y = term.getSize()
  991.         end
  992.     end
  993. end
  994.  
  995. local renderCatagoryMenu = function(expanded,cursor)
  996.     if expanded then
  997.         term.setCursorPos(1,1)
  998.         term.setBackgroundColor(palate.menubar.bg)
  999.         term.clearLine()
  1000.         term.setBackgroundColor(palate.menubar.categorymenu.selectbg)
  1001.         term.setTextColor(palate.menubar.categorymenu.selecttxt)
  1002.         if term.isColor() then
  1003.             if cursor == 0 then
  1004.                 term.setTextColor(palate.menubar.categorymenu.txt)
  1005.                 term.write(" No category")
  1006.             else
  1007.                 term.write("Select category:")
  1008.             end
  1009.         else
  1010.             term.setCursorPos(1,1)
  1011.             if cursor == 0 then
  1012.                 term.setTextColor(palate.menubar.categorymenu.txt)
  1013.                 term.write(" No category")
  1014.             else
  1015.                 term.write(" Pick category with up/down:")
  1016.             end
  1017.         end
  1018.         term.setTextColor(palate.menubar.categorymenu.txt)
  1019.         term.setBackgroundColor(palate.menubar.categorymenu.bg)
  1020.         local yposes = {}
  1021.         local longestLen = 0
  1022.         for a = 1, #std.storeCatagoryNames do
  1023.             if #std.storeCatagoryNames[a]+2 > longestLen then
  1024.                 longestLen = #std.storeCatagoryNames[a]+2
  1025.             end
  1026.         end
  1027.         longestLen = longestLen+1
  1028.         for a = 0, #std.storeCatagoryNames do
  1029.             term.setCursorPos(1,a+1)
  1030.             if term.isColor() then
  1031.                 term.setTextColor(palate.menubar.categorymenu.orbtxt)
  1032.                 term.setBackgroundColor(palate.menubar.categorymenu.bg)
  1033.                 if type(std.storeCatagoryColors) == "table" then
  1034.                     if std.storeCatagoryColors[a] then
  1035.                         term.setTextColor(std.storeCatagoryColors[a].txt)
  1036.                         term.setBackgroundColor(std.storeCatagoryColors[a].bg)
  1037.                     end
  1038.                 end
  1039.             else
  1040.                 term.setTextColor(colors.black)
  1041.                 term.setBackgroundColor(colors.lightGray)
  1042.             end
  1043.             if a > 0 then
  1044.                 clearMostline(longestLen+2)
  1045.             end
  1046.             if a == cursor then
  1047.                 if type(std.storeCatagoryColors) ~= "table" then
  1048.                     if term.isColor() then
  1049.                         if cursor == 0 then
  1050.                             term.setTextColor(palate.menubar.categorymenu.txt)
  1051.                             term.setBackgroundColor(palate.menubar.categorymenu.bg)
  1052.                         else
  1053.                             term.setTextColor(palate.menubar.categorymenu.cursortxt)
  1054.                             term.setBackgroundColor(palate.menubar.categorymenu.cursorbg)
  1055.                         end
  1056.                     else
  1057.                         term.setTextColor(colors.black)
  1058.                         term.setBackgroundColor(colors.lightGray)
  1059.                     end
  1060.                 elseif cursor == 0 then
  1061.                     term.setBackgroundColor(colors.black)
  1062.                 end
  1063.                 write(">")
  1064.             elseif a > 0 then
  1065.                 write(" ")
  1066.             end
  1067.             if a > 0 then
  1068.                 if type(std.storeCatagoryColors) ~= "table" then
  1069.                     term.setTextColor(palate.menubar.categorymenu.orbtxt)
  1070.                     term.setBackgroundColor(palate.menubar.categorymenu.bg)
  1071.                 end
  1072.                 if a == catag then
  1073.                     write("@ ")
  1074.                 else
  1075.                     write("O ")
  1076.                 end
  1077.                 write(std.storeCatagoryNames[a])
  1078.                 if term.isColor() then
  1079.                     term.setBackgroundColor(palate.menubar.categorymenu.borderbg)
  1080.                 else
  1081.                     term.setBackgroundColor(colors.black)
  1082.                 end
  1083.                 term.setCursorPos(longestLen+2,a+1)
  1084.                 term.write(" ")
  1085.                 table.insert(yposes,a+1)
  1086.             end
  1087.         end
  1088.         term.setCursorPos(1,#std.storeCatagoryNames+2)
  1089.         term.write((" "):rep(longestLen+2))
  1090.         return yposes,longestLen+2
  1091.     else
  1092.         term.setCursorPos(1,1)
  1093.         term.setBackgroundColor(palate.menubar.bg)
  1094.         term.clearLine()
  1095.         term.setTextColor(palate.menubar.categorytxt)
  1096.         term.setBackgroundColor(palate.menubar.categorybg)
  1097.         term.write("Cat.")
  1098.         term.setTextColor(palate.menubar.hotkeytxt)
  1099.         term.write("F1")
  1100.         term.setCursorPos(8,1)
  1101.         term.setTextColor(palate.menubar.channeltxt)
  1102.         term.setBackgroundColor(palate.menubar.channelbg)
  1103.         term.write("Chan.")
  1104.         term.setTextColor(palate.menubar.hotkeytxt)
  1105.         term.write("F3")
  1106.         --writef("~f&8Cat.&7F1~r&r ~f&8Chan.&7F3")
  1107.     end
  1108.     if term.isColor() then
  1109.         term.setCursorPos(scr_x-4,1)
  1110.         term.setBackgroundColor(palate.store.closebg)
  1111.         term.setTextColor(palate.store.closetxt)
  1112.         term.write("CLOSE")
  1113.     else
  1114.         term.setCursorPos(scr_x-11,1)
  1115.         term.setBackgroundColor(colors.black)
  1116.         term.setTextColor(colors.white)
  1117.         term.write("'Q' to CLOSE")
  1118.     end
  1119.     setDefaultColors()
  1120. end
  1121.  
  1122. local renderChannelMenu = function(cursor)
  1123.     term.setCursorPos(1,1)
  1124.     term.setBackgroundColor(palate.menubar.bg)
  1125.     term.clearLine()
  1126.     term.setBackgroundColor(palate.menubar.channelmenu.selectbg)
  1127.     term.setTextColor(palate.menubar.channelmenu.selecttxt)
  1128.     term.write("Select channel:")
  1129.     term.setTextColor(palate.menubar.channelmenu.txt)
  1130.     term.setBackgroundColor(palate.menubar.channelmenu.bg)
  1131.     local yposes = {}
  1132.     local longestLen = 0
  1133.     for a = 1, #std.channelNames do
  1134.         if #std.channelNames[a] > longestLen then
  1135.             longestLen = #std.channelNames[a]
  1136.         end
  1137.     end
  1138.     longestLen = longestLen + 4
  1139.     for a = 1, #std.channelNames do
  1140.         term.setBackgroundColor(palate.menubar.channelmenu.bg)
  1141.         term.setCursorPos(1,a+1)
  1142.         clearMostline(longestLen+2)
  1143.         if a == cursor then
  1144.             term.setTextColor(palate.menubar.channelmenu.cursortxt)
  1145.             term.setBackgroundColor(palate.menubar.channelmenu.cursorbg)
  1146.             write(">")
  1147.         else
  1148.             write(" ")
  1149.         end
  1150.         term.setTextColor(palate.menubar.channelmenu.orbtxt)
  1151.         term.setBackgroundColor(palate.menubar.channelmenu.bg)
  1152.         if std.channel == std.channelNames[a] then
  1153.             write("@ ")
  1154.         else
  1155.             write("O ")
  1156.         end
  1157.         term.write(" "..std.channelNames[a])
  1158.         if term.isColor() then
  1159.             term.setBackgroundColor(palate.menubar.channelmenu.borderbg)
  1160.         else
  1161.             term.setBackgroundColor(colors.black)
  1162.         end
  1163.         term.setCursorPos(longestLen+2,a+1)
  1164.         term.write(" ")
  1165.         table.insert(yposes,{a+1,std.channelNames[a],std.channelURLs[std.channelNames[a]]})
  1166.     end
  1167.     term.setCursorPos(1,#std.channelNames+2)
  1168.     term.write((" "):rep(longestLen+2))
  1169.     return yposes,longestLen+2
  1170. end
  1171.  
  1172. local tArg = {...}
  1173.  
  1174. if tArg[1] == "help" then
  1175.     return displayHelp(true)
  1176. elseif tArg[1] == "upgrade" then
  1177.     local updateURL = isBeta and "http://pastebin.com/raw/uMZ23APu" or "http://pastebin.com/raw/P9dDhQ2m"
  1178.     local res, outcome = getFile(shell.getRunningProgram(),updateURL)
  1179.     if not res then
  1180.         error(outcome)
  1181.     else
  1182.         print("Updated STD-GUI to latest "..(isBeta and "beta." or "stable.").." ("..outcome.." bytes)")
  1183.         return
  1184.     end
  1185. end
  1186.  
  1187. local res, outcome
  1188. if tArg[1] == "update" then
  1189.     res, outcome = std.getSTDList(std.prevChannel)
  1190.     print(outcome)
  1191.     return
  1192. else
  1193.     pleaseWait() --he said please
  1194.     res, outcome = std.getSTDList(std.prevChannel)
  1195. end
  1196.  
  1197.  
  1198. local cleanExit = function()
  1199.     term.setTextColor(colors.white)
  1200.     term.setBackgroundColor(colors.black)
  1201.     term.clear()
  1202.     local out
  1203.     if pocket then
  1204.         out = "Thanks for using STD!"
  1205.     else
  1206.         out = "Thank you for using STD-GUI!"
  1207.     end
  1208.     if isSimSoft or isAxiom then
  1209.         term.setCursorBlink(false)
  1210.     end
  1211.     cprint(out,scr_y/2)
  1212.     term.setCursorPos(1,scr_y)
  1213.     sleep(0)
  1214.     return true, "This shouldn't be an error."
  1215. end
  1216. local STDdownloadPrompt = function(item)
  1217.     term.setCursorPos(1,scr_y)
  1218.     for k,v in pairs(std.storeURLs) do
  1219.         if item.url == v.url then
  1220.             itname = k
  1221.             break
  1222.         end
  1223.     end
  1224.     local savepath
  1225.     if isAxiom then
  1226.         if std.storeURLs[itname].catagory == 8 then --if an API
  1227.             savepath = fs.combine("/home/APIs",itname)
  1228.         else
  1229.             savepath = fs.combine("/Axiom/programs",itname)
  1230.         end
  1231.     else
  1232.         bow()
  1233.         term.clearLine()
  1234.         write("Save as: ")
  1235.         savepath = funcread(nil,{},nil,true)
  1236.         term.setCursorBlink(false)
  1237.     end
  1238.     if savepath:gsub(" ","") == "" then
  1239.         sleep(0)
  1240.         return
  1241.     else
  1242.         if fs.exists(savepath) then
  1243.             term.setCursorPos(1,scr_y)
  1244.             term.clearLine()
  1245.             write("Overwrite? (Y/N)")
  1246.             local key
  1247.             repeat
  1248.                 _,key = os.pullEvent("char")
  1249.             until string.find("yn",key)
  1250.             if key == "n" then
  1251.                 sleep(0)
  1252.                 return
  1253.             end
  1254.         end
  1255.         if relativePath then
  1256.             savepath = fs.combine(shell.dir(),savepath)
  1257.         end
  1258.         term.setCursorPos(1,scr_y)
  1259.         term.clearLine()
  1260.         term.write("Downloading...")
  1261.         local res, outcome = getFile(savepath,item.url)
  1262.         term.setCursorPos(1,scr_y)
  1263.         term.clearLine()
  1264.         if not res then
  1265.             term.write(outcome)
  1266.             sleep(0.6)
  1267.         else
  1268.             if isAxiom then
  1269.                 if std.storeURLs[itname].catagory ~= 8 then --no need for an icon for an api, wouldn't you say
  1270.                     local file = fs.open(fs.combine("home/Desktop",itname)..".lnk", "w")
  1271.                     file.write(savepath)
  1272.                     file.close()
  1273.                 end
  1274.             end
  1275.             term.write("Downloaded! ("..outcome.." bytes)")
  1276.             sleep(0.7)
  1277.         end
  1278.     end
  1279.     return
  1280. end
  1281.  
  1282. SimSoftDownloadPrompt = function(object)
  1283.     local itname
  1284.     for k,v in pairs(std.storeURLs) do
  1285.         if object.url == v.url then
  1286.             itname = k
  1287.             break
  1288.         end
  1289.     end
  1290.     term.setCursorPos(1,scr_y)
  1291.     bow()
  1292.     term.clearLine()
  1293.     write("Label?:")
  1294.     local custLabel = funcread(_,_,_,true)
  1295.     if #custLabel:gsub("%s","") == 0 then
  1296.         custLabel = nil
  1297.     else
  1298.         custLabel = custLabel:sub(1,9)
  1299.     end
  1300.     term.setCursorPos(1,scr_y)
  1301.     term.clearLine()
  1302.     term.write("Downloading...")
  1303.     local res, outcome = simSoftInstall(object,itname or object.title:gsub(" ","-"),custLabel)
  1304.     term.setCursorPos(1,scr_y)
  1305.     term.clearLine()
  1306.     term.write(outcome)
  1307.     sleep(#outcome/13)
  1308. end
  1309.  
  1310. local doCategoryMenu = function()
  1311.     local mcursor = catag --(not term.isColor()) and (catag or 0) or false
  1312.     local cats,longth = renderCatagoryMenu(true,mcursor)
  1313.     local evt,butt,x,y
  1314.     while true do
  1315.         local evt,butt,x,y = os.pullEvent()
  1316.         if evt == "mouse_click" or (evt == "mouse_up" and y ~= 1) then
  1317.             doRedraw = true
  1318.             if y == 1 then
  1319.                 catag = 0
  1320.                 break
  1321.             else
  1322.                 for a = 1, #cats do
  1323.                     if cats[a] == y and x <= longth then
  1324.                         catag = a
  1325.                         scroll = 1
  1326.                     end
  1327.                 end
  1328.                 break
  1329.             end
  1330.         elseif evt == "key" then
  1331.             if butt == keys.f1 then
  1332.                 break
  1333.             elseif mcursor then
  1334.                 if (butt == keys.up) and (mcursor > 0) then
  1335.                     mcursor = mcursor - 1
  1336.                     doRedraw = true
  1337.                 elseif (butt == keys.down) and (mcursor < #std.storeCatagoryNames) then
  1338.                     mcursor = mcursor + 1
  1339.                     doRedraw = true
  1340.                 elseif (butt == keys.enter) or (butt == keys.space) then
  1341.                     os.queueEvent("mouse_click",1,2,mcursor+1)
  1342.                 end
  1343.             end
  1344.         end
  1345.         if doRedraw then
  1346.             renderCatagoryMenu(true,mcursor)
  1347.             doRedraw = false
  1348.         end
  1349.     end
  1350.     maxScroll = setMaxScroll(catag)
  1351. end
  1352.  
  1353. local doChannelMenu = function()
  1354.     local mcursor = 1 --(not term.isColor()) and 1 or false
  1355.     local yposes, longth = renderChannelMenu(mcursor)
  1356.     local evt,butt,x,y
  1357.     while true do
  1358.         local evt,butt,x,y = os.pullEvent()
  1359.         if evt == "mouse_click" or (evt == "mouse_up" and y ~= 1) then
  1360.             if y == 1 then break else
  1361.                 for a = 1, #yposes do
  1362.                     if (yposes[a][1] == y) and (x <= longth) then
  1363.                             if std.channel ~= yposes[a][2] then
  1364.                             std.prevChannel = std.channel
  1365.                             std.channel = yposes[a][2]
  1366.                             scroll = 1
  1367.                             std.getSTDList(std.prevChannel)
  1368.                         end
  1369.                         break
  1370.                     end
  1371.                 end
  1372.                 break
  1373.             end
  1374.         elseif evt == "key" then
  1375.             if butt == keys.f3 then
  1376.                 break
  1377.             elseif mcursor then
  1378.                 if (butt == keys.up) and (mcursor > 1) then
  1379.                     mcursor = mcursor - 1
  1380.                 elseif (butt == keys.down) and (mcursor < #std.channelNames) then
  1381.                     mcursor = mcursor + 1
  1382.                 elseif (butt == keys.enter) or (butt == keys.space) then
  1383.                     os.queueEvent("mouse_click",1,2,mcursor+1)
  1384.                 end
  1385.             end
  1386.         end
  1387.         renderChannelMenu(mcursor)
  1388.     end
  1389.     maxScroll = setMaxScroll(catag)
  1390. end
  1391.  
  1392. local STDViewEntry = function(url)
  1393.     local contents, outcome = contentsFile(url)
  1394.     if not contents then
  1395.         term.write(outcome)
  1396.         sleep(0.6)
  1397.         return
  1398.     else
  1399.         strless(contents,palate.item.previewtxt,palate.item.previewbg)
  1400.     end
  1401. end
  1402.  
  1403. local doEverything = function() --do I have to do EVERYTHING?
  1404.     if fs.exists(std.stdList) then
  1405.         shell.run(std.stdList)
  1406.     else
  1407.         if not std.storeURLs then
  1408.             pleaseWait()
  1409.             std.getSTDList(std.prevChannel)
  1410.         end
  1411.     end
  1412.     maxScroll = setMaxScroll(catag)
  1413.     local yposes
  1414.     while true do
  1415.         if scroll > maxScroll then
  1416.             scroll = maxScroll
  1417.         end
  1418.         if scroll < 1 then
  1419.             scroll = 1
  1420.         end
  1421.         if (scroll-1 % 4 ~= 0) and (not term.isColor()) then
  1422.             scroll = scroll - ((scroll-1) % 4)
  1423.         end
  1424.         local mcursor = (not term.isColor()) and 1 or false
  1425.         yposes = renderStore(std.storeURLs,catag,scroll,scrollX,fixDotY,not term.isColor())
  1426.         renderCatagoryMenu(false,mcursor)
  1427.         local evt = {getEvents("mouse_scroll","mouse_click","mouse_up","key","mouse_drag","char")}
  1428.         scr_x, scr_y = term.getSize()
  1429.         if evt[1] == "mouse_scroll" then
  1430.             if scroll+evt[2] >= 1 and scroll+evt[2] <= maxScroll then
  1431.                 scroll = scroll+evt[2]
  1432.                 doRedraw = true
  1433.             end
  1434.         elseif evt[1] == "mouse_click" and (evt[2] == 1) and (evt[4] <= scr_y) and (evt[4] >= 1) then --left click only! must deport right mouse buttons!
  1435.             if evt[3] == scr_x and evt[4] == math.floor(dotY) then
  1436.                 doScrollBar = true
  1437.             end
  1438.             if evt[4] == 1 then
  1439.                 if evt[3] >= scr_x-4 then
  1440.                     return cleanExit()
  1441.                 else
  1442.                     if evt[3] >= 1 and evt[3] <= 6 then
  1443.                         doCategoryMenu()
  1444.                     elseif evt[3] >= 8 and evt[3] <= 14 then
  1445.                         doChannelMenu()
  1446.                     end
  1447.                 end
  1448.             elseif yposes[evt[4]-1] and evt[3] ~= scr_x then
  1449.                 local y = evt[4]-1
  1450.                 local showPostURL = false
  1451.                 local guud = yposes[y].title
  1452.                 scrollX = 1
  1453.                 while true do
  1454.                     if not guud then break end
  1455.                     local event,butt,cx,cy = renderStoreItem(yposes[y],showPostURL)
  1456.                     if event == "key" then
  1457.                         if butt == keys.q then
  1458.                             sleep(0)
  1459.                             break
  1460.                         elseif butt == keys.d then --hehe
  1461.                             sleep(0)
  1462.                             STDdownloadPrompt(yposes[y])
  1463.                             --break
  1464.                         elseif butt == keys.v then
  1465.                             sleep(0)
  1466.                             STDViewEntry(yposes[y].url)
  1467.                             --break
  1468.                         elseif (butt == keys.i) then
  1469.                             sleep(0)
  1470.                             if isSimSoft then
  1471.                                 SimSoftDownloadPrompt(yposes[y])
  1472.                             elseif isAxiom then
  1473.                                 STDdownloadPrompt(yposes[y]) --axiom only changes the
  1474.                             end
  1475.                             --break
  1476.                         end
  1477.                     elseif event == "mouse_click" then
  1478.                         if cy == scr_y then
  1479.                             if (cx < scr_x-7) or (cx > scr_x) then
  1480.                                 if cx >= scr_x-11 and cx < scr_x-8 then
  1481.                                     term.setCursorPos(1,scr_y)
  1482.                                     bow()
  1483.                                     term.clearLine()
  1484.                                     if pocket or turtle then
  1485.                                         write("Args.: ")
  1486.                                     else
  1487.                                         write("Arguments:")
  1488.                                     end
  1489.                                     local arguments = explode(" ",funcread(nil,{},nil,true)) or {}
  1490.                                     term.setTextColor(colors.white)
  1491.                                     term.setBackgroundColor(colors.black)
  1492.                                     term.clear()
  1493.                                     term.setCursorPos(1,1)
  1494.                                     if #arguments == 0 then
  1495.                                         runURL(yposes[y].url)
  1496.                                     else
  1497.                                         runURL(yposes[y].url,unpack(arguments))
  1498.                                     end
  1499.                                     sleep(0)
  1500.                                     write("[press a key]")
  1501.                                     os.pullEvent("key")
  1502.                                 elseif cx >= scr_x-16 and cx < scr_x-12 then
  1503.                                     STDViewEntry(yposes[y].url)
  1504.                                 end
  1505.                                 sleep(0)
  1506.                                 break
  1507.                             else
  1508.                                 term.setCursorPos(1,scr_y)
  1509.                                 bow()
  1510.                                 term.clearLine()
  1511.                                 if isSimSoft then
  1512.                                     SimSoftDownloadPrompt(yposes[y])
  1513.                                     break
  1514.                                 else
  1515.                                     STDdownloadPrompt(yposes[y])
  1516.                                     break
  1517.                                 end
  1518.                             end
  1519.                         end
  1520.                     end
  1521.                 end
  1522.             end
  1523.         elseif evt[1] == "mouse_up" then
  1524.             doScrollBar = false
  1525.             fixDotY = nil
  1526.         elseif evt[1] == "mouse_drag" then
  1527.             if doScrollBar then
  1528.                 local my = evt[4]
  1529.                 if my > scr_y then --operating systems might allow this to be true
  1530.                     my = scr_y
  1531.                 elseif my < 1 then --this too
  1532.                     my = 1
  1533.                 end
  1534.                 if my > 1 then
  1535.                     scroll = math.floor( (my-2)/(scr_y-2) * (maxScroll)) + 1
  1536.                     fixDotY = my
  1537.                 end
  1538.             end
  1539.         elseif evt[1] == "key" then
  1540.             if evt[2] == keys.q then
  1541.                 return cleanExit()
  1542.             elseif evt[2] == keys.down then
  1543.                 scroll = scroll + 4
  1544.             elseif evt[2] == keys.up then
  1545.                 scroll = scroll - 4
  1546.             elseif evt[2] == keys.pageDown then
  1547.                 scroll = scroll + (scr_y-1)
  1548.             elseif evt[2] == keys.pageUp then
  1549.                 scroll = scroll - (scr_y-1)
  1550.             elseif evt[2] == keys.home then
  1551.                 scroll = 1
  1552.             elseif evt[2] == keys['end'] then
  1553.                 scroll = maxScroll
  1554.             elseif evt[2] == keys.h then --help screen!
  1555.                 displayHelp(false)
  1556.             elseif evt[2] == keys.right then
  1557.                 scrollX = scrollX + 1
  1558.             elseif evt[2] == keys.left then
  1559.                 if scrollX > 1 then
  1560.                     scrollX = scrollX - 1
  1561.                 end
  1562.             elseif (evt[2] == keys.numPadAdd) or (evt[2] == keys.rightBracket) then
  1563.                 catag = catag + 1
  1564.                 if catag > #std.storeCatagoryNames then
  1565.                     catag = 0
  1566.                 end
  1567.                 scroll = 1
  1568.                 maxScroll = setMaxScroll(catag)
  1569.             elseif (evt[2] == keys.minus) or (evt[2] == keys.leftBracket) then
  1570.                 catag = catag - 1
  1571.                 if catag < 0 then
  1572.                     catag = #std.storeCatagoryNames
  1573.                 end
  1574.                 scroll = 1
  1575.                 maxScroll = setMaxScroll(catag)
  1576.             elseif evt[2] == keys.f5 then
  1577.                 pleaseWait()
  1578.                 std.getSTDList(std.prevChannel)
  1579.             elseif (evt[2] == keys.f12) and (not isSimSoft) then
  1580.                 local updateURL = isBeta and "http://pastebin.com/raw/uMZ23APu" or "http://pastebin.com/raw/P9dDhQ2m"
  1581.                 getFile(shell.getRunningProgram(),updateURL)
  1582.                 local flashes = {
  1583.                     colors.black,
  1584.                     colors.white,
  1585.                     colors.lightGray,
  1586.                     colors.gray,
  1587.                     colors.black,
  1588.                 }
  1589.                 for a = 1, #flashes do
  1590.                     term.setBackgroundColor(flashes[a])
  1591.                     term.clear()
  1592.                     sleep(0)
  1593.                 end
  1594.                 return
  1595.             elseif evt[2] == keys.f1 then
  1596.                 doCategoryMenu()
  1597.             elseif evt[2] == keys.f or evt[2] == keys.f6 then
  1598.                 findPrompt()
  1599.             elseif evt[2] == keys.f3 then
  1600.                 doChannelMenu()
  1601.             end
  1602.         elseif evt[1] == "char" then
  1603.             if tonumber(evt[2]) then
  1604.                 local a = tonumber(evt[2]) ~= "0" and tonumber(evt[2]) or "10"
  1605.                 local b = (a*4)-1
  1606.                 os.queueEvent("mouse_click",1,scr_x-3,b)
  1607.             end
  1608.         end
  1609.     end
  1610. end
  1611.  
  1612. if doDisplayTitle then
  1613.     displayTitle()
  1614. end
  1615.  
  1616. if std.storeURLs then std.storeURLs = getFindList("") end
  1617.  
  1618. local errorHandler = function()
  1619.     local success, message = pcall(doEverything)
  1620.     if success then
  1621.         return true
  1622.     end
  1623.     if message == "Terminated" then
  1624.         term.setBackgroundColor(colors.black)
  1625.         term.scroll(2)
  1626.         term.setCursorPos(1, scr_y-1)
  1627.         printError(message)
  1628.         return false, message
  1629.     else
  1630.         term.setBackgroundColor(colors.white)
  1631.         for a = 1, math.ceil(scr_y/2) do
  1632.             term.scroll(2)
  1633.         end
  1634.         term.setTextColor(colors.black)
  1635.         cprint("STD-GUI has encountered an error!",2)
  1636.         term.setCursorPos(1,4)
  1637.         term.setTextColor(term.isColor() and colors.red or colors.gray)
  1638.         print(message or "".."\n")
  1639.         term.setTextColor(colors.black)
  1640.         print(" Please contact LDDestroier/EldidiStroyrr on either the ComputerCraft forums, or through other means.")
  1641.         sleep(0.5)
  1642.         print("\nPush a key.")
  1643.         os.pullEvent("key")
  1644.         term.setCursorPos(1,scr_y)
  1645.         term.setBackgroundColor(colors.black)
  1646.         term.setTextColor(colors.white)
  1647.         term.clearLine()
  1648.         return false, message
  1649.     end
  1650. end
  1651.  
  1652. return errorHandler()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement