MattiasBuelens

CCGUI flow

Jul 5th, 2012
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.26 KB | None | 0 0
  1. --[[
  2.  
  3.     ComputerCraft GUI
  4.     Flow container
  5.  
  6. --]]
  7.  
  8. ccgui = ccgui or {}
  9.  
  10. local FlowContainer = common.newClass({
  11.     -- Orientation
  12.     horizontal = false,
  13.     -- Spacing between children
  14.     spacing = 0
  15. }, ccgui.Container)
  16. ccgui.FlowContainer = FlowContainer
  17.  
  18. function FlowContainer:init()
  19.     ccgui.Container.init(self)
  20.  
  21.     -- Orientation
  22.     self.horizontal = not not self.horizontal
  23. end
  24.  
  25. function FlowContainer:calcSize(size)
  26.     -- Get inner box
  27.     local cbox = self:inner(size)
  28.  
  29.     -- Flow dimension
  30.     local flowDim = (self.horizontal and "w") or "h"
  31.     -- Fixed dimension
  32.     local fixedDim = (self.horizontal and "h") or "w"
  33.  
  34.     -- Flow size
  35.     local flowSize = 0
  36.     -- Remaining flow size
  37.     local remaining = cbox[flowDim]
  38.     -- Fixed size
  39.     local fixedSize = cbox[fixedDim]
  40.     -- Maximum fixed size
  41.     local maxFixed = 0
  42.  
  43.     -- Children to be stretched
  44.     local stretchChildren = {}
  45.  
  46.     -- Update sizes of children
  47.     self:eachVisible(function(child, i, isLast)
  48.         -- No spacing on last child
  49.         local spacing = (not isLast and self.spacing) or 0
  50.         -- Handle stretched children later
  51.         if child.stretch then
  52.             -- Remove spacing from remaining
  53.             -- and add to flow size
  54.             flowSize = flowSize + spacing
  55.             remaining = remaining - spacing
  56.             -- Add to stretched children
  57.             table.insert(stretchChildren, child)
  58.             return
  59.         end
  60.         -- Get child size
  61.         child:calcSize(ccgui.Rectangle:new{
  62.             [flowDim] = remaining,
  63.             [fixedDim] = fixedSize
  64.         })
  65.         -- Remove child size and spacing from remaining
  66.         -- and add to flow size
  67.         local childSize = child.size[flowDim] + spacing
  68.         flowSize = flowSize + childSize
  69.         remaining = remaining - childSize
  70.         -- Update maximum fixed size
  71.         maxFixed = math.max(maxFixed, child.size[fixedDim])
  72.     end)
  73.  
  74.     -- Divide remaining size over stretched children
  75.     local stretchSize = math.floor(remaining / #stretchChildren)
  76.     local firstStretch = stretchSize + (remaining % #stretchChildren)
  77.     for i,child in ipairs(stretchChildren) do
  78.         local childSize = (i == 1 and firstStretch) or stretchSize
  79.         -- Get child size
  80.         child:calcSize(ccgui.Rectangle:new{
  81.             [flowDim] = childSize,
  82.             [fixedDim] = fixedSize
  83.         })
  84.         -- Force flow size
  85.         child.size[flowDim] = childSize
  86.         -- Add child size to flow size
  87.         flowSize = flowSize + childSize
  88.         -- Update maximum fixed size
  89.         maxFixed = math.max(maxFixed, child.size[fixedDim])
  90.     end
  91.  
  92.     -- Enforce fixed size
  93.     self:eachVisible(function(child, i)
  94.         child.size[fixedDim] = maxFixed
  95.     end)
  96.  
  97.     -- Get children size box
  98.     local bbox = ccgui.Rectangle:new{
  99.         [flowDim] = flowSize,
  100.         [fixedDim] = maxFixed
  101.     }
  102.     -- Use outer size box
  103.     self.size = self:outer(bbox)
  104. end
  105.  
  106. function FlowContainer:calcLayout(bbox)
  107.     -- Get inner box for children bounding box
  108.     local cbox = self:inner(bbox)
  109.  
  110.     -- Collect old child bounding boxes
  111.     local childBboxes = {}
  112.     self:eachVisible(function(child, i)
  113.         childBboxes[i] = child.bbox
  114.     end)
  115.  
  116.     -- Flow coordinate
  117.     local flowCoord = (self.horizontal and "x") or "y"
  118.     -- Fixed coordinate
  119.     local fixedCoord = (self.horizontal and "y") or "x"
  120.     -- Flow dimension
  121.     local flowDim = (self.horizontal and "w") or "h"
  122.     -- Fixed dimension
  123.     local fixedDim = (self.horizontal and "h") or "w"
  124.  
  125.     -- Flow position
  126.     local flowPos = cbox[flowCoord]
  127.     -- Fixed size
  128.     local fixedPos, fixedSize = cbox[fixedCoord], cbox[fixedDim]
  129.  
  130.     -- Update layout of children
  131.     self:eachVisible(function(child, i, isLast)
  132.         local spacing = (not isLast and self.spacing) or 0
  133.         -- Get child bounding box
  134.         child:calcLayout(ccgui.Rectangle:new{
  135.             [flowCoord] = flowPos,
  136.             [fixedCoord] = fixedPos,
  137.             [flowDim] = child.size[flowDim],
  138.             [fixedDim] = fixedSize
  139.         })
  140.         -- Force size
  141.         child.bbox[flowDim] = child.size[flowDim]
  142.         child.bbox[fixedDim] = fixedSize
  143.         -- Add child size and spacing to flow position
  144.         local childSize = child.bbox[flowDim] + spacing
  145.         flowPos = flowPos + childSize
  146.     end)
  147.  
  148.     -- Check for child bounding box changes
  149.     --[[local childBboxChanged = false
  150.     self:eachVisible(function(child, i)
  151.         local oldBbox = childBboxes[i]
  152.         if oldBbox == nil or oldBbox ~= child.bbox then
  153.             -- Bounding box changed, repaint child and container
  154.             child:markRepaint()
  155.             childBboxChanged = true
  156.         end
  157.     end)
  158.     if childBboxChanged then
  159.         self:markRepaint()
  160.     end]]--
  161.  
  162.     -- Use given bounding box
  163.     self.bbox = bbox
  164. end
Advertisement
Add Comment
Please, Sign In to add comment