Advertisement
krzys_h

"guihelp" - GUI Help Viewer - v0.1

Jan 2nd, 2015
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 19.56 KB | None | 0 0
  1. local startupPage, mode = ...
  2.  
  3. if not term.isColor() then
  4.   print("WARNING: This program has been designed to run on Advanced Computer")
  5.   print("It should run fine, but you won't be able to follow links or click buttons")
  6.   print("To access button functions, use the following keys:")
  7.   print("Quit - Q, Home - 0 or H, Reload - 5, F5 or R, Back - 4 or Backspace, Next - 6")
  8.   print("Press any key to continue")
  9.   os.pullEvent("key")
  10. end
  11.  
  12. local title = "ERROR"
  13. local text = "ERROR: NO PAGE LOADED"
  14. local pos = 1
  15. local textLength = 1
  16. local lowercase = false
  17.  
  18. local offlineMode = false
  19. if not http then offlineMode = true end
  20. if mode then
  21.   if mode == "online" then
  22.     if offlineMode then
  23.       error("HTTP API not available", 0)
  24.     end
  25.     offlineMode = false
  26.   elseif mode == "offline" then
  27.     offlineMode = true
  28.   else
  29.     error("Unkown mode, use \"offline\" or \"online\"", 0)
  30.   end
  31. end
  32.  
  33. function error404()
  34.   title = "404 ERROR"
  35.   text = "\\v;Not Found!\\r;"
  36. end
  37.  
  38. function loadOfflinePage(page)
  39.   title = page
  40.  
  41.   if page == "index" then
  42.     text = "Help topics available:\n"
  43.     for i, topic in pairs(help.topics()) do
  44.       text = text .. "\\l"..topic..";"..topic.."\\r;\n"
  45.     end
  46.   else
  47.     local filename = help.lookup(page)
  48.     if filename == nil then
  49.       return error404()
  50.     end
  51.    
  52.     local file = fs.open(filename, "r")
  53.     text = file.readAll()
  54.     file.close()
  55.   end
  56.  
  57.   if page == "apis" then
  58.     -- This is code fragment from "apis" program
  59.     local tApis = {}
  60.     for k,v in pairs( _G ) do
  61.       if type(k) == "string" and type(v) == "table" and k ~= "_G" then
  62.         table.insert( tApis, k )
  63.       end
  64.     end
  65.     table.insert( tApis, "shell" )
  66.     table.sort( tApis )
  67.    
  68.     text = text .. "\n\nList of available APIs:\n"
  69.     for k,v in pairs(tApis) do
  70.       local tag = "\\x"
  71.       if help.lookup(v) then
  72.         tag = "\\l"..v..";"
  73.       end
  74.       text = text .. tag .. v .. "\\r;\n"
  75.     end
  76.   end
  77.  
  78.   if page == "programs" then
  79.     local programs = shell.programs()
  80.     text = text .. "\n\nList of available programs:\n"
  81.     for k,v in pairs(programs) do
  82.       local tag = "\\x;"
  83.       if help.lookup(v) then
  84.         tag = "\\l"..v..";"
  85.       end
  86.       text = text .. tag .. v .. "\\r;\n"
  87.     end
  88.   end
  89.  
  90.   function detect_links(s)
  91.     if s:sub(1,5) == "help " then
  92.       local target = s:sub(6)
  93.       if target == "<program>" then target = "programs" end
  94.       if target == "index" or help.lookup(target) ~= nil then
  95.         return "\"\\l"..target..";"..s.."\\r;\""
  96.       end
  97.     elseif s == "programs" or s == "apis" then
  98.       return "\"\\l"..s..";"..s.."\\r;\""
  99.     end
  100.     return "\"\\x;"..s.."\\r;\""
  101.   end
  102.  
  103.   text = string.gsub(text, "\"(.-)\"", detect_links)
  104.   text = string.gsub(text, "https?://[a-zA-Z0-9./-]*", "\\u;%1\\r;")
  105.   text = string.gsub(text, "Ctrl%+(.)", "\\v;Ctrl+%1\\r;")
  106. end
  107.  
  108. function loadOnlinePage(page)
  109.   if page == "Main Page" or page == "Main_Page" then
  110.     -- There is just too much HTML in there
  111.     title = "Main Page"
  112.     text = "   \\h; Welcome to the ComputerCraft Wiki! \\r;\n\n"
  113.     test = text.."\\s;Wiki Contents\\r;\n"
  114.     text = text.."\\lTutorials;Tutorial List\\r;\n"
  115.     text = text.."\\lCategory:Programs;Program List\\r;\n"
  116.     text = text.."\\lCategory:APIs;API List\\r;\n"
  117.     --text = text.."\\lRecipes;Recipe List\\r;\n" --TODO: We'll handle images somehow
  118.     text = text.."\\lCategory:Peripherals;Peripherals & Addons\\r;\n"
  119.     text = text.."\\lCategory:Notable Programs;Notable Programs\\r;\n"
  120.     text = text.."\\lCategory:OSes;Operating Systems\\r;\n"
  121.     text = text.."\\lChangelog;ComuterCraft Changelog\\r;\n"
  122.     --text = text.."\\lWiki Todo;Wiki Todo\\r;\n" -- I don't think we need that
  123.     return
  124.   end
  125.  
  126.   local h = http.get("http://computercraft.info/wiki/api.php?format=xml&action=query&prop=revisions&titles="..textutils.urlEncode(page).."&rvprop=content", {["User-Agent"] = "GUI Help Viewer by krzys_h"})
  127.   if not h then
  128.     title = "ERROR"
  129.     text = "\\v;CONNECTION ERROR!\\r;\nMake sure you have internet connection and computercraft.info website is working"
  130.     return
  131.   end
  132.   if h.getResponseCode() ~= 200 then
  133.     title = h.getResponseCode().." ERROR"
  134.     text = "\\v;SERVER RETURNED ERROR "..h.getResponseCode().."\\r;"
  135.     h.close()
  136.     return
  137.   end
  138.  
  139.   local data = h.readAll()
  140.   h.close()
  141.  
  142.   title = string.match(data, "title=\"(.-)\"")
  143.   if title == nil then
  144.     title = page
  145.   end
  146.  
  147.   text = string.match(data, "<rev xml:space=\"preserve\">(.-)</rev>")
  148.   if text == nil then
  149.     return error404()
  150.   end
  151.  
  152.   if text:sub(1, 10) == "#REDIRECT " then
  153.     loadOnlinePage(text:sub(13, -3))
  154.     return
  155.   end
  156.  
  157.   text = string.gsub(text, "&lt;", "<")
  158.   text = string.gsub(text, "&gt;", ">")
  159.   text = string.gsub(text, "&quot;", "\"")
  160.   text = string.gsub(text, "<!--(.-)-->", "")
  161.  
  162.   -- Computer terminal doesn't like special chars
  163.   text = string.gsub(text, "’", "'")
  164.   text = string.gsub(text, "—", "-")
  165.  
  166.   text = string.gsub(text, "<table.*>", "")
  167.   text = string.gsub(text, "</table>", "")
  168.   text = string.gsub(text, "<tr.->", "")
  169.   text = string.gsub(text, "</tr>", "")
  170.   text = string.gsub(text, "<td.->", "")
  171.   text = string.gsub(text, "</td>", "")
  172.  
  173.   text = string.gsub(text, "__TOC__", "") --TODO: We could implement TOC...
  174.   text = string.gsub(text, "__NOTOC__", "")
  175.  
  176.   function lowercase_match(s)
  177.     lowercase = true
  178.     return ""
  179.   end
  180.   text = string.gsub(text, "{{lowercase}}", lowercase_match)
  181.   text = string.gsub(text, "{{Lowercase}}", lowercase_match)
  182.  
  183.   text = string.gsub(text, "'''(.-)'''", "%1")
  184.   text = string.gsub(text, "''(.-)''", "%1")
  185.   text = string.gsub(text, "'(.-)'", "%1")
  186.  
  187.   text = string.gsub(text, "{{type|(.-)}}", "\\t;%1\\r;")
  188.   text = string.gsub(text, "{{Type|(.-)}}", "\\t;%1\\r;")
  189.   text = string.gsub(text, "<var>(.-)</var>", "\\v;%1\\r;")
  190.   text = string.gsub(text, "<code>(.-)</code>", "\\x;%1\\r;") --TODO: syntax highlighting?
  191.   text = string.gsub(text, "<nowiki/>", "")
  192.   text = string.gsub(text, "<em>(.-)</em>", "%1")
  193.   text = string.gsub(text, "<br />", "\n")
  194.   text = string.gsub(text, "<br/>", "\n")
  195.   text = string.gsub(text, "<pre>(.-)</pre>", "\\x;%1\\r;")
  196.   text = string.gsub(text, "<tt>(.-)</tt>", "\\x;%1\\r;")
  197.  
  198.   text = string.gsub(text, "<div(.+)>(.-)</div>", "%2")
  199.  
  200.   function link_replace(link)
  201.     local linktarget = link
  202.     local linkname = link
  203.     local splitpos = link:find("|")
  204.     if splitpos then
  205.       linktarget = link:sub(1, splitpos-1)
  206.       linkname = link:sub(splitpos+1)
  207.     end
  208.     if linktarget:sub(1, 1) == ":" then
  209.       linktarget = linktarget:sub(2)
  210.     end
  211.     if linktarget:sub(1, 5) == "File:" then return "" end
  212.     if linktarget:sub(1, 6) == "Image:" then return "" end
  213.     return "\\l"..linktarget..";"..linkname.."\\r;"
  214.   end
  215.  
  216.   text = string.gsub(text, "%[%[Category:(.-)%]%]", "") --TODO: category display?
  217.   text = string.gsub(text, "%[%[(.-)%]%]", link_replace)
  218.   text = string.gsub(text, "%[(.-) (.-)%]", "\\u;%2 (%1)\\r;")
  219.   text = string.gsub(text, "%[(.-)%]", "\\u;%1\\r;")
  220.  
  221.   text = parseTemplates(text)
  222.  
  223.   text = string.gsub(text, "\n===(.-)===\n", "\n  \\s;%1\\r;\n")
  224.   text = string.gsub(text, "\n==(.-)==\n", "\n   \\h;%1\\r;\n")
  225.   text = string.gsub(text, "\n=(.-)=\n", "\n    \\c;%1\\r;\n")
  226.  
  227.   if title:sub(1, 9) == "Category:" then
  228.     local h = http.get("http://computercraft.info/wiki/api.php?format=xml&action=query&list=categorymembers&cmtitle="..textutils.urlEncode(page).."&cmlimit=500", {["User-Agent"] = "GUI Help Viewer by krzys_h"})
  229.     if not h then
  230.       title = "ERROR"
  231.       text = "\\v;CONNECTION ERROR!\\r;\nMake sure you have internet connection and computercraft.info website is working"
  232.       return
  233.     end
  234.     if h.getResponseCode() ~= 200 then
  235.       title = h.getResponseCode().." ERROR"
  236.       text = "\\v;SERVER RETURNED ERROR "..h.getResponseCode().."\\r;"
  237.       h.close()
  238.       return
  239.     end
  240.    
  241.     local data = h.readAll()
  242.     h.close()
  243.    
  244.     text = text .. "\n  \\h; Pages in this category: \\r;\n"
  245.     for page in string.gmatch(data, "title=\"(.-)\"") do
  246.       text = text .. "\\l" .. page .. ";" .. page .. "\\r;\n"
  247.     end
  248.   end
  249. end
  250.  
  251. function closest(...)
  252.   local x = {...}
  253.   local r
  254.   for i, d in pairs(x) do
  255.     if x[i] then
  256.       if not r or x[i] < r then
  257.         r = x[i]
  258.       end
  259.     end
  260.   end
  261.   return r
  262. end
  263.  
  264. -- http://lua-users.org/wiki/StringTrim
  265. function trim(s)
  266.   return (s:gsub("^%s*(.-)%s*$", "%1"))
  267. end
  268.  
  269. function findParam(params, name)
  270.   for id, data in pairs(params) do
  271.     local x = string.find(data, "=")
  272.     if x ~= nil then
  273.       thisname = trim(string.sub(data, 1, x-1))
  274.       if thisname == name then
  275.         return string.sub(data, x+1)
  276.       end
  277.     end
  278.   end
  279.   if type(name) == "number" then
  280.     return params[name]
  281.   end
  282.   return nil
  283. end
  284.  
  285. function expandTemplate(name, params)
  286.   if name == "API table" then
  287.     return " \\a;  "..findParam(params, 1).." (API)  \\r;\n"..string.sub(findParam(params, 3), 3)
  288.   end
  289.   if name == "API table/row" then
  290.     return findParam(params, 1).." \\z;--\\r; "..findParam(params, 2).." \\z;--\\r; "..findParam(params, 3).."\n"
  291.   end
  292.   if name == "Deprecated" then
  293.     return "\\x;These functions have been removed from ComputerCraft\\r;"
  294.   end
  295.   if name == "Stub" then
  296.     return "\\x;This article is a stub\\r;\n"
  297.   end
  298.   if name == "ToDelete" then
  299.     return "\\x;This page is marked for deletion!\\r;\n"
  300.   end
  301.   if name == "Example" then
  302.     local s = " \\s;Example\\r;\n"..findParam(params, "desc").."\n\n\\x;"..findParam(params, "code").."\\r;\n"
  303.     if findParam(params, "output") then
  304.       s = s .. "\nOutput:\n\\x;"..findParam(params, "output").."\\r;\n"
  305.     end
  306.     return s
  307.   end
  308.   if name == "Event" then
  309.     local s = " \\a;  Event "..findParam(params, "name").."  \\r;\n"
  310.     s = s .. findParam(params, "desc") .. "\n"
  311.     for i=1,5 do
  312.       if findParam(params, "return"..tostring(i)) then
  313.         s = s .. "\\x;Return "..tostring(i)..":\\r; " .. findParam(params, "return"..tostring(i)) .. "\n"
  314.       end
  315.     end
  316.     if findParam(params, "examples") then
  317.       s = s .. "\n" .. findParam(params, "examples")
  318.     end
  319.     return s
  320.   end
  321.   if name == "Function" then
  322.     s = " \\a;  Function "..findParam(params, "name").."  \\r;\n"
  323.     s = s .. findParam(params, "desc") .. "\n"
  324.     if findParam(params, "args") then
  325.       s = s .. "\\x;Syntax:\\r; "..findParam(params, "name").."("..findParam(params, "args")..")\n"
  326.     else
  327.       s = s .. "\\x;Syntax:\\r; "..findParam(params, "name").."()\n"
  328.     end
  329.     if findParam(params, "returns") then
  330.       s = s .. "\\x;Returns:\\r; "..findParam(params, "returns").."\n"
  331.     else
  332.       s = s .. "\\x;Returns:\\r; \\t;nil\\r;\n"
  333.     end
  334.     if findParam(params, "examples") then
  335.       s = s .. "\n" .. findParam(params, "examples")
  336.     end
  337.     return s
  338.   end
  339.   return "\\v;UNKNOWN TEMPLATE: "..name.."\\r;"
  340. end
  341.  
  342. function parseTemplate(s, p)
  343.   local res = s
  344.   local params = {}
  345.   while true do
  346.     nextparam = string.find(res, "|", p)
  347.     subtemplate = string.find(res, "{{", p)
  348.     templateend = string.find(res, "}}", p)
  349.     local x = closest(nextparam, subtemplate, templateend)
  350.     if x == nil then
  351.       error("Unclosed template")
  352.     elseif x == templateend or x == nextparam then
  353.       param = trim(string.sub(res, p, x-1))
  354.       table.insert(params, param)
  355.       p = x+1
  356.       if x == templateend then
  357.         p = p + 1
  358.         break
  359.       end
  360.     elseif x == subtemplate then
  361.       pos_start = x-2
  362.       _, tpl, pos_end = parseTemplate(res, x+2)
  363.       res = string.sub(
  364.       res, 1, pos_start) .. tpl .. string.sub(res, pos_end+1)
  365.     end
  366.   end
  367.   local name = params[1]
  368.   table.remove(params, 1)
  369.   return res, expandTemplate(name, params), p
  370. end
  371.  
  372. function parseTemplates(s)
  373.   local p = 1
  374.   local out = ""
  375.   while p <= #s do
  376.     templatepos = string.find(s, "{{", p)
  377.     if templatepos == nil then
  378.       out = out .. string.sub(s, p)
  379.       break
  380.     else
  381.       out = out .. string.sub(s, p, templatepos-1)
  382.       p = templatepos+2
  383.       s, res, p = parseTemplate(s, p)
  384.       out = out .. res
  385.     end
  386.   end
  387.   return out
  388. end
  389.  
  390. local hist = {}
  391. local hist_pos = 0
  392. function loadPage(page, new_page)
  393.   if new_page == nil then new_page = true end
  394.   lowercase = false
  395.   if not offlineMode then
  396.     title = "<LOADING>"
  397.     text = "  \\t;Loading, please wait...\\r;"
  398.     pos = 1
  399.     generateWindows()
  400.     draw()
  401.    
  402.     loadOnlinePage(page)
  403.   else
  404.     loadOfflinePage(page)
  405.   end
  406.   if new_page then
  407.     while hist_pos < #hist do
  408.       table.remove(hist)
  409.     end
  410.     table.insert(hist, page)
  411.     hist_pos = #hist
  412.   end
  413.   pos = 1
  414.   if lowercase then
  415.     title = title:sub(1,1):lower()..title:sub(2)
  416.   end
  417. end
  418.  
  419. function history(amount)
  420.   local old_hist = hist_pos
  421.   hist_pos = hist_pos + amount
  422.   if hist_pos >= #hist then
  423.     hist_pos = #hist
  424.   end
  425.   if hist_pos <= 1 then
  426.     hist_pos = 1
  427.   end
  428.   if hist_pos ~= old_hist then
  429.     loadPage(hist[hist_pos], false)
  430.     generateWindows()
  431.   end
  432. end
  433.  
  434. function reload()
  435.   loadPage(hist[hist_pos], false)
  436.   generateWindows()
  437. end
  438.  
  439. local w, h = term.getSize()
  440. local header = window.create(term.current(), 1, 1, w, 2)
  441. local content = window.create(term.current(), 1, 3, w, 1000)
  442. local links = {}
  443. function generateWindows()
  444.   w, h = term.getSize()
  445.  
  446.   -- draw content
  447.   local old = term.current()
  448.   term.redirect(content)
  449.   term.clear()
  450.   term.setCursorPos(1, 1)
  451.   local p = 1
  452.   local linktarget, linkstartx, linkstarty, linkendx, linkendy
  453.   local inCode = false
  454.   links = {}
  455.   while p <= #text do
  456.     controlpos, controlend = string.find(text, "\\.-;", p)
  457.     if controlpos == nil then
  458.       write(string.sub(text, p))
  459.       break
  460.     else
  461.       write(string.sub(text, p, controlpos-1))
  462.       p = controlend + 1
  463.       c = string.sub(text, controlpos+1, controlpos+1)
  464.       if c == "l" and term.isColor() then -- l = link
  465.         linktarget = string.sub(text, controlpos+2, controlend-1)
  466.         linkstartx, linkstarty = term.getCursorPos()
  467.         term.setTextColor(colors.lightBlue)
  468.       end
  469.       if c == "r" then -- r = reset formatting
  470.         if linktarget then
  471.           linkendx, linkendy = term.getCursorPos()
  472.           table.insert(links, {startx = linkstartx, starty = linkstarty, endx = linkendx, endy = linkendy, target = linktarget})
  473.           linktarget = nil
  474.         end
  475.         inCode = false
  476.         term.setBackgroundColor(colors.black)
  477.         term.setTextColor(colors.white)
  478.       end
  479.       if c == "t" and term.isColor() then -- t = type
  480.         term.setTextColor(colors.lime)
  481.       end
  482.       if c == "c" and not inCode and term.isColor() then -- c = chapter header
  483.         --TODO: I don't really like that color...
  484.         term.setBackgroundColor(colors.yellow)
  485.         term.setTextColor(colors.black)
  486.       end
  487.       if c == "h" and not inCode and term.isColor() then -- h = header
  488.         term.setBackgroundColor(colors.blue)
  489.       end
  490.       if c == "s" and not inCode and term.isColor() then -- s = subheader
  491.         term.setBackgroundColor(colors.purple)
  492.       end
  493.       if c == "a" and not inCode and term.isColor() then -- a = api header
  494.         term.setBackgroundColor(colors.green)
  495.       end
  496.       if c == "z" and term.isColor() then -- z = table separator
  497.         term.setTextColor(colors.gray)
  498.       end
  499.       if c == "v" and term.isColor() then -- v = var
  500.         term.setTextColor(colors.red)
  501.       end
  502.       if c == "x" and term.isColor() then -- x = code / comment
  503.         term.setTextColor(colors.lightGray)
  504.         inCode = true
  505.       end
  506.       if c == "u" and term.isColor() then -- u = unclickable link (e.g. http)
  507.         term.setTextColor(colors.blue)
  508.       end
  509.     end
  510.   end
  511.   _, textLength = term.getCursorPos()
  512.   term.redirect(old)
  513.  
  514.   -- draw header
  515.   local old = term.current()
  516.   term.redirect(header)
  517.   term.setBackgroundColor(colors.black)
  518.   term.setTextColor(colors.white)
  519.   term.clear()
  520.   term.setCursorPos(1, 1)
  521.   if not term.isColor() then
  522.     term.setBackgroundColor(colors.white)
  523.     term.setTextColor(colors.black)
  524.   else
  525.     term.setBackgroundColor(colors.lightGray)
  526.     term.setTextColor(colors.red)
  527.   end
  528.   write("[X] ")
  529.   if term.isColor() then
  530.     term.setTextColor(colors.orange)
  531.   end
  532.   write("[H] ")
  533.   if term.isColor() then
  534.     term.setTextColor(colors.blue)
  535.   end
  536.   write("[<]")
  537.   if term.isColor() then
  538.     term.setTextColor(colors.lime)
  539.   end
  540.   write("[R]")
  541.   if term.isColor() then
  542.     term.setTextColor(colors.blue)
  543.   end
  544.   write("[>]")
  545.   if term.isColor() then
  546.     term.setTextColor(colors.black)
  547.   end
  548.   local t = "  "..title.." --- GUI Help Viewer"
  549.   if #t < w-17-11 then t = t .. " by krzys_h" end
  550.   for i=0,w-#t-17 do t = t.." " end
  551.   t = t:sub(1, w-17)
  552.   print(t)
  553.   term.redirect(old)
  554. end
  555.  
  556. function draw()
  557.   term.setBackgroundColor(colors.black)
  558.   term.setTextColor(colors.white)
  559.   term.clear()
  560.   term.setCursorPos(1, 1)
  561.  
  562.   content.reposition(1, 3-pos+1, w, 1000)
  563.   header.reposition(1, 1, w, 2)
  564. end
  565.  
  566. function move(x)
  567.   pos = pos + x
  568.   if pos > textLength-(h-3) then pos = textLength-(h-3) end
  569.   if pos < 1 then pos = 1 end
  570. end
  571.  
  572. function getLink(x, y)
  573.   for id, link in pairs(links) do
  574.     if (y > link.starty or (y == link.starty and x >= link.startx)) and (y < link.endy or (y == link.endy and x < link.endx)) then
  575.       return link
  576.     end
  577.   end
  578.   return nil
  579. end
  580.  
  581. function handleClick(x, y, button)
  582.   if y == 1 then
  583.     if x >= 1 and x <= 3 then
  584.       os.queueEvent("terminate")
  585.     end
  586.     if x >= 5 and x <= 7 then
  587.       loadPage(offlineMode and "intro" or "Main Page")
  588.       generateWindows()
  589.     end
  590.     if x >= 9 and x <= 11 then
  591.       history(-1)
  592.     end
  593.     if x >= 12 and x <= 14 then
  594.       reload()
  595.     end
  596.     if x >= 15 and x <= 17 then
  597.       history(1)
  598.     end
  599.   end
  600.  
  601.   local y = y - 2 + pos - 1
  602.   local link = getLink(x, y)
  603.   if link then
  604.     loadPage(link.target)
  605.     generateWindows()
  606.   end
  607. end
  608.  
  609. function handleScroll(scroll)
  610.   move(scroll)
  611. end
  612.  
  613. function handleKey(key)
  614.   if key == keys.down then
  615.     move(1)
  616.   end
  617.   if key == keys.up then
  618.     move(-1)
  619.   end
  620.   if key == keys.pageDown then -- TODO: doesn't work?
  621.     move(h-2)
  622.   end
  623.   if key == keys.pageUp then -- TODO: doesn't work?
  624.     move(-(h-2))
  625.   end
  626.   if key == keys.home then
  627.     pos = 1
  628.   end
  629.   if key == keys["end"] then -- Lua doesn't like keys.end
  630.     if textLength > (h-3) then
  631.       pos = textLength-(h-3)
  632.     else
  633.       pos = 1
  634.     end
  635.   end
  636.   if key == keys.q then
  637.     os.queueEvent("terminate")
  638.   end
  639.   if key == keys.backspace or key == keys.four or key == keys.numPad4 then
  640.     history(-1)
  641.   end
  642.   if key == keys.six or key == keys.numPad6 then
  643.     history(1)
  644.   end
  645.   if key == keys.f5 or key == keys.five or key == keys.numPad5 or key == keys.r then
  646.     reload()
  647.   end
  648.   if key == keys.zero or key == keys.numPad0 or key == keys.h then
  649.     loadPage(offlineMode and "intro" or "Main Page")
  650.     generateWindows()
  651.   end
  652. end
  653.  
  654. if not startupPage or startupPage == "-" then
  655.   if offlineMode then
  656.     startupPage = "intro"
  657.   else
  658.     startupPage = "Main Page"
  659.   end
  660. end
  661. loadPage(startupPage)
  662. generateWindows()
  663. while true do
  664.   draw()
  665.  
  666.   local event = {os.pullEventRaw()}
  667.   if event[1] == "mouse_click" then
  668.     handleClick(event[3], event[4], event[2])
  669.   end
  670.   if event[1] == "mouse_scroll" then
  671.     handleScroll(event[2])
  672.   end
  673.   if event[1] == "key" then
  674.     handleKey(event[2])
  675.   end
  676.   if event[1] == "term_resize" then
  677.     generateWindows()
  678.   end
  679.   if event[1] == "terminate" then
  680.     term.clear()
  681.     term.setCursorPos(1, 1)
  682.     break
  683.   end
  684. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement