1.  
  2. local setmetatable = setmetatable
  3. local table = table
  4. local pairs = pairs
  5. local type = type
  6. local base = require("wibox.layout.base")
  7. local widget_base = require("wibox.widget.base")
  8.  
  9. -- XXX
  10. local print = print
  11. local assert = assert
  12.  
  13. module("center")
  14.  
  15. -- Draw the given align layout. dir describes the orientation of the layout, "x"
  16. -- means horizontal while "y" is vertical.
  17. local function draw(dir, layout, wibox, cr, width, height)
  18.     --assert(dir == "x")
  19.  
  20.     left = width/2
  21.     right = left
  22.  
  23.     if layout.second then
  24.       -- Get size of the middle widget
  25.       local w, _ = layout.second:fit(width,height)
  26.  
  27.       left = left-w/2
  28.       right = right+w/2
  29.  
  30.       base.draw_widget(wibox, cr, layout.second, left, 0, w, height)
  31.     end
  32.  
  33.     if layout.first then
  34.       local w, _ = layout.first:fit(left, height)
  35.  
  36.       base.draw_widget(wibox, cr, layout.first, 0, 0, w, height)
  37.     end
  38.  
  39.     if layout.third then
  40.       local w, _ = layout.third:fit(width-right, height)
  41.  
  42.       base.draw_widget(wibox, cr, layout.third, width-w, 0, w, height)
  43.     end
  44. end
  45.  
  46. local function widget_changed(layout, old_w, new_w)
  47.     if old_w then
  48.         old_w:disconnect_signal("widget::updated", layout._emit_updated)
  49.     end
  50.     if new_w then
  51.         widget_base.check_widget(new_w)
  52.         new_w:connect_signal("widget::updated", layout._emit_updated)
  53.     end
  54.     layout._emit_updated()
  55. end
  56.  
  57. --- Set the layout's first widget. This is the widget that is at the left/top
  58. function set_first(layout, widget)
  59.     widget_changed(layout, layout.first, widget)
  60.     layout.first = widget
  61. end
  62.  
  63. --- Set the layout's second widget. This is the centered one.
  64. function set_second(layout, widget)
  65.     widget_changed(layout, layout.second, widget)
  66.     layout.second = widget
  67. end
  68.  
  69. --- Set the layout's third widget. This is the widget that is at the right/bottom
  70. function set_third(layout, widget)
  71.     widget_changed(layout, layout.third, widget)
  72.     layout.third = widget
  73. end
  74.  
  75. function reset(layout)
  76.     for k, v in pairs({ "first", "second", "third" }) do
  77.         layout[v] = nil
  78.     end
  79.     layout:emit_signal("widget::updated")
  80. end
  81.  
  82. local function get_layout(dir)
  83.     local function draw_dir(layout, wibox, cr, width, height)
  84.         draw(dir, layout, wibox, cr, width, height)
  85.     end
  86.  
  87.     local ret = widget_base.make_widget()
  88.     ret.draw = draw_dir
  89.     ret.fit = function(box, ...) return ... end
  90.     ret.get_dir = function () return dir end
  91.     ret._emit_updated = function()
  92.         ret:emit_signal("widget::updated")
  93.     end
  94.  
  95.     for k, v in pairs(_M) do
  96.         if type(v) == "function" then
  97.             ret[k] = v
  98.         end
  99.     end
  100.  
  101.     return ret
  102. end
  103.  
  104. --- Returns a new horizontal align layout. An align layout can display up to
  105. -- three widgets. The widget set via :set_left() is left-aligned. :set_right()
  106. -- sets a widget which will be right-aligned. The remaining space between those
  107. -- two will be given to the widget set via :set_middle().
  108. function horizontal()
  109.     local ret = get_layout("x")
  110.  
  111.     ret.set_left = ret.set_first
  112.     ret.set_middle = ret.set_second
  113.     ret.set_right = ret.set_third
  114.  
  115.     return ret
  116. end
  117.  
  118. --- Returns a new vertical align layout. An align layout can display up to
  119. -- three widgets. The widget set via :set_top() is top-aligned. :set_bottom()
  120. -- sets a widget which will be bottom-aligned. The remaining space between those
  121. -- two will be given to the widget set via :set_middle().
  122. function vertical()
  123.     local ret = get_layout("y")
  124.  
  125.     ret.set_top = ret.set_first
  126.     ret.set_middle = ret.set_second
  127.     ret.set_bottom = ret.set_third
  128.  
  129.     return ret
  130. end
  131.  
  132. -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80