diff options
author | Matthias Richter <vrld@vrld.org> | 2012-05-09 21:27:45 +0200 |
---|---|---|
committer | Matthias Richter <vrld@vrld.org> | 2012-05-09 21:27:45 +0200 |
commit | adc78875875a64d40b4cf65a8618fb49a77e8080 (patch) | |
tree | 132bc89a60cf3bc60cf9acacdf0c31aad6df969e /group.lua | |
parent | 7b1b6e4176829d4c9d897821c8a2d51da78e0243 (diff) | |
download | Quickie-adc78875875a64d40b4cf65a8618fb49a77e8080.tar.gz Quickie-adc78875875a64d40b4cf65a8618fb49a77e8080.tar.bz2 Quickie-adc78875875a64d40b4cf65a8618fb49a77e8080.tar.xz Quickie-adc78875875a64d40b4cf65a8618fb49a77e8080.zip |
Mega update: Auto layout, code cleanup, api change.
Basically half a rewrite.
Diffstat (limited to 'group.lua')
-rw-r--r-- | group.lua | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/group.lua b/group.lua new file mode 100644 index 0000000..50e413e --- /dev/null +++ b/group.lua @@ -0,0 +1,143 @@ +--[[ +Copyright (c) 2012 Matthias Richter + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +Except as contained in this notice, the name(s) of the above copyright holders +shall not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +]]-- + +local stack = {n = 0} +local default = { + pos = {0,0}, + grow = {0,0}, + spacing = 2, + size = {100, 30}, + upper_left = {0,0}, + lower_right = {0,0}, +} +local current = default + +local Grow = { + none = { 0, 0}, + up = { 0, -1}, + down = { 0, 1}, + left = {-1, 0}, + right = { 1, 0} +} + +-- {grow = grow, spacing = spacing, size = size, pos = pos} +local function push(info) + local grow = info.grow or "none" + local spacing = info.spacing or default.spacing + + local size = { + info.size and info.size[1] or current.size[1], + info.size and info.size[2] or current.size[2] + } + + local pos = {current.pos[1], current.pos[2]} + if info.pos then + pos[1] = pos[1] + (info.pos[1] or 0) + pos[2] = pos[2] + (info.pos[2] or 0) + end + + assert(size, "Size neither specified nor derivable from parent group.") + assert(pos, "Position neither specified nor derivable from parent group.") + grow = assert(Grow[grow], "Invalid grow: " .. tostring(grow)) + + current = { + pos = pos, + grow = grow, + size = size, + spacing = spacing, + upper_left = { math.huge, math.huge}, + lower_right = {-math.huge, -math.huge}, + } + stack.n = stack.n + 1 + stack[stack.n] = current +end + +local function advance(pos, size) + current.upper_left[1] = math.min(current.upper_left[1], pos[1]) + current.upper_left[2] = math.min(current.upper_left[2], pos[2]) + current.lower_right[1] = math.max(current.lower_right[1], pos[1] + size[1]) + current.lower_right[2] = math.max(current.lower_right[2], pos[2] + size[2]) + + if current.grow[1] ~= 0 then + current.pos[1] = pos[1] + current.grow[1] * (size[1] + current.spacing) + end + if current.grow[2] ~= 0 then + current.pos[2] = pos[2] + current.grow[2] * (size[2] + current.spacing) + end + return pos, size +end + +local function getRect(pos, size) + pos = {pos and pos[1] or 0, pos and pos[2] or 0} + size = {size and size[1] or current.size[1], size and size[2] or current.size[2]} + + -- growing left/up: update current position to account for differnt size + if current.grow[1] < 0 and current.size[1] ~= size[1] then + current.pos[1] = current.pos[1] + (current.size[1] - size[1]) + end + if current.grow[2] < 0 and current.size[2] ~= size[2] then + current.pos[2] = current.pos[2] - (current.size[2] - size[2]) + end + + pos[1] = pos[1] + current.pos[1] + pos[2] = pos[2] + current.pos[2] + + return advance(pos, size) +end + +local function pop() + assert(stack.n > 0, "Group stack is empty.") + stack.n = stack.n - 1 + local child = current + current = stack[stack.n] or default + + local size = { + child.lower_right[1] - math.max(child.upper_left[1], current.pos[1]), + child.lower_right[2] - math.max(child.upper_left[2], current.pos[2]) + } + advance(current.pos, size) +end + +local function beginFrame() + current = default + stack.n = 0 +end + +local function endFrame() + -- future use? +end + +return setmetatable({ + push = push, + pop = pop, + getRect = getRect, + advance = advance, + beginFrame = beginFrame, + endFrame = endFrame, + default = default, +}, {__index = function(_,k) + return ({size = current.size, pos = current.pos})[k] +end}) |