MattiasBuelens

CCGUI container

Jul 5th, 2012
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.71 KB | None | 0 0
  1. --[[
  2.  
  3.     ComputerCraft GUI
  4.     Container element
  5.  
  6. --]]
  7.  
  8. ccgui = ccgui or {}
  9.  
  10. local Container = common.newClass({
  11.     -- Children
  12.     children = nil,
  13.     -- Focused child index
  14.     childFocus = nil
  15. }, ccgui.Element)
  16. ccgui.Container = Container
  17.  
  18. function Container:init()
  19.     ccgui.Element.init(self)
  20.  
  21.     self.children = {}
  22.  
  23.     -- Paint
  24.     self:on("paint", self.drawChildren, self)
  25.     self:sinkEvent("beforepaint")
  26.     self:sinkEvent("afterpaint")
  27.     self:sinkEvent("beforeframe")
  28.     self:sinkEvent("afterframe")
  29.  
  30.     -- Mouse
  31.     self:sinkEvent("mouse_click")
  32.     self:sinkEvent("mouse_drag")
  33.     self:sinkEventToCurrent("mouse_scroll")
  34.  
  35.     -- Keyboard
  36.     self:sinkEventToCurrent("key")
  37.     self:sinkEventToCurrent("char")
  38. end
  39.  
  40. function Container:find(elem, deep)
  41.     if elem == nil then return nil end
  42.  
  43.     -- Deep search in child containers
  44.     deep = not not deep
  45.  
  46.     for i,child in ipairs(self.children) do
  47.         if child == elem then
  48.             return i
  49.         elseif (deep and type(child.find) == "function") then
  50.             if child:find(elem) ~= nil then
  51.                 return i
  52.             end
  53.         end
  54.     end
  55.     return nil
  56. end
  57.  
  58. function Container:each(func)
  59.     local n = #self.children
  60.     for i,child in ipairs(self.children) do
  61.         func(child, i, i == n)
  62.     end
  63. end
  64.  
  65. function Container:eachVisible(func)
  66.     -- Check if there is another visible child
  67.     -- after the given child index
  68.     local hasVisibleAfter = function(i)
  69.         for j=i+1, #self.children do
  70.             if self.children[j].isVisible then
  71.                 return true
  72.             end
  73.         end
  74.         return false
  75.     end
  76.  
  77.     -- Process only visible children
  78.     self:each(function(child, i)
  79.         if child.isVisible then
  80.             func(child, i, not hasVisibleAfter(i))
  81.         end
  82.     end)
  83. end
  84.  
  85. function Container:add(...)
  86.     local children = {...}
  87.  
  88.     -- Add as child
  89.     for i,child in ipairs(children) do
  90.         child.parent = self
  91.         table.insert(self.children, child)
  92.     end
  93.  
  94.     return #self.children
  95. end
  96.  
  97. function Container:remove(child)
  98.     if child.parent ~= self then
  99.         return false
  100.     end
  101.  
  102.     -- Remove as parent
  103.     child.parent = nil
  104.  
  105.     -- Remove from children
  106.     local i = common.ifind(self.children, child)
  107.     if i ~= nil then
  108.         table.remove(self.children, i)
  109.         -- Fix focused child
  110.         if self.childFocus ~= nil then
  111.             if self.childFocus == i then
  112.                 -- Currently focused child removed
  113.                 self.childFocus = nil
  114.                 self:updateFocus(nil)
  115.             elseif self.childFocus > i then
  116.                 -- Adjust focused child index
  117.                 self.childFocus = self.childFocus - 1
  118.             end
  119.         end
  120.     end
  121.  
  122.     return true
  123. end
  124.  
  125. function Container:drawChildren()
  126.     -- Repaint all children
  127.     self:eachVisible(function(child)
  128.         child:paint()
  129.     end)
  130. end
  131.  
  132. --[[
  133.  
  134.     Focus
  135.  
  136. ]]
  137.  
  138. function Container:updateFocus(newFocus)
  139.     local newIndex = self:find(newFocus)
  140.  
  141.     -- Blur previously focused child
  142.     if self.childFocus ~= nil and self.childFocus ~= newIndex then
  143.         self.children[self.childFocus]:blur()
  144.     end
  145.  
  146.     -- Set focused child
  147.     self.childFocus = newIndex
  148.  
  149.     -- Bubble up to parent
  150.     if self.parent ~= nil then
  151.         if newFocus == nil then
  152.             self.parent:updateFocus(nil)
  153.         else
  154.             self.parent:updateFocus(self)
  155.         end
  156.     end
  157. end
  158.  
  159. function Container:blur()
  160.     -- Blur previously focused child
  161.     if self.childFocus ~= nil then
  162.         self.children[self.childFocus]:blur()
  163.         self.childFocus = nil
  164.     end
  165.  
  166.     -- Call super
  167.     return ccgui.Element.blur(self)
  168. end
  169.  
  170. --[[
  171.  
  172.     Event sinking
  173.  
  174. ]]--
  175.  
  176. function Container:sinkEvent(event)
  177.     self:on(event, function(self, ...)
  178.         if self.isVisible then
  179.             local args = { ... }
  180.             self:each(function(child)
  181.                 child:trigger(event, unpack(args))
  182.             end)
  183.         end
  184.     end, self, 1000)
  185. end
  186.  
  187. function Container:sinkEventToCurrent(event)
  188.     self:on(event, function(self, ...)
  189.         if self.isVisible and self.childFocus ~= nil then
  190.             self.children[self.childFocus]:trigger(event, ...)
  191.         end
  192.     end, self, 1000)
  193. end
Advertisement
Add Comment
Please, Sign In to add comment