Advertisement
D_Puppy

wm.lua

Jul 29th, 2017
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 36.46 KB | None | 0 0
  1. local component = require("component")
  2. local gpu = component.gpu
  3. local event = require("event")
  4. local unicode = require("unicode")
  5. local computer = require("computer")
  6.  
  7. -- libthread from Zer0Galaxy found on openprograms.ru
  8. local computer = require("computer")
  9. computer.SingleThread = computer.pullSignal
  10. --local thread = {}
  11.  
  12. local mainThread
  13. local timeouts
  14.  
  15. local function MultiThread( _timeout )
  16.   if coroutine.running()==mainThread then
  17.     local mintime = _timeout or math.huge
  18.     local co=next(timeouts)
  19.     while co do
  20.       if coroutine.status( co ) == "dead" then
  21.         timeouts[co],co=nil,next(timeouts,co)
  22.       else
  23.         if timeouts[co] < mintime then mintime=timeouts[co] end
  24.         co=next(timeouts,co)
  25.       end
  26.     end
  27.     if not next(timeouts) then
  28.       computer.pullSignal=computer.SingleThread
  29.       computer.pushSignal("AllThreadsDead")
  30.     end
  31.     local event={computer.SingleThread(mintime)}
  32.     local ok, param
  33.     for co in pairs(timeouts) do
  34.       ok, param = coroutine.resume( co, table.unpack(event) )
  35.       if not ok then timeouts={} error( param )
  36.       else timeouts[co] = param or math.huge end
  37.     end
  38.     return table.unpack(event)
  39.   else
  40.     return coroutine.yield( _timeout )
  41.   end
  42. end
  43.  
  44. function threadInit()
  45.   mainThread=coroutine.running()
  46.   timeouts={}
  47. end
  48.  
  49. function threadCreate(f,...)
  50.   computer.pullSignal=MultiThread
  51.   local co=coroutine.create(f)
  52.   timeouts[co]=math.huge
  53.   local ok, param = coroutine.resume( co, ... )
  54.   if not ok then timeouts={} error( param )
  55.   else timeouts[co] = param or math.huge end
  56.   return co
  57. end
  58.  
  59.  
  60.  
  61.  
  62. local wm = {}
  63.  
  64.  
  65. local versionMajor = 1
  66. local versionMinor = 2
  67. local versionState = "Release 1"
  68.  
  69.  
  70. local color={}
  71. color.black=0x000000
  72. color.gray=0xA9A9A9
  73. color.lightBlue=0x808080
  74. color.white=0xFFFFFF
  75. color.magenta=0xFF00FF
  76. color.yellow=0xFFFF00
  77. color.green=0x00FF00
  78. color.darkGreen=0x008000
  79. color.blue=0x0000ff
  80. color.red=0xFF0000
  81. color.orange=0xFFA500
  82. color.brown=0xA52A2A
  83. color.lightRed=0xF00000
  84. color.darkGray=0x202020
  85.  
  86. -- screen colors
  87. local Color = {}
  88. Color.ScreenBackground = color.lightBlue
  89. Color.ScreenForeground = color.white
  90. Color.TopLineBackground = color.darkGray
  91. Color.TopLineForeground = color.white
  92. Color.BottomLineBackground = color.darkGray
  93. Color.BottomLineForeground = color.white
  94. Color.BottomLineActive = color.red
  95. Color.TopLineActive = color.red
  96. Color.RunningDot = color.green
  97.  
  98. -- window colors
  99. Color.WindowBackground = color.gray
  100. Color.WindowForeground = color.black
  101. Color.WindowActiveFrameBackground = color.blue
  102. Color.WindowActiveFrameForeground = color.white
  103. Color.WindowInactiveFrameBackground = color.magenta
  104. Color.WindowInactiveFrameForeground = color.white
  105. Color.Shadow = color.black
  106. Color.Frame = color.white
  107.  
  108. --menu colors
  109. Color.MenuBackground = color.darkGray
  110. Color.MenuForeground = color.white
  111. Color.MenuSelectedBackground = color.darkGreen
  112. Color.MenuSelectedForeground = color.white
  113. Color.startMenuBackground = color.darkGray
  114. Color.startMenuForeground = color.white
  115. Color.startMenuActiveBackground = color.darkGray
  116. Color.startMenuActiveForeground = color.red
  117. Color.systemMenuBackground = color.darkGray
  118. Color.systemMenuForeground = color.white
  119. Color.systemMenuActiveBackground = color.darkGray
  120. Color.systemMenuActiveForeground = color.red
  121.  
  122. -- frames
  123. local frame = {
  124.   -- horizontal, vertical, left-top, right-top, left-bottom, right-bottom
  125.   ["Flat"] = {0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020},
  126.   ["Double"] = {0x2550, 0x2551, 0x2554, 0x2557, 0x255A, 0x255D},
  127.   ["Small"] = {0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518},
  128.   ["Bold"] = {0x2501, 0x2503, 0x0250F, 0x2513, 0x2517, 0x251B}
  129. }
  130.  
  131. local windowFrame = frame.Bold      -- standard frame for windows is double line
  132. local useWindowShadows = true
  133. local useBoxShadows = true
  134.  
  135. local menuFrame = frame.Small
  136.  
  137. local ScreenWidth, ScreenHeight = gpu.getResolution()
  138.  
  139. local blockMouse = false
  140.  
  141. function wm.setBoxShadow(state)
  142.   useBoxShadows = state
  143. end
  144.  
  145. function wm.useShadows(state)
  146.   useWindowShadows = state
  147. end
  148.  
  149. function wm.getShadowState()
  150.   return useWindowShadows
  151. end
  152.  
  153. function wm.getShadowBoxed()
  154.   return useBoxShadows
  155. end
  156.  
  157. local userLevel = 100
  158. local userName = ""
  159.  
  160. function wm.setUserLevel(level)
  161.   userLevel = level
  162. end
  163.  
  164. function wm.getUserLevel()
  165.   return userLevel
  166. end
  167.  
  168. function wm.getUsername()
  169.   return userName
  170. end
  171.  
  172. function wm.setUsername(name)
  173.   userName = name
  174. end
  175.  
  176. -- general functions
  177.  
  178. function clearScreen()
  179.     gpu.setBackground(Color.ScreenBackground)
  180.     gpu.setForeground(Color.ScreenForeground)
  181.     gpu.fill(1, 2, ScreenWidth, ScreenHeight - 2, " ")
  182. end
  183.  
  184. function drawScreen()
  185.   gpu.setBackground(Color.TopLineBackground)
  186.   gpu.setForeground(Color.TopLineForeground)
  187.   gpu.fill(1, 1, ScreenWidth, 1, " ")
  188.   gpu.setBackground(Color.BottomLineBackground)
  189.   gpu.setForeground(Color.BottomLineForeground)
  190.   gpu.fill(1, ScreenHeight, ScreenWidth, 1, " ")
  191. end
  192.  
  193.  
  194. -- gui elements
  195. local Element = {}
  196. Element.__index = Element
  197.  
  198. function Element:New(id, x, y, w, h, text, callback)
  199.   element = setmetatable({
  200.     id = id or "unknown",                   -- id for identification of type, eg. label, button
  201.     x = x or 1,
  202.     y = y or 1,
  203.     w = w or 1,
  204.     h = h or 1,
  205.     text = text,
  206.     alignment = "left",
  207.     autoWordWrap = false,
  208.     protected = false,                      -- use for inputs to set asterix as letter (password input)
  209.     background = nil,
  210.     foreground = nil,
  211.     callback = callback or nil,                 -- callback that's called when element is clicked
  212.     drawCallback = nil,                     -- callback for draw function
  213.     handleCallback = nil,                   -- callback for handling the element
  214.     activeBackground = nil,                     -- colors for clicked
  215.     activeForeground = nil,
  216.     isActive = false,
  217.     max = 0,
  218.     min = 0,
  219.     value = 0,
  220.     steps = 1,
  221.     state = false,                      -- can be used for checkboxes
  222.     data = {},                          -- used for element groups, like radio bottons
  223.     selected = 1,                       -- for selected elements in groups
  224.     first = 1,
  225.     last = 1,
  226.     type = 1,                           -- if there are differend types of the element, like lines (small or double)
  227.     ignoreMouseBlock = false,                   -- if set to true, element will ignore the mouse block function
  228.     userData1 = {},
  229.     userData2 = {},                     -- extra space for user created elements
  230.     userData3 = {},
  231.   },Element)
  232.   return element
  233. end
  234.  
  235. local function correctPos(win, self)
  236.   local x = self.x + win.x
  237.   local y = self.y + win.y
  238.   local w = self.w - 1
  239.   local h = self.h
  240.  
  241.   while x + w > win.x + win.w - 1 do        -- element is too long
  242.     w = w - 1
  243.   end
  244.   if w < 0 then
  245.     w = 0
  246.   end
  247.   while y + h > win.y + win.h do        -- element is too long
  248.     h = h - 1
  249.   end
  250.   if h < 0 then
  251.     h = 0
  252.   end
  253.   return x, y, w, h
  254. end
  255.  
  256.  
  257. function checkElementTouch(x, y, b, win, self)
  258.     for j = 1, #win.elements do
  259.       if win.elements[j].isActive == true then
  260.     return
  261.       end
  262.     end
  263.   local sx, sy, sw, sh = correctPos(win, self)
  264.   if x >= sx and x <= sx + sw  and x < win.x + win.w - 1 then
  265.     if y >= sy and y <= sy + sh - 1 then
  266.       if self.handleCallback then
  267.       if self.handleCallback(win, self, x, y, b) == false then  -- first the handle callback for further actions
  268.         return                          -- we get out, if the handle callback gives a false back. no user callback then
  269.       end
  270.       end
  271.       if self.callback then
  272.     if blockMouse == false or self.ignoreMouseBlock == true then
  273.       self.callback(self, win)                  -- second the user callback
  274.     end
  275.       end
  276.     end
  277.   end
  278. end
  279.  
  280.  
  281.  
  282.  
  283.  
  284. -- for the window list menu
  285. local windowListMenu = {}
  286.  
  287. -- Window stuff
  288. local Window = {}
  289. Window.__index = Window
  290.  
  291. local WindowList = {}
  292.  
  293.  
  294. local function redrawAllWindows()
  295.   for i = 1, #WindowList do
  296.     if WindowList[i].lowered == false then-- don't display lowered windows
  297.       WindowList[i]:draw()
  298.     end
  299.   end
  300. end
  301.  
  302. local function resortWindows()
  303.   for i = 1, #WindowList do
  304.     WindowList[i].id  = i           -- resort the id values
  305.   end
  306. end
  307.  
  308. function Window:New(x, y, w, h, text)
  309.   window = setmetatable({
  310.   x = x,
  311.   y = y + 1,        -- start under the top line
  312.   w = w,
  313.   h = h,
  314.   text = text,
  315.   id = #WindowList + 1,
  316.   lowered = true,
  317.   buffer = {},
  318.   buffer2 = {},
  319.   moving = false,
  320.   elements = {},
  321.   disableButtons = false,
  322.   sticky = false,
  323.   hide = false,
  324.   onCloseCallback = nil,
  325.   onLowerCallback = nil,
  326.   onTop = false,
  327.   refesh = true,
  328.   }, Window)
  329.   table.insert(WindowList, window)
  330.   return window
  331. end
  332.  
  333. function Window:saveBackground()
  334.   self.buffer = {}          -- clear the buffer
  335.   -- for the active window we save the whole background, if it is not moving, or lowered
  336. --[[
  337.   if self.id == #WindowList and self.moving == false and self.lowered  == false then
  338.     for i = 1, self. w do
  339.       self.buffer[i] = {}
  340.       for j = 1, self.h + 1 do
  341.     local c, fg, bg = gpu.get(self.x + i - 1, self.y + j - 1)
  342.     self.buffer[i][j] = {["c"] = c, ["fg"] = fg, ["bg"] = bg}
  343.       end
  344.     end
  345.   elseif self.id == #WindowList then
  346. ]]--
  347.     for x = self.x, self.x + self.w do
  348.       local c, fg, bg = gpu.get(x, self.y)
  349.       table.insert(self.buffer, {c, fg, bg})    -- insert the character and colors into the buffer
  350.     end
  351. --  end
  352. end
  353.  
  354. function Window:restoreBackground()
  355.   -- for the active window we restore the whole background, if it is not moving or lowered
  356. --[[
  357.   if self.id == #WindowList and self.moving == false and self.lowered  == false then
  358.     local oldBG = -1
  359.     local oldFG = -1
  360.     for i = 1, self.w do
  361.       for j = 1, self.h + 1 do
  362.     if oldBG ~= self.buffer[i][j].bg then
  363.       gpu.setBackground(self.buffer[i][j].bg)
  364.       oldBG = self.buffer[i][j].bg
  365.     end
  366.     if oldFG ~= self.buffer[i][j].fg then
  367.       gpu.setForeground(self.buffer[i][j].fg)
  368.       oldFG = self.buffer[i][j].fg
  369.     end
  370.     gpu.set(self.x + i - 1, self.y + j - 1, self.buffer[i][j].c)
  371.       end
  372.     end
  373.   elseif self.id == #WindowList then
  374. ]]--
  375.     local oldFG, oldBG
  376.     for x, value in pairs(self.buffer) do
  377.       local bg = value[3]
  378.       local fg = value[2]
  379.       if oldBG ~= bg then
  380.     gpu.setBackground(bg)
  381.     oldBG = bg
  382.       end
  383.       if oldFG ~= fg then
  384.     gpu.setForeground(fg)
  385.     oldFG = fg
  386.       end
  387.       gpu.set(self.x + x -1, self.y, value[1])
  388.     end
  389. --  end
  390. end
  391.  
  392. function Window:draw()
  393.   -- check size of window depending an screen an correct the position if outside
  394.   if self.y < 2 then                -- no window on top line of screen
  395.     self.y = 2
  396.   end
  397.   if self.x < 1 then
  398.     self.x = 1
  399.   end
  400.   if self.x + self.w > ScreenWidth then
  401.     self.x = ScreenWidth - self.w
  402.   end
  403.   if useWindowShadows == true then
  404.     if self.y + self.h > ScreenHeight - 2 then
  405.       self.y = ScreenHeight - 2 - self.h        -- we need the bottom line of screen for window manager
  406.     end
  407.   else
  408.     if self.y + self.h > ScreenHeight - 1 then
  409.       self.y = ScreenHeight - 1 - self.h        -- we need the bottom line of screen for window manager
  410.     end
  411.   end
  412.   -- save the background of the top line for moving
  413.   self:saveBackground()
  414.   -- color of top line depends if window is on top or in background
  415.   if self.id == #WindowList then
  416.     gpu.setForeground(Color.WindowActiveFrameForeground)
  417.     gpu.setBackground(Color.WindowActiveFrameBackground)
  418.   else
  419.     gpu.setForeground(Color.WindowInactiveFrameForeground)
  420.     gpu.setBackground(Color.WindowInactiveFrameBackground)
  421.   end
  422.   -- display the top line of the window
  423.   gpu.fill(self.x, self.y, self.w, 1, " ")
  424.   if string.len(self.text) <= self.w - 3 then
  425.     gpu.set(self.x + math.floor((self.w/2) - (string.len(self.text)/2)), self.y, self.text)
  426.   else
  427.     gpu.set(self.x +1, self.y, string.sub(self.text,1, self.w - 3))
  428.   end
  429.   if self.sticky == false then
  430.     gpu.set(self.x, self.y, "#")
  431.   end
  432.   if self.disableButtons == false then
  433.     gpu.set(self.x + self.w - 2, self.y, "_X")
  434.   end
  435.   if self.moving == false then
  436.     -- fill the window main body
  437.     gpu.setBackground(Color.WindowBackground)
  438.     gpu.setForeground(Color.Frame)
  439.     gpu.fill(self.x, self.y + 1, self.w, self.h, " ")
  440.     -- paint the frame
  441.     gpu.fill(self.x, self.y + 1, 1, self.h - 1, unicode.char(windowFrame[2]))
  442.     gpu.fill(self.x + self.w - 1, self.y + 1, 1, self.h - 1, unicode.char(windowFrame[2]))
  443.     gpu.fill(self.x + 1, self.y + self.h, self.w - 2, 1, unicode.char(windowFrame[1]))
  444.     gpu.set(self.x, self.y + self.h, unicode.char(windowFrame[5]))
  445.     gpu.set(self.x + self.w - 1, self.y + self.h, unicode.char(windowFrame[6]))
  446.     if useWindowShadows == true then
  447.       gpu.setForeground(Color.Shadow)
  448.       gpu.setBackground(Color.Shadow)
  449.       gpu.fill(self.x + 1, self.y + self.h + 1, self.w - 1, 1, " ")
  450.       gpu.fill(self.x + self.w, self.y + 1, 1, self.h + 1, " ")
  451.       if useBoxShadows == true then
  452.     _, _, Background, _ = gpu.get(self.x + self.w, self.y)
  453.     gpu.setBackground(Background)
  454.     gpu.set(self.x + self.w, self.y, unicode.char(0x25E3))
  455.     _, _, Background, _ = gpu.get(self.x, self.y + self.h + 1)
  456.     gpu.setBackground(Background)
  457.     gpu.set(self.x, self.y + self.h + 1, unicode.char(0x25E5))
  458.       end
  459.      
  460.     end
  461.     -- redraw all elements in window
  462.     for i = 1, #self.elements do
  463.       self.elements[i].drawCallback(self, self.elements[i])     -- each element has his own callback for drawing it
  464.     end
  465.   end
  466. end
  467.  
  468. -- checks if window is touched and raise it, if it is not the top one
  469. function Window:onTouch(x, y, b)
  470.   if self.lowered == true then
  471.     return false
  472.   end
  473.  
  474.   for key, value in pairs(self.elements) do
  475.     if x >= self.x and x <= self.x + self.w - 1 and self.moving == false then
  476.       if y >= self.y and y <= self.y + self.h then
  477.     if self.id < #WindowList then
  478.       if blockMouse == false then
  479.         wm.raiseWindow(self)
  480.       end
  481.     end
  482.     checkElementTouch(x, y, b, self, value)
  483.       end
  484.     end
  485.   end
  486.  
  487.   if blockMouse == true then
  488.     return true
  489.   end
  490.   -- check if one of the window buttons is clicked (lower or close)
  491.   if x == self.x + self.w - 1 and y == self.y and self.moving == false and self.disableButtons == false then            -- close button
  492.       wm.closeWindow(self)
  493.       return true
  494.   elseif x == self.x + self.w - 2 and y == self.y and self.moving == false and self.disableButtons == false then        -- lower button
  495.       wm.lowerWindow(self)
  496.       return true
  497.   elseif x == self.x and y == self.y and self.sticky == false then          -- then movement button
  498.     self.moving = not self.moving                           -- switch movemnt mode of window
  499.     wm.raiseWindow(self)
  500.     return true
  501.   end
  502.  
  503.   if x >= self.x and x <= self.x + self.w - 1 and self.moving == false then
  504.     if y >= self.y and y <= self.y + self.h then
  505.       if self.id < #WindowList then
  506.     -- window is lower, then the top one. raise it top level
  507.     wm.raiseWindow(self)
  508.     return true
  509.       else
  510.     return true
  511.       end
  512.     end
  513.   end
  514.  
  515.  
  516.   return false
  517. end
  518.  
  519. function Window:move(x, y)
  520.   self.x = x
  521.   self.y = y
  522. end
  523.  
  524. -- top and bottom stuff
  525. local symbolList = {}
  526. local Symbol = {}
  527. Symbol.__index = Symbol
  528.  
  529. function Symbol:New(x, y, icon, program, level, w)
  530.   symbol = setmetatable({
  531.     x = x,
  532.     y = y,
  533.     level = level or 0,
  534.     icon = icon or "?",
  535.     w = w or 1,
  536.     program = assert(loadfile(program)) or nil,
  537.     runningState = false,
  538.   },Symbol)
  539.   table.insert(symbolList, symbol)
  540.   if symbolList[#symbolList].program and symbolList[#symbolList].runningState == false then
  541.     symbolList[#symbolList].program(#symbolList, "load", 0, symbolList[#symbolList].icon)
  542.   end
  543. end
  544.  
  545. local function drawSymbols()
  546.   gpu.setBackground(Color.BottomLineBackground)
  547.   gpu.setForeground(Color.BottomLineForeground)
  548.   for i = 1, #symbolList do
  549.     gpu.set(symbolList[i].x, symbolList[i].y, symbolList[i].icon)
  550.   end
  551. end
  552.  
  553. function symbolTouchCheck(x, y, b)
  554.   if blockMouse == true then
  555.     return
  556.   end
  557.   for i = 1, #symbolList do
  558.     if x <= symbolList[i].x + symbolList[i].w - 1 and x >= symbolList[i].x and y == symbolList[i].y then
  559.     if symbolList[i].program and symbolList[i].runningState == false then
  560.       if userLevel >= symbolList[i].level then
  561.         symbolList[i].program(i, "execute", math.floor(b), symbolList[i].icon)
  562.       end
  563.     end
  564.     end
  565.   end
  566. end
  567.  
  568. function wm.newSymbol(icon, program, level)
  569.   local w = string.len(icon)
  570.   if w < 1 then
  571.     w = 1
  572.   end
  573.   for i = 1, #symbolList do
  574.     w = w + symbolList[i].w
  575.   end
  576.   local x = ScreenWidth - w + 1
  577.   local y = ScreenHeight
  578.   l = string.len(icon)
  579.   if l < 1 then
  580.     l = 1
  581.   end
  582.   ret = Symbol:New(x, y, icon, program, level, l)
  583.   drawSymbols()
  584.   return ret
  585. end
  586.  
  587. function wm.setSymbolSize(id, size)
  588.   local w = size
  589.   for i = 1, #symbolList do
  590.     if i ~= id then
  591.       w = w + symbolList[i].w
  592.     end
  593.   end
  594.   symbolList[id].w = size
  595.   symbolList[id].x = ScreenWidth - w + 1
  596.   drawSymbols()
  597. end
  598.  
  599. function wm.setIcon(id, icon)
  600.   symbolList[id].icon = icon
  601.   drawSymbols()
  602. end
  603.  
  604. function wm.setSymbolProgram(self, program)
  605.   self.program = assert(loadfile(program))
  606. end
  607.  
  608. function wm.drawSymbol(id, c)
  609.   gpu.setBackground(Color.BottomLineBackground)
  610.   if c then
  611.     gpu.setForeground(c)
  612.   else
  613.     gpu.setForeground(Color.BottomLineForeground)
  614.   end
  615.   gpu.set(symbolList[id].x, symbolList[id].y, symbolList[id].icon)
  616. end
  617.  
  618. function wm.getSymbolPos(id)
  619.   return symbolList[id].x, symbolList[id].y
  620. end
  621.  
  622. function wm.setRunningState(num, state)
  623.   symbolList[num].runningState = state
  624. end
  625.  
  626. -- menu stuff
  627. local Menu = {}
  628. Menu.__index = Menu
  629.  
  630. local MenuList = {}
  631. local menuIsActive = 0
  632.  
  633. function Menu:New(x, y, w, text, callback)
  634.   menu = setmetatable({
  635.     id = #MenuList + 1,
  636.     x = x,
  637.     y = y,
  638.     w = w,
  639.     text = text,
  640.     entries = {},
  641.     selected = 1,
  642.     callback = callback,
  643.     useFrame = false,
  644.     buffer = {}
  645.   }, Menu)
  646.   for i = 1, w + 2 do
  647.     menu.buffer[i] = {}
  648.     for j = 1, 20 do
  649.       menu.buffer[i][j] = { ["bg"] = 0, ["fg"] = 0, ["ch"] = " " }
  650.     end
  651.   end
  652.   table.insert(MenuList, menu)          -- just for loop over all menus
  653.   return menu
  654. end
  655.  
  656. function menuSaveBackground(self)
  657.   local w = self.w
  658.   local h = #self.entries
  659.   if self.useFrame == true then
  660.     h = h + 2
  661.     -- needed if menu list is empty
  662.     if h == 2 then
  663.       return
  664.     end
  665.   end
  666.   if h == 0 then
  667.     return
  668.   end
  669.   for i = 1, w do
  670.     for j = 1, h do
  671.       local ch, fg, bg = gpu.get(self.x + i - 1, self.y + j - 1)
  672.       self.buffer[i][j] = { ["bg"] = bg, ["fg"] = fg, ["ch"] = ch }
  673.     end
  674.   end
  675. end
  676.  
  677. function restoreMenuBackground(self)
  678.   local oldBG, oldFG
  679.   local w = self.w
  680.   local h = #self.entries
  681.   if self.useFrame == true then
  682.     h = h + 2
  683.     -- needed if menu list is empty
  684.     if h == 2 then
  685.       return
  686.     end
  687.   end
  688.   if h == 0 then
  689.     return
  690.   end
  691.   for i = 1, w do
  692.     for j = 1, h do
  693.       if oldBG ~= self.buffer[i][j].bg then
  694.     gpu.setBackground(self.buffer[i][j].bg)
  695.     oldBG = self.buffer[i][j].bg
  696.       end
  697.       if oldFG ~= self.buffer[i][j].fg then
  698.     oldFG = self.buffer[i][j].fg
  699.       end
  700.       gpu.set(self.x + i - 1, self.y + j - 1, self.buffer[i][j].ch)
  701.     end
  702.   end
  703. end
  704.  
  705. function Menu:draw()
  706.   if #self.entries == 0 then
  707.     return
  708.   end
  709.   if self.x <= 1 then
  710.     self.x = 1
  711.   end
  712.   if self.x + self.w > ScreenWidth then
  713.     self.x = ScreenWidth - self.w
  714.   end
  715.   if self.y < 2 then
  716.     self.y = 2
  717.   end
  718.   if self.useFrame == true then
  719.     if self.y + #self.entries + 2 > ScreenHeight  then
  720.       self.y = ScreenHeight - #self.entries - 2
  721.     end
  722.   else
  723.     if self.y + #self.entries > ScreenHeight  then
  724.       self.y = ScreenHeight - #self.entries
  725.     end
  726.   end
  727.   menuSaveBackground(self)
  728.   for i = 1, #self.entries do
  729.     if i == self.selected then
  730.       gpu.setBackground(Color.MenuSelectedBackground)
  731.       gpu.setForeground(Color.MenuSelectedForeground)
  732.     else
  733.       gpu.setBackground(Color.MenuBackground)
  734.       gpu.setForeground(Color.MenuForeground)
  735.     end
  736.     if self.useFrame == true then
  737.       gpu.fill(self.x + 1, self.y + i, self.w - 2, 1, " ")
  738.       gpu.set(self.x + 1, self.y + i, string.sub(self.entries[i], 1, self.w - 2))
  739.       -- start frame
  740.       gpu.setBackground(Color.MenuBackground)
  741.       gpu.setForeground(Color.MenuForeground)
  742.       gpu.set(self.x, self.y + i, unicode.char(menuFrame[2]))
  743.       gpu.set(self.x + self.w - 1, self.y + i, unicode.char(menuFrame[2]))
  744.       gpu.set(self.x, self.y, unicode.char(menuFrame[3]))
  745.       gpu.set(self.x + self.w - 1, self.y, unicode.char(menuFrame[4]))
  746.       gpu.set(self.x, self.y + #self.entries + 1, unicode.char(menuFrame[5]))
  747.       gpu.set(self.x + self.w - 1, self.y + #self.entries + 1, unicode.char(menuFrame[6]))
  748.     else
  749.       gpu.fill(self.x , self.y + i - 1, self.w, 1, " ")
  750.       gpu.set(self.x, self.y + i - 1, string.sub(self.entries[i], 1, self.w - 1))
  751.     end
  752.   end
  753.   if self.useFrame == true then
  754.     gpu.fill(self.x + 1, self.y, self.w - 2, 1, unicode.char(menuFrame[1]))
  755.     gpu.fill(self.x + 1, self.y + #self.entries + 1, self.w - 2, 1, unicode.char(menuFrame[1]))
  756.     gpu.set(self.x + math.floor(self.w/2) - math.floor(string.len(self.text)/2), self.y, self.text)
  757.   end
  758. end
  759.  
  760. function Menu:onTouch(x, y, b)
  761.   if blockMouse == true then
  762.     return
  763.   end
  764.   if b == 0 then                        -- menus will only accept left mouse button
  765.     -- touch is inside menu
  766.     if x >= self.x and x <= self.x + self.w - 1 then
  767.       if y >= self.y and y <= self.y + #self.entries then
  768. -- FIXME: Need to be redone, because sometimes the wrong window is selected if menu is shown over a window.
  769.     --Then the window under the menu will become the active one
  770.     if self.useFrame == true then
  771.       self.selected = y - self.y
  772.       restoreMenuBackground(self)
  773.       self:draw()
  774.       os.sleep(0.1)                     -- give user a chance to see the click :-)
  775.       restoreMenuBackground(self)
  776.       self.callback(y - self.y)
  777.     else
  778.       self.selected = y - self.y + 1
  779.       restoreMenuBackground(self)
  780.       self:draw()
  781.       os.sleep(0.1)                     -- give user a chance to see the click :-)
  782.       restoreMenuBackground(self)
  783.       self.callback(y - self.y + 1)
  784.     end
  785.       end
  786.     else
  787.       restoreMenuBackground(self)
  788.     end
  789.   else
  790.     restoreMenuBackground(self)
  791.   end
  792.     -- at last deactivate menu and get back to window handling
  793.     menuIsActive = 0
  794. end
  795.  
  796.  
  797. -- screen event handling
  798. function screenTouchCheck(x, y, b)
  799.   if blockMouse == false then
  800.     if y > 1 and y < ScreenHeight then                  -- ignore touch on top or bottom line
  801.       if b == 1 then                            -- right mouse button opens window list
  802.     wm.clearMenu(windowListMenu)
  803.     wm.menuSetPosition(windowListMenu, x, y)
  804.     for i = 1, #WindowList do
  805.       if WindowList[i].hide == false then               -- hide windows will not shown in window list
  806.         if WindowList[i].lowered == true then
  807.           wm.insertMenu(windowListMenu, "-" .. WindowList[i].text)
  808.         else
  809.           wm.insertMenu(windowListMenu, " " .. WindowList[i].text)
  810.         end
  811.       end
  812.     end
  813.     wm.drawMenu(windowListMenu)
  814.       end
  815.     end
  816.   end
  817. end
  818.  
  819. local systemMenu = {}
  820. local systemMenuState = false
  821. local systemMenuEnabled = true
  822. local systemMenuPos = 1
  823.  
  824. local systemMenuList = {}
  825. local SystemMenuElement = {}
  826. SystemMenuElement.__index = SystemMenuElement
  827.  
  828. local function drawSystemMenu()
  829.   if systemMenuEnabled == true then
  830.     if systemMenuState == false then
  831.       gpu.setBackground(Color.systemMenuBackground)
  832.       gpu.setForeground(Color.systemMenuForeground)
  833.     elseif systemMenuState == true then
  834.       gpu.setBackground(Color.systemMenuActiveBackground)
  835.       gpu.setForeground(Color.systemMenuActiveForeground)
  836.     end
  837.     gpu.set(systemMenuPos, 1, "[system]")
  838.   end
  839. end
  840.  
  841.  
  842. function SystemMenuElement:New(name, path, param, level, Type)
  843.   sm = setmetatable ({
  844.     name = name,
  845.     path = path,
  846.     level = level or 0,
  847.     isActive = false,
  848.     Type = Type or 0,
  849.     param = param or nil,
  850.   },SystemMenuElement)
  851.   wm.insertMenu(systemMenu, name)
  852.   table.insert(systemMenuList, sm)
  853.   wm.menuSetPosition(systemMenu, systemMenuPos - 10, 1)
  854.   drawSystemMenu()
  855.   return sm
  856. end
  857.  
  858. function systemmenuTouchCheck(x, y, b)
  859.   if blockMouse == true then
  860.     return
  861.   end
  862.   if y == 1 and x >= systemMenuPos and x <= systemMenuPos + 7 then          -- menu clicked
  863.     systemMenuState = not systemMenuState
  864.     drawSystemMenu()
  865.     if systemMenuState == true then
  866.       wm.drawMenu(systemMenu)
  867.     end
  868.   end
  869. end
  870.  
  871. function wm.addSystemMenu(name, path, param, level, Type)
  872.   SystemMenuElement:New(name, path, param, level, Type)
  873. end
  874.  
  875. local function systemMenuCallback(entry)
  876.   systemMenuState = false
  877.   drawSystemMenu()
  878.   if systemMenuList[entry].isActive == false then
  879.     systemMenuList[entry].isActive = true
  880.     if userLevel >= systemMenuList[entry].level then
  881.       if systemMenuList[entry].Type == 0 then
  882.     wm.startProgram(systemMenuList[entry].path, entry)(systemMenuList[entry].param)
  883.       elseif systemMenuList[entry].Type == 1 then
  884.     systemMenuList[entry].path(systemMenuList[entry].param)
  885.       end
  886.     end
  887.   end
  888. end
  889.  
  890. function wm.enableSytemMenu(state)
  891.   systemMenuEnabled = state
  892. end
  893.  
  894. function wm.setSystemMenuPos(pos)
  895.   if pos == "left" then
  896.     systemMenuPos = 1
  897.   elseif pos == "right" then
  898.     systemMenuPos = ScreenWidth - 8
  899.   end
  900. end
  901.  
  902. local startMenu = {}
  903. local startMenuState = false
  904. local startMenuEnabled = true
  905.  
  906. local startMenuList = {}
  907. local StartMenuElement = {}
  908. StartMenuElement.__index = StartMenuElement
  909.  
  910. local function drawStartMenu()
  911.   if startMenuEnabled == true then
  912.     if startMenuState == false then
  913.       gpu.setBackground(Color.startMenuBackground)
  914.       gpu.setForeground(Color.startMenuForeground)
  915.     elseif startMenuState == true then
  916.       gpu.setBackground(Color.startMenuActiveBackground)
  917.       gpu.setForeground(Color.startMenuActiveForeground)
  918.     end
  919.     gpu.set(2, ScreenHeight, "[start]")
  920.   end
  921. end
  922.  
  923.  
  924. function StartMenuElement:New(name, path, param, level, Type)
  925.   sm = setmetatable ({
  926.     name = name,
  927.     path = path,
  928.     level = level or 0,
  929.     isActive = false,
  930.     Type = Type or 0,
  931.     param = param or nil,
  932.   },StartMenuElement)
  933.   wm.insertMenu(startMenu, name)
  934.   table.insert(startMenuList, sm)
  935.   wm.menuSetPosition(startMenu, 2, ScreenHeight - 2 - #startMenuList)
  936.   drawStartMenu()
  937.   return sm
  938. end
  939.  
  940. function startmenuTouchCheck(x, y, b)
  941.   if blockMouse == true then
  942.     return
  943.   end
  944.   if y == ScreenHeight and x >= 1 and x <= 7 then           -- start clicked
  945.     startMenuState = not startMenuState
  946.     drawStartMenu()
  947.     if startMenuState == true then
  948.       wm.drawMenu(startMenu)
  949.     end
  950.   end
  951. end
  952.  
  953. function wm.addStartMenu(name, path, param, level, Type)
  954.   StartMenuElement:New(name, path, param, level, Type)
  955. end
  956.  
  957. local function startMenuCallback(entry)
  958.   startMenuState = false
  959.   drawStartMenu()
  960.   if startMenuList[entry].isActive == false then
  961.     startMenuList[entry].isActive = true
  962.     if userLevel >= startMenuList[entry].level then
  963.       if startMenuList[entry].Type == 0 then
  964.     wm.startProgram(startMenuList[entry].path, entry)(startMenuList[entry].param)
  965.       elseif startMenuList[entry].Type == 1 then
  966.     startMenuList[entry].path(startMenuList[entry].param)
  967.       end
  968.     end
  969.   end
  970. end
  971.  
  972. function wm.shutdown(reboot)
  973.   computer.shutdown(reboot)
  974. end
  975.  
  976. function wm.exitProgram(id)
  977.   startMenuList[id].isActive = false
  978. end
  979.  
  980. function wm.enableStartMenu(state)
  981.   startMenuEnabled = state
  982. end
  983.  
  984. -- event listeners
  985.  
  986. -- the touch event handler it self
  987. local function TouchEventListener(_, _, x, y, b)
  988.   if menuIsActive == 0 then                     -- if a menu is running, no window management
  989.     local wasWindowAction = false
  990.     -- needs to be backwards, because top window is allways last in list
  991.     for i = #WindowList, 1, -1 do
  992.       -- window touch returns true, if window is on top
  993.       if WindowList[i]:onTouch(x, y, b) == true then
  994.     wasWindowAction = true                      -- needed for on screen clicks, if click was inside any window
  995.     break
  996.       end
  997.     end
  998.     if wasWindowAction == false then                    -- the click was somewhere on the screen, outside a window
  999.     if systemMenuState == true then
  1000.       restoreMenuBackground(systemMenu)
  1001.       systemMenuState = false
  1002.       drawSystemMenu()
  1003.     end
  1004.     if startMenuState == true then
  1005.       restoreMenuBackground(startMenu)
  1006.       startMenuState = false
  1007.       drawStartMenu()
  1008.     end
  1009.       screenTouchCheck(x, y, b)
  1010.     end
  1011.   elseif menuIsActive > 0 then
  1012.     -- handle menu touch
  1013.     if systemMenuState == true then
  1014.       restoreMenuBackground(systemMenu)
  1015.       systemMenuState = false
  1016.       drawSystemMenu()
  1017.     end
  1018.     if startMenuState == true then
  1019.       restoreMenuBackground(startMenu)
  1020.       startMenuState = false
  1021.       drawStartMenu()
  1022.     end
  1023.     MenuList[menuIsActive]:onTouch(x, y, b)
  1024.   end
  1025.     -- bottom line check
  1026.   if y == ScreenHeight then
  1027.     if systemMenuState == true then
  1028.       restoreMenuBackground(systemMenu)
  1029.       systemMenuState = false
  1030.       drawSystemMenu()
  1031.     end
  1032.     if x > 10 then
  1033.       symbolTouchCheck(x, y, b)
  1034.     elseif startMenuEnabled == true then
  1035.       startmenuTouchCheck(x, y, b)
  1036.     end
  1037.   elseif y == 1 then
  1038.     if startMenuState == true then
  1039.       restoreMenuBackground(startMenu)
  1040.       startMenuState = false
  1041.       drawStartMenu()
  1042.     end
  1043.     systemmenuTouchCheck(x, y, b)
  1044.   end
  1045. end
  1046.  
  1047. local function DragEventListener(_, _, x, y, b)
  1048.   if blockMouse == false then
  1049.     if WindowList[#WindowList].moving == true then
  1050.       WindowList[#WindowList]:restoreBackground()
  1051.       WindowList[#WindowList]:move(x, y)
  1052.       WindowList[#WindowList]:draw()
  1053. --      clearScreen()
  1054. --      AllWindows()
  1055.     end
  1056.   end
  1057. end
  1058.  
  1059. local function DropEventListener(_, _, x, y, b)
  1060.   if blockMouse == false then
  1061.     WindowList[#WindowList].moving = false
  1062.     WindowList[#WindowList]:draw()
  1063.   end
  1064. end
  1065.  
  1066.  
  1067. local DriverList = {}
  1068. local Driver = {}
  1069. Driver.__index = Driver
  1070.  
  1071. function Driver:New(name, description, copyright, version)
  1072.   driver = setmetatable({
  1073.     id = #DriverList + 1,
  1074.     name = name,
  1075.     description = description or "",
  1076.     copyright = copyright or "",
  1077.     version = version or "0.0"
  1078.   },Driver)
  1079.   table.insert(DriverList, driver)
  1080.   return driver
  1081. end
  1082.  
  1083. dotPosition = ScreenWidth
  1084.  
  1085. function wm.registerDriver(name, description, copyright, version)
  1086.   Driver:New(name, description, copyright, version)
  1087.   dotPosition = dotPosition - 1
  1088.   return dotPosition
  1089. end
  1090.  
  1091. function wm.getDriverList()
  1092.   return DriverList
  1093. end
  1094.  
  1095. local function autoUpdateTimerCallback()
  1096.   MultiThread()
  1097. end
  1098.  
  1099.  
  1100. -- General functions
  1101. function wm.getActiveWindow()
  1102.   return WindowList[#WindowList]
  1103. end
  1104.  
  1105. function wm.blockMouse(state)
  1106.   blockMouse = state
  1107. end
  1108.  
  1109. function windowMenuListCallback(entry)
  1110.   wm.raiseWindow(WindowList[entry])
  1111. end
  1112.  
  1113. local timerEventTimer
  1114.  
  1115. function wm.startProgram(path, id)
  1116.   local program = loadfile(path)(id)
  1117.   local th = threadCreate(program)
  1118. end
  1119.  
  1120. -- must be called once before using the gui
  1121. function wm.startGui()
  1122.   gpu.setBackground(color.black)
  1123.   gpu.setForeground(color.white)
  1124.   gpu.fill(1, 1, ScreenWidth, ScreenHeight, " ")
  1125.   gpu.set(1,1,"Starting windowmanager")
  1126.   clearScreen()
  1127.   drawScreen()
  1128.  
  1129.   -- build up the empty menu for the window list menu
  1130.   windowListMenu = wm.newMenu(1, 1, 20, "Window list", windowMenuListCallback)      -- x and y will be changed later
  1131.   if startMenuEnabled == true then
  1132.     startMenu = wm.newMenu(1, ScreenHeight, 20, "", startMenuCallback)
  1133.     wm.menuUseFrame(startMenu, true)
  1134.   end
  1135.   if systemMenuEnabled == true then
  1136.     systemMenu = wm.newMenu(1, 1, 20, "", systemMenuCallback)
  1137.     wm.menuUseFrame(systemMenu, true)
  1138.   end
  1139.   wm.menuUseFrame(windowListMenu, true)
  1140.  
  1141.   redrawAllWindows()
  1142.  
  1143.  
  1144.   event.listen("touch", TouchEventListener)
  1145.   event.listen("drag", DragEventListener)
  1146.   event.listen("drop", DropEventListener)
  1147.   autoUpdateTimer = event.timer(0.1, autoUpdateTimerCallback, math.huge)
  1148.   threadInit()
  1149.  
  1150. end
  1151.  
  1152. function wm.exitGui()
  1153.   gpu.setBackground(color.black)
  1154.   gpu.setForeground(color.white)
  1155.   gpu.fill(1, 1, ScreenWidth, ScreenHeight, " ")
  1156.   gpu.set(1, 1, "Stopping event listeners ")
  1157.   event.ignore("touch", TouchEventListener)
  1158.   event.ignore("drag", DragEventListener)
  1159.   event.ignore("drop", DropEventListener)
  1160.   event.cancel(autoUpdateTimer)
  1161.   gpu.set(26, 1, "ok")
  1162.   local d = 12
  1163.   gpu.set(1,2, "Cleaning up")
  1164.   for i = #WindowList, 1, -1 do
  1165.     table.remove(WindowList, i)
  1166.     gpu.set(d, 2, ".")
  1167.     d = d + 1
  1168.   end
  1169.   for i = #symbolList, 1, -1 do
  1170.     if symbolList[i].program then
  1171.       symbolList[i].program(i, "unload", 0, symbolList[i].icon)
  1172.       symbolList[i].program = nil
  1173.     end
  1174.     table.remove(symbolList, i)
  1175.     gpu.set(d, 2, ".")
  1176.     d = d + 1
  1177.   end
  1178.   gpu.set(d, 2, "ok")
  1179.   gpu.set(1,3, "Gui stopped")
  1180.   gpu.set(1,4, "You better reboot now :-)")
  1181.   os.exit()
  1182. end
  1183.  
  1184. function wm.setTopText(text)
  1185.   gpu.setBackground(Color.TopLineBackground)
  1186.   gpu.setForeground(Color.TopLineForeground)
  1187.   gpu.fill(1, 1, ScreenWidth, 1, " ")
  1188.   gpu.set(math.floor(ScreenWidth/2) - math.floor(string.len(text)/2), 1, text)
  1189. end
  1190.  
  1191.  
  1192. function wm.getColors()
  1193.   return Color
  1194. end
  1195.  
  1196. function wm.getVersion()
  1197.   return versionMajor, versionMinor, versionState
  1198. end
  1199.  
  1200. function wm.getWindowFrame()
  1201.   return windowFrame
  1202. end
  1203.  
  1204. function wm.setWindowFrame(num)
  1205.   if num == 1 then
  1206.     windowFrame = frame.Small
  1207.   elseif num == 2 then
  1208.     windowFrame = frame.Double
  1209.   elseif num == 3 then
  1210.     windowFrame = frame.Bold
  1211.   elseif num == 4 then
  1212.     windowFrame = frame.Flat
  1213.   end
  1214. end
  1215.  
  1216. function wm.getShadow()
  1217.   return useWindowShadows
  1218. end
  1219.  
  1220. function wm.setShadow(state)
  1221.   useWindowShadows = state
  1222. end
  1223.  
  1224. function wm.getMenuFrame()
  1225.   return menuFrame
  1226. end
  1227.  
  1228. function wm.setMenuFrame(num)
  1229.   if num == 1 then
  1230.     menuFrame = frame.Small
  1231.   elseif num == 2 then
  1232.     menuFrame = frame.Double
  1233.   elseif num == 3 then
  1234.     menuFrame = frame.Bold
  1235.   elseif num == 4 then
  1236.     menuFrame = frame.Flat
  1237.   end
  1238. end
  1239.  
  1240.  
  1241. -- Window functions
  1242.  
  1243. function wm.getViewport(self)
  1244.   return self.x, self.y + 1, self.w - 2, self.h - 1
  1245. end
  1246.  
  1247. function wm.newWindow(x, y, w, h, text)
  1248.   return Window:New(x, y, w, h, text)
  1249. end
  1250.  
  1251. -- set a window to top over all other windows
  1252. function wm.raiseWindow(self)
  1253.   self.lowered = false
  1254.   table.remove(WindowList, self.id)     -- remove the window from table
  1255.   table.insert(WindowList, self)        -- insert window as last in table
  1256.   resortWindows()
  1257.   for i = #WindowList - 1, 1, -1 do     -- take movement of all windows
  1258.     WindowList[i].moving = false
  1259.   end
  1260.   self.onTop = true
  1261.   clearScreen()
  1262.   redrawAllWindows()
  1263. end
  1264.  
  1265. function wm.closeWindow(self)
  1266. --  self:restoreBackground()
  1267.   if self.onCloseCallback then
  1268.     if self.onCloseCallback(self) == false then
  1269.       return
  1270.     end
  1271.   end
  1272.   table.remove(WindowList, self.id)
  1273.   self = nil
  1274.   resortWindows()
  1275.   clearScreen()
  1276.   redrawAllWindows()
  1277. end
  1278.  
  1279. function wm.lowerWindow(self)
  1280. --  self:restoreBackground()
  1281.   if self.onLowerCallback then
  1282.     if self.onLowerCallback(self) == false then
  1283.       return
  1284.     end
  1285.   end
  1286.   self.lowered = true
  1287.   for i = #WindowList, 1, -1 do         -- raise the next available window from end of list
  1288.     if WindowList[i].lowered == false then
  1289.       wm.raiseWindow(WindowList[i])
  1290.       break
  1291.     end
  1292.   end
  1293.  
  1294.   clearScreen()
  1295.   redrawAllWindows()
  1296. end
  1297.  
  1298. function wm.disableWindowButtons(self, state)
  1299.   self.disableButtons = state
  1300. end
  1301.  
  1302. function wm.setWindowSticky(self, state)
  1303.   self.sticky = state
  1304. end
  1305.  
  1306. function wm.hideWindow(self, state)
  1307.   self.hide = state
  1308. end
  1309.  
  1310. function wm.setOnCloseCallback(self, callback)
  1311.   self.onCloseCallback = callback
  1312. end
  1313.  
  1314. function wm.setOnLowerCallback(self, callback)
  1315.   self.onLowerCallback = callback
  1316. end
  1317.  
  1318. function wm.getWindowInfo(self)
  1319.   if self.lowered == false then
  1320.     return self.x, self.y, self.w, self.h, self.text, #self.elements
  1321.   elseif self.lowered == true then
  1322.     return 0, 0, 0, 0, self.text, #self.elements
  1323.   end
  1324. end
  1325.  
  1326.  
  1327. function wm.redraw()
  1328.     clearScreen()
  1329.     redrawAllWindows()
  1330. end
  1331.  
  1332. -- gui elements
  1333. function wm.addElement(self, element)
  1334.   table.insert(self.elements, element)
  1335. end
  1336.  
  1337. function wm.newElement(id, x, y, w, h, text, callback)
  1338.   return Element:New(id, x, y, w, h, text, callback)
  1339. end
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345. -- Menu functions
  1346. function wm.newMenu(x, y, w, text, callback)
  1347.   return Menu:New(x, y, w, text, callback)
  1348. end
  1349.  
  1350. function wm.insertMenu(self, entry)
  1351.   table.insert(self.entries, entry)
  1352. end
  1353.  
  1354. function wm.removeMenu(self, entry)
  1355.   table.remove(self.entries, entry)
  1356. end
  1357.  
  1358. function wm.clearMenu(self)
  1359.   self.entries = {}
  1360. end
  1361.  
  1362. function wm.setMenuCallback(self, callback)
  1363.   self.callback = callback
  1364. end
  1365.  
  1366. function wm.drawMenu(self)
  1367.   if menuIsActive ~= self.id and menuIsActive > 0 then
  1368.     restoreMenuBackground(MenuList[menuIsActive])
  1369.   end
  1370.   menuIsActive = self.id
  1371.   self.selected = 1
  1372.   self:draw()
  1373. end
  1374.  
  1375. function wm.menuSetPosition(self, x, y)
  1376.   self.x = x
  1377.   self.y = y
  1378. end
  1379.  
  1380. function wm.menuUseFrame(self, state)
  1381.   self.useFrame = state
  1382. end
  1383.  
  1384.  
  1385. return wm
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement