I just noticed a little glitch in patch #10, a fixed version is
attached.

-- 
GCS/IT/M d- s+:- a--- C++ UL+++ US UB++ P+++ L+++ E--- W+ N+ o--
K- w--- O M-- V PS+ PE- Y+ PGP+++ t+ 5 X+ R tv+ b++ DI+++ D+++ G+
e- h! r y+

    Gregor Best
From d4e448cc139887c5dc8fad59aa01c6314aced2ad Mon Sep 17 00:00:00 2001
From: Gregor Best <farha...@googlemail.com>
Date: Thu, 2 Jul 2009 02:10:32 +0200
Subject: [PATCH 10/15] awful.widget: add layouts

Signed-off-by: Gregor Best <farha...@googlemail.com>
---
 lib/awful/widget/init.lua.in              |    1 +
 lib/awful/widget/layout/horizontal.lua.in |  159 +++++++++++++++++++++++++++++
 lib/awful/widget/layout/init.lua.in       |    7 ++
 lib/awful/widget/layout/vertical.lua.in   |  104 +++++++++++++++++++
 4 files changed, 271 insertions(+), 0 deletions(-)
 create mode 100644 lib/awful/widget/layout/horizontal.lua.in
 create mode 100644 lib/awful/widget/layout/init.lua.in
 create mode 100644 lib/awful/widget/layout/vertical.lua.in

diff --git a/lib/awful/widget/init.lua.in b/lib/awful/widget/init.lua.in
index 6d4b51c..db39ed5 100644
--- a/lib/awful/widget/init.lua.in
+++ b/lib/awful/widget/init.lua.in
@@ -12,6 +12,7 @@ require("awful.widget.prompt")
 require("awful.widget.progressbar")
 require("awful.widget.graph")
 require("awful.widget.layoutbox")
+require("awful.widget.layout")
 
 --- Widget module for awful
 module("awful.widget")
diff --git a/lib/awful/widget/layout/horizontal.lua.in 
b/lib/awful/widget/layout/horizontal.lua.in
new file mode 100644
index 0000000..cbdff21
--- /dev/null
+++ b/lib/awful/widget/layout/horizontal.lua.in
@@ -0,0 +1,159 @@
+-------------------------------------------------
+-- @author Gregor Best <farha...@googlemail.com>
+-- @copyright 2009 Gregor Best
+-- @release @AWESOME_VERSION@
+-------------------------------------------------
+
+-- Grab environment
+local ipairs = ipairs
+local type = type
+local table = table
+local math = math
+local util = require("awful.util")
+
+--- Horizontal widget layout
+module("awful.widget.layout.horizontal")
+
+local function horizontal(direction, bounds, widgets, screen)
+    local geometries = { }
+
+    if direction == "rightleft" then -- reverse widget table
+        widgets = util.table.reverse(widgets)
+    end
+
+    -- we are only interested in tables and widgets
+    local keys = util.table.keys_filter(widgets, "table", "widget")
+
+    for _, k in ipairs(keys) do
+        local v = widgets[k]
+        if type(v) == "table" then
+            local layout = v["layout"] or function (...) return 
horizontal(direction, ...) end
+            local g = layout(bounds, v, screen)
+            if direction == "rightleft" then
+                g = util.table.reverse(g)
+            end
+            bounds = g.free
+            for _, v in ipairs(g) do
+                table.insert(geometries, v)
+            end
+        elseif type(v) == "widget" then
+            local g
+            if v.visible then
+                g = v:extents(screen)
+            else
+                g = {
+                    ["width"] = 0,
+                    ["height"] = 0,
+                }
+            end
+            g.ratio = 1
+            if g.height > 0 then
+                g.ratio = g.width / g.height
+            end
+            if g.width > bounds.width then
+                g.width = bounds.width
+            end
+            g.height = bounds.height
+            g.y = bounds.y
+
+            if v.resize and g.width > 0 then
+                g.width = math.floor(g.height * g.ratio)
+            end
+
+            if direction == "leftright" then
+                g.x = bounds.x
+                bounds.x = bounds.x + g.width
+            else
+                g.x = bounds.x + bounds.width - g.width
+            end
+            bounds.width = bounds.width - g.width
+
+            table.insert(geometries, g)
+        end
+    end
+
+    if direction == "rightleft" then -- reverse geometries table
+        geometries = util.table.reverse(geometries)
+    end
+
+    geometries.free = util.table.clone(bounds)
+
+    return geometries
+end
+
+function flex(bounds, widgets, screen)
+    local geometries = {
+        free = util.table.clone(bounds)
+    }
+    geometries.free.width = 0
+
+    -- we are only interested in tables and widgets
+    local keys = util.table.keys_filter(widgets, "table", "widget")
+    local nelements = 0
+
+    for _, k in ipairs(keys) do
+        local v = widgets[k]
+        if type(v) == "table" then
+            nelements = nelements + 1
+        elseif type(v) == "widget" then
+            local g = v:extents()
+            if v.resize and g.width > 0 and g.height > 0 then
+                bounds.width = bounds.width - bounds.height
+            elseif g.width > 0 and g.height > 0 then
+                nelements = nelements + 1
+            end
+        end
+    end
+
+    nelements = (nelements == 0) and 1 or nelements
+
+    local x = bounds.x
+    local width = math.floor(bounds.width / nelements)
+
+    for _, k in ipairs(util.table.keys(widgets)) do
+        local v = widgets[k]
+        if type(v) == "table" then
+            local layout = v.layout or flex
+            local g = layout(bounds, v, screen)
+            for _, v in ipairs(g) do
+                table.insert(geometries, v)
+            end
+            bounds = g.free
+        elseif type(v) == "widget" then
+            local g = v:extents(screen)
+            g.resize = v.resize
+
+            if v.resize and g.width > 0 and g.height > 0 then
+                g.width = bounds.height
+                g.height = bounds.height
+                g.x = x
+                g.y = bounds.y
+            elseif g.width > 0 and g.height > 0 then
+                g.x = x
+                g.y = bounds.y
+                g.width = width
+                g.height = bounds.height
+            else
+                g.x = 0
+                g.y = 0
+                g.width = 0
+                g.height = 0
+            end
+            x = x + g.width
+
+            table.insert(geometries, g)
+        end
+    end
+
+    return geometries
+end
+
+function leftright(...)
+    return horizontal("leftright", ...)
+end
+
+function rightleft(...)
+    return horizontal("rightleft", ...)
+end
+
+-- vim: 
filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
diff --git a/lib/awful/widget/layout/init.lua.in 
b/lib/awful/widget/layout/init.lua.in
new file mode 100644
index 0000000..f8d1d7b
--- /dev/null
+++ b/lib/awful/widget/layout/init.lua.in
@@ -0,0 +1,7 @@
+require("awful.widget.layout.horizontal")
+require("awful.widget.layout.vertical")
+
+-- Widget layouts
+module("awful.widget.layout")
+
+-- vim: 
filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
diff --git a/lib/awful/widget/layout/vertical.lua.in 
b/lib/awful/widget/layout/vertical.lua.in
new file mode 100644
index 0000000..5cdd5c8
--- /dev/null
+++ b/lib/awful/widget/layout/vertical.lua.in
@@ -0,0 +1,104 @@
+-------------------------------------------------
+-- @author Gregor Best <farha...@googlemail.com>
+-- @copyright 2009 Gregor Best
+-- @release @AWESOME_VERSION@
+-------------------------------------------------
+
+-- Grab environment
+local ipairs = ipairs
+local type = type
+local table = table
+local math = math
+local util = require("awful.util")
+
+--- Vertical widget layout
+module("awful.widget.layout.vertical")
+
+local function vertical(direction, bounds, widgets, screen)
+    local geometries = {
+        free = util.table.clone(bounds)
+    }
+
+    if direction == "bottomup" then -- reverse widget table
+        widgets = util.table.reverse(widgets)
+    end
+
+    -- we are only interested in tables and widgets
+    local keys = util.table.keys_filter(widgets, "table", "widget")
+    local nelements = #keys
+    local height = math.floor(bounds.height / nelements)
+
+    for _, k in ipairs(keys) do
+        local v = widgets[k]
+        if type(v) == "table" then
+            local layout = v["layout"] or function (...) return 
vertical(direction, ...) end
+            -- we need to modify the height a bit because vertical layouts 
always span the
+            -- whole height
+            nbounds = util.table.clone(bounds)
+            nbounds.height = height
+            local g = layout(nbounds, v, screen)
+            for _, v in ipairs(g) do
+                table.insert(geometries, v)
+            end
+            bounds.y = bounds.y + height
+        elseif type(v) == "widget" then
+            local g
+            if v.visible then
+                g = v:extents(screen)
+            else
+                g = {
+                    ["width"] = 0,
+                    ["height"] = 0
+                }
+            end
+
+            g.ratio = 1
+            if g.height > 0 and g.width > 0 then
+                g.ratio = g.width / g.height
+            end
+            g.height = height
+            if v.resize then
+                g.width = g.height * g.ratio
+            end
+            g.width = math.min(g.width, bounds.width)
+            geometries.free.x = bounds.x + math.max(geometries.free.x - 
bounds.x, g.width)
+            g.x = bounds.x
+
+            if direction == "topdown" then
+                g.y = bounds.y
+                bounds.y = bounds.y + g.height
+            else
+                g.y = bounds.y + bounds.height - g.height
+            end
+            bounds.height = bounds.height - g.height
+
+            table.insert(geometries, g)
+        end
+    end
+
+    if direction == "bottomup" then
+        geometries = util.table.reverse(geometries)
+    end
+
+    local maxw = 0
+    local maxx = 0
+    for _, v in ipairs(geometries) do
+        if v.width > maxw then maxw = v.width end
+        if v.x > maxx then maxx = v.x end
+    end
+
+    geometries.free.width = geometries.free.width - maxw
+    geometries.free.x = geometries.free.x + maxw
+
+    geometries.free.height = nelements * height
+
+    return geometries
+end
+
+function topdown(...)
+    return vertical("topdown", ...)
+end
+
+function bottomup(...)
+    return vertical("bottomup", ...)
+end
-- 
1.6.3.3

Attachment: pgpLKQ7oVsn7J.pgp
Description: PGP signature

Reply via email to