commit
15ae2ad7d7
|
@ -0,0 +1,935 @@
|
|||
---------------------------------------------------------------------------
|
||||
--- A grid layout.
|
||||
--
|
||||
-- Widgets spanning several columns or rows cannot be included using the
|
||||
-- declarative system.
|
||||
-- Instead, create the grid layout and call the `add_widget_at` method.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_imperative_EXAMPLE@
|
||||
--
|
||||
-- Using the declarative system, widgets are automatically added next to each
|
||||
-- other spanning only one cell.
|
||||
--
|
||||
--@DOC_wibox_layout_defaults_grid_EXAMPLE@
|
||||
-- @author getzze
|
||||
-- @copyright 2017 getzze
|
||||
-- @classmod wibox.layout.grid
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
local setmetatable = setmetatable
|
||||
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
|
||||
local table = table
|
||||
local pairs = pairs
|
||||
local ipairs = ipairs
|
||||
local math = math
|
||||
local util = require("awful.util")
|
||||
local base = require("wibox.widget.base")
|
||||
|
||||
local grid = { mt = {} }
|
||||
|
||||
local properties = {
|
||||
"orientation", "superpose",
|
||||
"forced_num_rows", "forced_num_cols",
|
||||
"min_cols_size", "min_rows_size",
|
||||
}
|
||||
|
||||
local dir_properties = { "spacing", "homogeneous", "expand" }
|
||||
|
||||
|
||||
|
||||
--- Set the preferred orientation of the grid layout.
|
||||
--
|
||||
-- Allowed values are "horizontal" and "vertical".
|
||||
-- When calling `get_next_empty`, empty cells are browsed differently:
|
||||
--
|
||||
-- * for "horizontal", the grid can be extended horizontally. The current
|
||||
-- column is filled first; if no empty cell is found up to `forced_num_rows`,
|
||||
-- the next column is filled, creating it if it does not exist.
|
||||
--
|
||||
-- * for "vertical", the grid can be extended vertically. The current row is
|
||||
-- filled first; if no empty cell is found up to `forced_num_cols`, the next
|
||||
-- row is filled, creating it if it does not exist.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_orientation_EXAMPLE@
|
||||
-- @param[opt="vertical"] string Preferred orientation: "horizontal" or "vertical".
|
||||
-- @property orientation
|
||||
|
||||
--- Allow to superpose widgets in the same cell.
|
||||
-- If false, check before adding a new widget if it will superpose with another
|
||||
-- widget and prevent from adding it.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_superpose_EXAMPLE@
|
||||
-- @param[opt=false] boolean
|
||||
-- @property superpose
|
||||
|
||||
--- Force the number of rows of the layout.
|
||||
-- @property forced_num_rows
|
||||
-- @tparam[opt=nil] number|nil number Forced number of rows (`nil` for automatic).
|
||||
|
||||
--- Force the number of columns of the layout.
|
||||
-- @property forced_num_cols
|
||||
-- @tparam[opt=nil] number|nil number Forced number of columns (`nil` for automatic).
|
||||
|
||||
--- Set the minimum size for the columns.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_min_size_EXAMPLE@
|
||||
-- @param[opt=0] number Minimum size of the columns.
|
||||
-- @property min_cols_size
|
||||
|
||||
--- Set the minimum size for the rows.
|
||||
-- @param[opt=0] number Minimum size of the rows.
|
||||
-- @property min_rows_size
|
||||
|
||||
--- The spacing between columns.
|
||||
--
|
||||
-- see `spacing`
|
||||
--
|
||||
-- @param[opt=0] number The spacing
|
||||
-- @property horizontal_spacing
|
||||
|
||||
--- The spacing between rows.
|
||||
--
|
||||
-- see `spacing`
|
||||
--
|
||||
-- @param[opt=0] number The spacing
|
||||
-- @property vertical_spacing
|
||||
|
||||
--- The spacing between rows and columns.
|
||||
-- Set both `horizontal_spacing` and `vertical_spacing` to the same value.
|
||||
-- Get the value `horizontal_spacing` or `vertical_spacing` defined by the
|
||||
-- preferred `orientation`.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_spacing_EXAMPLE@
|
||||
-- @param[opt=0] number The spacing
|
||||
-- @property spacing
|
||||
|
||||
--- Controls if the columns are expanded to use all the available width.
|
||||
--
|
||||
-- see `expand`
|
||||
--
|
||||
-- @param[opt=false] boolean Expand the grid into the available space
|
||||
-- @property horizontal_expand
|
||||
|
||||
--- Controls if the rows are expanded to use all the available height.
|
||||
--
|
||||
-- see `expand`
|
||||
--
|
||||
-- @param[opt=false] boolean Expand the grid into the available space
|
||||
-- @property vertical_expand
|
||||
|
||||
--- Controls if the columns/rows are expanded to use all the available space.
|
||||
-- Set both `horizontal_expand` and `vertical_expand` to the same value.
|
||||
-- Get the value `horizontal_expand` or `vertical_expand` defined by the
|
||||
-- preferred `orientation`.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_expand_EXAMPLE@
|
||||
-- @param[opt=false] boolean Expand the grid into the available space
|
||||
-- @property expand
|
||||
|
||||
--- Controls if the columns all have the same width or if the width of each
|
||||
-- column depends on the content.
|
||||
--
|
||||
-- see `homogeneous`
|
||||
--
|
||||
-- @param[opt=true] boolean All the columns have the same width.
|
||||
-- @property horizontal_homogeneous
|
||||
|
||||
--- Controls if the rows all have the same height or if the height of each row
|
||||
-- depends on the content.
|
||||
--
|
||||
-- see `homogeneous`
|
||||
--
|
||||
-- @param[opt=true] boolean All the rows have the same height.
|
||||
-- @property vertical_homogeneous
|
||||
|
||||
--- Controls if the columns/rows all have the same size or if the size depends
|
||||
-- on the content.
|
||||
-- Set both `horizontal_homogeneous` and `vertical_homogeneous` to the same value.
|
||||
-- Get the value `horizontal_homogeneous` or `vertical_homogeneous` defined
|
||||
-- by the preferred `orientation`.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_expand_EXAMPLE@
|
||||
-- @param[opt=true] boolean All the columns/rows have the same size.
|
||||
-- @property homogeneous
|
||||
|
||||
--- Child widget position. Return of `get_widget_position`.
|
||||
-- @field row Top row index
|
||||
-- @field col Left column index
|
||||
-- @field row_span Number of rows to span
|
||||
-- @field col_span Number of columns to span
|
||||
-- @table position
|
||||
|
||||
-- Return the maximum value of a table.
|
||||
local function max_value(t)
|
||||
local m = 0
|
||||
for _,v in ipairs(t) do
|
||||
if m < v then m = v end
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
-- Return the sum of the values in the table.
|
||||
local function sum_values(t)
|
||||
local m = 0
|
||||
for _,v in ipairs(t) do
|
||||
m = m + v
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
|
||||
-- Find a widget in a widget_table, by matching the coordinates.
|
||||
-- Using the `row`:`col` coordinates, and the spans `row_span` and `col_span`
|
||||
-- @tparam table widgets_table Table of the widgets present in the grid
|
||||
-- @tparam number row Row number for the top left corner of the widget
|
||||
-- @tparam number col Column number for the top left corner of the widget
|
||||
-- @tparam number row_span The number of rows the widget spans (default to 1)
|
||||
-- @tparam number col_span The number of columns the widget spans (default to 1)
|
||||
-- @treturn table Table of index of widget_table
|
||||
local function find_widgets_at(widgets_table, row, col, row_span, col_span)
|
||||
if not row or row < 1 or not col or col < 1 then return nil end
|
||||
row_span = (row_span and row_span > 0) and row_span or 1
|
||||
col_span = (col_span and col_span > 0) and col_span or 1
|
||||
local ret = {}
|
||||
for index, data in ipairs(widgets_table) do
|
||||
-- If one rectangular widget is on left side of other
|
||||
local test_horizontal = not (row > data.row + data.row_span - 1
|
||||
or data.row > row + row_span - 1)
|
||||
-- If one rectangular widget is above other
|
||||
local test_vertical = not (col > data.col + data.col_span - 1
|
||||
or data.col > col + col_span - 1)
|
||||
if test_horizontal and test_vertical then
|
||||
table.insert(ret, index)
|
||||
end
|
||||
end
|
||||
-- reverse sort for safe removal of indices
|
||||
table.sort(ret, function(a,b) return a>b end)
|
||||
return #ret > 0 and ret or nil
|
||||
end
|
||||
|
||||
|
||||
-- Find a widget in a widget_table, by matching the object.
|
||||
-- @tparam table widgets_table Table of the widgets present in the grid
|
||||
-- @param widget The widget to find
|
||||
-- @treturn number|nil The index of the widget in widget_table, `nil` if not found
|
||||
local function find_widget(widgets_table, widget)
|
||||
for index, data in ipairs(widgets_table) do
|
||||
if data.widget == widget then
|
||||
return index
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the number of rows and columns occupied by the widgets in the grid.
|
||||
-- @treturn number,number The number of rows and columns
|
||||
function grid:get_dimension()
|
||||
return self._private.num_rows, self._private.num_cols
|
||||
end
|
||||
|
||||
-- Update the number of rows and columns occupied by the widgets in the grid.
|
||||
local function update_dimension(self)
|
||||
local num_rows, num_cols = 0, 0
|
||||
if self._private.forced_num_rows then
|
||||
num_rows = self._private.forced_num_rows
|
||||
end
|
||||
if self._private.forced_num_cols then
|
||||
num_cols = self._private.forced_num_cols
|
||||
end
|
||||
|
||||
for _, data in ipairs(self._private.widgets) do
|
||||
num_rows = math.max(num_rows, data.row + data.row_span - 1)
|
||||
num_cols = math.max(num_cols, data.col + data.col_span - 1)
|
||||
end
|
||||
self._private.num_rows = num_rows
|
||||
self._private.num_cols = num_cols
|
||||
end
|
||||
|
||||
|
||||
--- Find the next available cell to insert a widget.
|
||||
-- The grid is browsed according to the `orientation`.
|
||||
-- @tparam[opt=1] number hint_row The row coordinate of the last occupied cell.
|
||||
-- @tparam[opt=1] number hint_column The column coordinate of the last occupied cell.
|
||||
-- @return number,number The row,column coordinate of the next empty cell
|
||||
function grid:get_next_empty(hint_row, hint_column)
|
||||
local row = (hint_row and hint_row > 0) and hint_row or 1
|
||||
local column = (hint_column and hint_column > 0) and hint_column or 1
|
||||
|
||||
local next_field
|
||||
if self._private.orientation == "vertical" then
|
||||
next_field = function(x, y)
|
||||
if y < self._private.num_cols then
|
||||
return x, y+1
|
||||
end
|
||||
return x+1,1
|
||||
end
|
||||
elseif self._private.orientation == "horizontal" then
|
||||
next_field = function(x, y)
|
||||
if x < self._private.num_rows then
|
||||
return x+1, y
|
||||
end
|
||||
return 1,y+1
|
||||
end
|
||||
end
|
||||
while true do
|
||||
if find_widgets_at(self._private.widgets, row, column, 1, 1) == nil then
|
||||
return row, column
|
||||
end
|
||||
row, column = next_field(row, column)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Add some widgets to the given grid layout.
|
||||
-- The widgets are assumed to span one cell
|
||||
-- @param ... Widgets that should be added (must at least be one)
|
||||
function grid:add(...)
|
||||
local args = { n=select('#', ...), ... }
|
||||
assert(args.n > 0, "need at least one widget to add")
|
||||
local row, column
|
||||
for i=1, args.n do
|
||||
local w = args[i]
|
||||
-- Get the next empty coordinate to insert the widget
|
||||
row, column = self:get_next_empty(row, column)
|
||||
self:add_widget_at(w, row, column, 1, 1)
|
||||
end
|
||||
end
|
||||
|
||||
--- Add a widget to the grid layout at specific coordinate.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_add_EXAMPLE@
|
||||
-- @param child Widget that should be added
|
||||
-- @tparam number row Row number for the top left corner of the widget
|
||||
-- @tparam number col Column number for the top left corner of the widget
|
||||
-- @tparam[opt=1] number row_span The number of rows the widget spans.
|
||||
-- @tparam[opt=1] number col_span The number of columns the widget spans.
|
||||
-- @treturn boolean index If the operation is successful
|
||||
function grid:add_widget_at(child, row, col, row_span, col_span)
|
||||
if not row or row < 1 or not col or col < 1 then return false end
|
||||
row_span = (row_span and row_span > 0) and row_span or 1
|
||||
col_span = (col_span and col_span > 0) and col_span or 1
|
||||
|
||||
-- check if the object is a widget
|
||||
base.check_widget(child)
|
||||
|
||||
-- test if the new widget superpose with existing ones
|
||||
local superpose = find_widgets_at(
|
||||
self._private.widgets, row, col, row_span, col_span
|
||||
)
|
||||
|
||||
if not self._private.superpose and superpose then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Add grid information attached to the widget
|
||||
local child_data = {
|
||||
widget = child,
|
||||
row = row,
|
||||
col = col,
|
||||
row_span = row_span,
|
||||
col_span = col_span
|
||||
}
|
||||
table.insert(self._private.widgets, child_data)
|
||||
|
||||
-- Update the row and column numbers
|
||||
self._private.num_rows = math.max(self._private.num_rows, row + row_span - 1)
|
||||
self._private.num_cols = math.max(self._private.num_cols, col + col_span - 1)
|
||||
|
||||
self:emit_signal("widget::layout_changed")
|
||||
self:emit_signal("widget::redraw_needed")
|
||||
return true
|
||||
end
|
||||
|
||||
--- Remove one or more widgets from the layout.
|
||||
-- @param ... Widgets that should be removed (must at least be one)
|
||||
-- @treturn boolean If the operation is successful
|
||||
function grid:remove(...)
|
||||
local args = { ... }
|
||||
local ret = false
|
||||
for _, rem_widget in ipairs(args) do
|
||||
local index = find_widget(self._private.widgets, rem_widget)
|
||||
if index ~= nil then
|
||||
table.remove(self._private.widgets, index)
|
||||
ret = true
|
||||
end
|
||||
end
|
||||
if ret then
|
||||
-- Recalculate num_rows and num_cols
|
||||
update_dimension(self)
|
||||
self:emit_signal("widget::layout_changed")
|
||||
self:emit_signal("widget::redraw_needed")
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
--- Remove widgets at the coordinates.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_remove_EXAMPLE@
|
||||
-- @tparam number row The row coordinate of the widget to remove
|
||||
-- @tparam number col The column coordinate of the widget to remove
|
||||
-- @tparam[opt=1] number row_span The number of rows the area to remove spans.
|
||||
-- @tparam[opt=1] number col_span The number of columns the area to remove spans.
|
||||
-- @treturn boolean If the operation is successful (widgets found)
|
||||
function grid:remove_widgets_at(row, col, row_span, col_span)
|
||||
local widget_indices = find_widgets_at(
|
||||
self._private.widgets, row, col, row_span, col_span
|
||||
)
|
||||
if widget_indices == nil then return false end
|
||||
|
||||
for _,index in ipairs(widget_indices) do
|
||||
table.remove(self._private.widgets, index)
|
||||
end
|
||||
-- Recalculate num_rows and num_cols
|
||||
update_dimension(self)
|
||||
self:emit_signal("widget::layout_changed")
|
||||
self:emit_signal("widget::redraw_needed")
|
||||
return true
|
||||
end
|
||||
|
||||
--- Return the coordinates of the widget.
|
||||
-- @param widget The widget
|
||||
-- @treturn table The `position` table of the coordinates in the grid, with
|
||||
-- fields `row`, `col`, `row_span` and `col_span`.
|
||||
function grid:get_widget_position(widget)
|
||||
local index = find_widget(self._private.widgets, widget)
|
||||
if index == nil then return nil end
|
||||
local data = self._private.widgets[index]
|
||||
local ret = {}
|
||||
ret["row"] = data.row
|
||||
ret["col"] = data.col
|
||||
ret["row_span"] = data.row_span
|
||||
ret["col_span"] = data.col_span
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
--- Return the widgets at the coordinates.
|
||||
-- @tparam number row The row coordinate of the widget
|
||||
-- @tparam number col The column coordinate of the widget
|
||||
-- @tparam[opt=1] number row_span The number of rows to span.
|
||||
-- @tparam[opt=1] number col_span The number of columns to span.
|
||||
-- @treturn table The widget(s) found at the specific coordinates, nil if no widgets found
|
||||
function grid:get_widgets_at(row, col, row_span, col_span)
|
||||
local widget_indices = find_widgets_at(
|
||||
self._private.widgets, row, col, row_span, col_span
|
||||
)
|
||||
|
||||
if widget_indices == nil then return nil end
|
||||
|
||||
local ret = {}
|
||||
for _,index in ipairs(widget_indices) do
|
||||
local data = self._private.widgets[index]
|
||||
table.insert(ret, data.widget)
|
||||
end
|
||||
|
||||
return #ret > 0 and ret or nil
|
||||
end
|
||||
|
||||
--- Replace old widget by new widget, spanning the same columns and rows.
|
||||
-- @param old The widget to remove
|
||||
-- @param new The widget to add
|
||||
-- @treturn boolean If the operation is successful (widget found)
|
||||
function grid:replace_widget(old, new)
|
||||
-- check if the new object is a widget
|
||||
local status = pcall(function () base.check_widget(new) end)
|
||||
if not status then return false end
|
||||
-- find the old widget
|
||||
local index = find_widget(self._private.widgets, old)
|
||||
if index == nil then return false end
|
||||
|
||||
-- get old widget position
|
||||
local data = self._private.widgets[index]
|
||||
local row, col, row_span, col_span = data.row, data.col, data.row_span, data.col_span
|
||||
|
||||
table.remove(self._private.widgets, index)
|
||||
return self:add_widget_at(new, row, col, row_span, col_span)
|
||||
end
|
||||
|
||||
-- Update position of the widgets when inserting, adding or removing a row or a column.
|
||||
-- @tparam table table_widgets Table of widgets
|
||||
-- @tparam string orientation Orientation of the line: "horizontal" -> column, "vertical" -> row
|
||||
-- @tparam number index Index of the line
|
||||
-- @tparam string mode insert, extend or remove
|
||||
-- @tparam boolean after Add the line after the index instead of inserting it before.
|
||||
-- @tparam boolean extend Extend the line at index instead of inserting an empty line.
|
||||
local function update_widgets_position(table_widgets, orientation, index, mode)
|
||||
local t = orientation == "horizontal" and "col" or "row"
|
||||
local to_remove = {}
|
||||
-- inc : Index increment or decrement
|
||||
-- first : Offset index for top-left cell of the widgets to shift
|
||||
-- last : Offset index for bottom-right cell of the widgets to resize
|
||||
local inc, first, last
|
||||
if mode == "remove" then
|
||||
inc, first, last = -1, 1, 1
|
||||
elseif mode == "insert" then
|
||||
inc, first, last = 1, 0, 0
|
||||
elseif mode == "extend" then
|
||||
inc, first, last = 1, 1, 0
|
||||
else
|
||||
return
|
||||
end
|
||||
for i, data in ipairs(table_widgets) do
|
||||
-- single widget in the line
|
||||
if mode == "remove" and data[t] == index and data[t .. "_span"] == 1 then
|
||||
table.insert(to_remove, i)
|
||||
-- widgets to shift
|
||||
elseif data[t] >= index + first then
|
||||
data[t] = data[t] + inc
|
||||
-- widgets to resize
|
||||
elseif data[t] + data[t .. "_span"] - 1 >= index + last then
|
||||
data[t .. "_span"] = data[t .. "_span"] + inc
|
||||
end
|
||||
end
|
||||
if mode == "remove" then
|
||||
-- reverse sort to remove
|
||||
table.sort(to_remove, function(a,b) return a>b end)
|
||||
-- Remove widgets
|
||||
for _,i in ipairs(to_remove) do
|
||||
table.remove(table_widgets, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Insert column at index.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_insert_column_EXAMPLE@
|
||||
-- @tparam number|nil index Insert the new column at index. If `nil`, the column is added at the end.
|
||||
-- @treturn number The index of the inserted column
|
||||
function grid:insert_column(index)
|
||||
if index == nil or index > self._private.num_cols + 1 or index < 1 then
|
||||
index = self._private.num_cols + 1
|
||||
end
|
||||
-- Update widget positions
|
||||
update_widgets_position(self._private.widgets, "horizontal", index, "insert")
|
||||
-- Recalculate number of rows and columns
|
||||
self._private.num_cols = self._private.num_cols + 1
|
||||
return index
|
||||
end
|
||||
|
||||
--- Extend column at index.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_extend_column_EXAMPLE@
|
||||
-- @tparam number|nil index Extend the column at index. If `nil`, the last column is extended.
|
||||
-- @treturn number The index of the extended column
|
||||
function grid:extend_column(index)
|
||||
if index == nil or index > self._private.num_cols or index < 1 then
|
||||
index = self._private.num_cols
|
||||
end
|
||||
-- Update widget positions
|
||||
update_widgets_position(self._private.widgets, "horizontal", index, "extend")
|
||||
-- Recalculate number of rows and columns
|
||||
self._private.num_cols = self._private.num_cols + 1
|
||||
return index
|
||||
end
|
||||
|
||||
--- Remove column at index.
|
||||
--
|
||||
--@DOC_wibox_layout_grid_remove_column_EXAMPLE@
|
||||
-- @tparam number|nil index Remove column at index. If `nil`, the last column is removed.
|
||||
-- @treturn number The index of the removed column
|
||||
function grid:remove_column(index)
|
||||
if index == nil or index > self._private.num_cols or index < 1 then
|
||||
index = self._private.num_cols
|
||||
end
|
||||
-- Update widget positions
|
||||
update_widgets_position(self._private.widgets, "horizontal", index, "remove")
|
||||
-- Recalculate number of rows and columns
|
||||
update_dimension(self)
|
||||
return index
|
||||
end
|
||||
|
||||
--- Insert row at index.
|
||||
--
|
||||
-- see `insert_column`
|
||||
-- @tparam number|nil index Insert the new row at index. If `nil`, the row is added at the end.
|
||||
-- @treturn number The index of the inserted row
|
||||
function grid:insert_row(index)
|
||||
if index == nil or index > self._private.num_rows + 1 or index < 1 then
|
||||
index = self._private.num_rows + 1
|
||||
end
|
||||
-- Update widget positions
|
||||
update_widgets_position(self._private.widgets, "vertical", index, "insert")
|
||||
-- Recalculate number of rows and columns
|
||||
self._private.num_rows = self._private.num_rows + 1
|
||||
return index
|
||||
end
|
||||
|
||||
--- Extend row at index.
|
||||
--
|
||||
-- see `extend_column`
|
||||
-- @tparam number|nil index Extend the row at index. If `nil`, the last row is extended.
|
||||
-- @treturn number The index of the extended row
|
||||
function grid:extend_row(index)
|
||||
if index == nil or index > self._private.num_rows or index < 1 then
|
||||
index = self._private.num_rows
|
||||
end
|
||||
-- Update widget positions
|
||||
update_widgets_position(self._private.widgets, "vertical", index, "extend")
|
||||
-- Recalculate number of rows and columns
|
||||
self._private.num_rows = self._private.num_rows + 1
|
||||
return index
|
||||
end
|
||||
|
||||
--- Remove row at index.
|
||||
--
|
||||
-- see `remove_column`
|
||||
-- @tparam number|nil index Remove row at index. If `nil`, the last row is removed.
|
||||
-- @treturn number The index of the removed row
|
||||
function grid:remove_row(index)
|
||||
if index == nil or index > self._private.num_rows or index < 1 then
|
||||
index = self._private.num_rows
|
||||
end
|
||||
-- Update widget positions
|
||||
update_widgets_position(self._private.widgets, "vertical", index, "remove")
|
||||
-- Recalculate number of rows and columns
|
||||
update_dimension(self)
|
||||
return index
|
||||
end
|
||||
|
||||
|
||||
-- Return list of children
|
||||
function grid:get_children()
|
||||
local ret = {}
|
||||
for _, data in ipairs(self._private.widgets) do
|
||||
table.insert(ret, data.widget)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
-- Add list of children to the layout
|
||||
function grid:set_children(children)
|
||||
self:reset()
|
||||
if #children > 0 then
|
||||
self:add(unpack(children))
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the preferred orientation of the grid layout.
|
||||
function grid:set_orientation(val)
|
||||
if self._private.orientation ~= val and (val == "horizontal" or val == "vertical") then
|
||||
self._private.orientation = val
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the minimum size for the columns.
|
||||
function grid:set_min_cols_size(val)
|
||||
if self._private.min_cols_size ~= val and val >= 0 then
|
||||
self._private.min_cols_size = val
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the minimum size for the rows.
|
||||
function grid:set_min_rows_size(val)
|
||||
if self._private.min_rows_size ~= val and val >= 0 then
|
||||
self._private.min_rows_size = val
|
||||
end
|
||||
end
|
||||
|
||||
-- Force the number of columns of the layout.
|
||||
function grid:set_forced_num_cols(val)
|
||||
if self._private.forced_num_cols ~= val then
|
||||
self._private.forced_num_cols = val
|
||||
update_dimension(self)
|
||||
self:emit_signal("widget::layout_changed")
|
||||
end
|
||||
end
|
||||
|
||||
-- Force the number of rows of the layout.
|
||||
function grid:set_forced_num_rows(val)
|
||||
if self._private.forced_num_rows ~= val then
|
||||
self._private.forced_num_rows = val
|
||||
update_dimension(self)
|
||||
self:emit_signal("widget::layout_changed")
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the grid properties
|
||||
for _, prop in ipairs(properties) do
|
||||
if not grid["set_" .. prop] then
|
||||
grid["set_"..prop] = function(self, value)
|
||||
if self._private[prop] ~= value then
|
||||
self._private[prop] = value
|
||||
self:emit_signal("widget::layout_changed")
|
||||
end
|
||||
end
|
||||
end
|
||||
if not grid["get_" .. prop] then
|
||||
grid["get_"..prop] = function(self)
|
||||
return self._private[prop]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Set the directional grid properties
|
||||
-- create a couple of properties by prepending `horizontal_` and `vertical_`
|
||||
-- create a common property for the two directions:
|
||||
-- setting the common property sets both directional properties
|
||||
-- getting the common property returns the directional property
|
||||
-- defined by the `orientation` property
|
||||
for _, prop in ipairs(dir_properties) do
|
||||
for _,dir in ipairs{"horizontal_, vertical_"} do
|
||||
local dir_prop = dir .. "_" .. prop
|
||||
grid["set_"..dir_prop] = function(self, value)
|
||||
if self._private[dir_prop] ~= value then
|
||||
self._private[dir_prop] = value
|
||||
self:emit_signal("widget::layout_changed")
|
||||
end
|
||||
end
|
||||
grid["get_"..dir_prop] = function(self)
|
||||
return self._private[dir_prop]
|
||||
end
|
||||
end
|
||||
|
||||
-- Non-directional options
|
||||
grid["set_"..prop] = function(self, value)
|
||||
if self._private["horizontal_"..prop] ~= value or self._private["vertical_"..prop] ~= value then
|
||||
self._private["horizontal_"..prop] = value
|
||||
self._private["vertical_"..prop] = value
|
||||
self:emit_signal("widget::layout_changed")
|
||||
end
|
||||
end
|
||||
grid["get_"..prop] = function(self)
|
||||
return self._private[self._private.orientation .. "_" .. prop]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Return two tables of the fitted sizes of the rows and columns
|
||||
-- @treturn table,table Tables of row heights and column widths
|
||||
local function get_grid_sizes(self, context, orig_width, orig_height)
|
||||
local rows_size = {}
|
||||
local cols_size = {}
|
||||
|
||||
-- Set the row and column sizes to the minimum value
|
||||
for i = 1,self._private.num_rows do
|
||||
rows_size[i] = self._private.min_rows_size
|
||||
end
|
||||
for j = 1,self._private.num_cols do
|
||||
cols_size[j] = self._private.min_cols_size
|
||||
end
|
||||
|
||||
-- Calculate cell sizes
|
||||
for _, data in ipairs(self._private.widgets) do
|
||||
local w, h = base.fit_widget(self, context, data.widget, orig_width, orig_height)
|
||||
h = math.max( self._private.min_rows_size, h / data.row_span )
|
||||
w = math.max( self._private.min_cols_size, w / data.col_span )
|
||||
-- update the row and column maximum size
|
||||
for i = data.row, data.row + data.row_span - 1 do
|
||||
if h > rows_size[i] then rows_size[i] = h end
|
||||
end
|
||||
for j = data.col, data.col + data.col_span - 1 do
|
||||
if w > cols_size[j] then cols_size[j] = w end
|
||||
end
|
||||
end
|
||||
return rows_size, cols_size
|
||||
end
|
||||
|
||||
|
||||
-- Fit the grid layout into the given space.
|
||||
-- @param context The context in which we are fit.
|
||||
-- @param orig_width The available width.
|
||||
-- @param orig_height The available height.
|
||||
function grid:fit(context, orig_width, orig_height)
|
||||
local width, height = orig_width, orig_height
|
||||
|
||||
-- Calculate the space needed
|
||||
local function fit_direction(dir, sizes)
|
||||
local m = 0
|
||||
if self._private[dir .. "_homogeneous"] then
|
||||
-- all the columns/rows have the same size
|
||||
m = #sizes * max_value(sizes) + (#sizes - 1) * self._private[dir .. "_spacing"]
|
||||
else
|
||||
-- sum the columns/rows size
|
||||
for _,s in ipairs(sizes) do
|
||||
m = m + s + self._private[dir .. "_spacing"]
|
||||
end
|
||||
m = m - self._private[dir .. "_spacing"]
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
-- fit matrix cells
|
||||
local rows_size, cols_size = get_grid_sizes(self, context, width, height)
|
||||
|
||||
-- compute the width
|
||||
local used_width_max = fit_direction("horizontal", cols_size)
|
||||
local used_height_max = fit_direction("vertical", rows_size)
|
||||
|
||||
return used_width_max, used_height_max
|
||||
end
|
||||
|
||||
-- Layout a grid layout.
|
||||
-- @param context The context in which we are drawn.
|
||||
-- @param width The available width.
|
||||
-- @param height The available height.
|
||||
function grid:layout(context, width, height)
|
||||
local result = {}
|
||||
local hspacing, vspacing = self._private.horizontal_spacing, self._private.vertical_spacing
|
||||
|
||||
-- Fit matrix cells
|
||||
local rows_size, cols_size = get_grid_sizes(self, context, width, height)
|
||||
local total_expected_width, total_expected_height = sum_values(cols_size), sum_values(rows_size)
|
||||
|
||||
-- Figure out the maximum size we can give out to sub-widgets
|
||||
local single_width, single_height = max_value(cols_size), max_value(rows_size)
|
||||
if self._private.horizontal_expand then
|
||||
single_width = (width - (self._private.num_cols-1)*hspacing) / self._private.num_cols
|
||||
end
|
||||
if self._private.vertical_expand then
|
||||
single_height = (height - (self._private.num_rows-1)*vspacing) / self._private.num_rows
|
||||
end
|
||||
|
||||
-- Calculate the position and size to place the widgets
|
||||
local cumul_width, cumul_height = {}, {}
|
||||
local cw, ch = 0, 0
|
||||
for j = 1, #cols_size do
|
||||
cumul_width[j] = cw
|
||||
if self._private.horizontal_homogeneous then
|
||||
cols_size[j] = math.max(self._private.min_cols_size, single_width)
|
||||
elseif self._private.horizontal_expand then
|
||||
local hpercent = self._private.num_cols * single_width * cols_size[j] / total_expected_width
|
||||
cols_size[j] = math.max(self._private.min_cols_size, hpercent)
|
||||
end
|
||||
cw = cw + cols_size[j] + hspacing
|
||||
end
|
||||
cumul_width[#cols_size + 1] = cw
|
||||
for i = 1, #rows_size do
|
||||
cumul_height[i] = ch
|
||||
if self._private.vertical_homogeneous then
|
||||
rows_size[i] = math.max(self._private.min_rows_size, single_height)
|
||||
elseif self._private.vertical_expand then
|
||||
local vpercent = self._private.num_rows * single_height * rows_size[i] / total_expected_height
|
||||
rows_size[i] = math.max(self._private.min_rows_size, vpercent)
|
||||
end
|
||||
ch = ch + rows_size[i] + vspacing
|
||||
end
|
||||
cumul_height[#rows_size + 1] = ch
|
||||
|
||||
-- Place widgets
|
||||
local fill_space = true -- should be fill_space property?
|
||||
for _, v in pairs(self._private.widgets) do
|
||||
local x, y, w, h
|
||||
-- Round numbers to avoid decimals error, force to place tight widgets
|
||||
-- and avoid redraw glitches
|
||||
x = math.floor(cumul_width[v.col])
|
||||
y = math.floor(cumul_height[v.row])
|
||||
w = math.floor(cumul_width[v.col + v.col_span] - hspacing - x)
|
||||
h = math.floor(cumul_height[v.row + v.row_span] - vspacing - y)
|
||||
-- Recalculate the width so the last widget fits
|
||||
if (fill_space or self._private.horizontal_expand) and x + w > width then
|
||||
w = math.floor(math.max(self._private.min_cols_size, width - x))
|
||||
end
|
||||
-- Recalculate the height so the last widget fits
|
||||
if (fill_space or self._private.vertical_expand) and y + h > height then
|
||||
h = math.floor(math.max(self._private.min_rows_size, height - y))
|
||||
end
|
||||
-- Place the widget if it fits in the area
|
||||
if x + w <= width and y + h <= height then
|
||||
table.insert(result, base.place_widget_at(v.widget, x, y, w, h))
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
--- Reset the grid layout.
|
||||
-- Remove all widgets and reset row and column counts
|
||||
--
|
||||
-- **Signal:** widget::reset
|
||||
function grid:reset()
|
||||
self._private.widgets = {}
|
||||
-- reset the number of columns and rows to the forced value or to 0
|
||||
self._private.num_rows = self._private.forced_num_rows ~= nil
|
||||
and self._private.forced_num_rows or 0
|
||||
self._private.num_cols = self._private.forced_num_cols ~= nil
|
||||
and self._private.forced_num_cols or 0
|
||||
-- emit signals
|
||||
self:emit_signal("widget::layout_changed")
|
||||
self:emit_signal("widget::reset")
|
||||
end
|
||||
|
||||
--- When the layout is reset.
|
||||
-- This signal is emitted when the layout has been reset,
|
||||
-- all the widgets removed and the row and column counts reset.
|
||||
-- @signal widget::reset
|
||||
|
||||
|
||||
|
||||
--- Return a new grid layout.
|
||||
--
|
||||
-- A grid layout sets widgets in a grids of custom number of rows and columns.
|
||||
-- @tparam[opt="y"] string orientation The preferred grid extension direction.
|
||||
-- @function wibox.layout.grid
|
||||
local function new(orientation)
|
||||
-- Preference for vertical direction: fill rows first, extend grid with new row
|
||||
local dir = (orientation == "horizontal"or orientation == "vertical")
|
||||
and orientation or "vertical"
|
||||
|
||||
local ret = base.make_widget(nil, nil, {enable_properties = true})
|
||||
|
||||
util.table.crush(ret, grid, true)
|
||||
|
||||
ret._private.orientation = dir
|
||||
ret._private.widgets = {}
|
||||
ret._private.num_rows = 0
|
||||
ret._private.num_cols = 0
|
||||
ret._private.rows_size = {}
|
||||
ret._private.cols_size = {}
|
||||
|
||||
ret._private.superpose = false
|
||||
ret._private.forced_num_rows = nil
|
||||
ret._private.forced_num_cols = nil
|
||||
ret._private.min_rows_size = 0
|
||||
ret._private.min_cols_size = 0
|
||||
|
||||
ret._private.horizontal_homogeneous = true
|
||||
ret._private.vertical_homogeneous = true
|
||||
ret._private.horizontal_expand = false
|
||||
ret._private.vertical_expand = false
|
||||
ret._private.horizontal_spacing = 0
|
||||
ret._private.vertical_spacing = 0
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
--- Return a new horizontal grid layout.
|
||||
--
|
||||
-- Each new widget is positioned below the last widget on the same column
|
||||
-- up to `forced_num_rows`. Then the next column is filled, creating it if it doesn't exist.
|
||||
-- @tparam number|nil forced_num_rows Forced number of rows (`nil` for automatic).
|
||||
-- @tparam widget ... Widgets that should be added to the layout.
|
||||
-- @function wibox.layout.grid.horizontal
|
||||
function grid.horizontal(forced_num_rows, ...)
|
||||
local ret = new("horizontal")
|
||||
ret:set_forced_num_rows(forced_num_rows)
|
||||
ret:add(...)
|
||||
return ret
|
||||
end
|
||||
|
||||
--- Return a new vertical grid layout.
|
||||
--
|
||||
-- Each new widget is positioned left of the last widget on the same row
|
||||
-- up to `forced_num_cols`. Then the next row is filled, creating it if it doesn't exist.
|
||||
-- @tparam number|nil forced_num_cols Forced number of columns (`nil` for automatic).
|
||||
-- @tparam widget ... Widgets that should be added to the layout.
|
||||
-- @function wibox.layout.grid.vertical
|
||||
function grid.vertical(forced_num_cols, ...)
|
||||
local ret = new("vertical")
|
||||
ret:set_forced_num_cols(forced_num_cols)
|
||||
ret:add(...)
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
function grid.mt:__call(...)
|
||||
return new(...)
|
||||
end
|
||||
|
||||
--@DOC_widget_COMMON@
|
||||
|
||||
--@DOC_object_COMMON@
|
||||
|
||||
return setmetatable(grid, grid.mt)
|
||||
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -18,6 +18,7 @@ return setmetatable({
|
|||
scroll = require("wibox.layout.scroll");
|
||||
ratio = require("wibox.layout.ratio");
|
||||
stack = require("wibox.layout.stack");
|
||||
grid = require("wibox.layout.grid");
|
||||
}, {__call = function(_, args) return base.make_widget_declarative(args) end})
|
||||
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
local generic_widget = ... --DOC_HIDE
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
|
||||
return --DOC_HIDE
|
||||
wibox.widget {
|
||||
generic_widget( "first" ),
|
||||
generic_widget( "second" ),
|
||||
generic_widget( "third" ),
|
||||
generic_widget( "fourth" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
expand = true,
|
||||
layout = wibox.layout.grid
|
||||
}
|
||||
, nil, 60 --DOC_HIDE
|
|
@ -0,0 +1,16 @@
|
|||
local generic_widget, generic_before_after = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
local beautiful = require("beautiful") --DOC_HIDE
|
||||
|
||||
print("l:add_widget_at(new, 1, 4, 1, 1)") --DOC_HIDE
|
||||
|
||||
local w = generic_before_after(wibox.layout.grid, {
|
||||
forced_num_cols = 3,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
}, 6, "add_widget_at", {wibox.widget( --DOC_HIDE
|
||||
generic_widget("__new__",beautiful.bg_highlight) --DOC_HIDE
|
||||
), 1, 4, 1, 1 --DOC_HIDE
|
||||
}) --DOC_HIDE
|
||||
|
||||
return w, w:fit({dpi=96}, 9999, 9999) --DOC_HIDE
|
|
@ -0,0 +1,106 @@
|
|||
local generic_widget = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox")
|
||||
local beautiful = require("beautiful")
|
||||
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
{
|
||||
markup = "<b>expand</b> = <i>false</i>\n<b>homogeneous</b> = <i>false</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "short 1" ),
|
||||
generic_widget( "-------- long 1 --------" ),
|
||||
generic_widget( "short 2" ),
|
||||
generic_widget( "-------- long 2 --------" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
expand = false,
|
||||
homogeneous = false,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
{
|
||||
markup = "<b>expand</b> = <i>true</i>\n<b>homogeneous</b> = <i>false</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "short 1" ),
|
||||
generic_widget( "-------- long 1 --------" ),
|
||||
generic_widget( "short 2" ),
|
||||
generic_widget( "-------- long 2 --------" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
expand = true,
|
||||
homogeneous = false,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
layout = wibox.layout.flex.horizontal
|
||||
},
|
||||
{
|
||||
{
|
||||
{
|
||||
markup = "<b>expand</b> = <i>false</i>\n<b>homogeneous</b> = <i>true</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "short 1" ),
|
||||
generic_widget( "-------- long 1 --------" ),
|
||||
generic_widget( "short 2" ),
|
||||
generic_widget( "-------- long 2 --------" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
expand = false,
|
||||
homogeneous = true,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
{
|
||||
markup = "<b>expand</b> = <i>true</i>\n<b>homogeneous</b> = <i>true</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "short 1" ),
|
||||
generic_widget( "-------- long 1 --------" ),
|
||||
generic_widget( "short 2" ),
|
||||
generic_widget( "-------- long 2 --------" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
expand = true,
|
||||
homogeneous = true,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
layout = wibox.layout.flex.horizontal
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
}
|
||||
return w, 600, 150
|
|
@ -0,0 +1,11 @@
|
|||
local _, generic_before_after = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
|
||||
print("l:extend_column(2)") --DOC_HIDE
|
||||
|
||||
local w = generic_before_after(wibox.layout.grid, {
|
||||
forced_num_cols = 3,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
}, 6, "extend_column", {2}) --DOC_HIDE
|
||||
return w, w:fit({dpi=96}, 9999, 9999) --DOC_HIDE
|
|
@ -0,0 +1,27 @@
|
|||
local generic_widget = ... --DOC_NO_USAGE --DOC_HIDE
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
|
||||
local first = wibox.widget(generic_widget( "first" )) --DOC_HIDE
|
||||
local second = wibox.widget(generic_widget( "second" )) --DOC_HIDE
|
||||
local third = wibox.widget(generic_widget( "t\nh\ni\nr\nd" )) --DOC_HIDE
|
||||
local fourth = wibox.widget(generic_widget( "fourth" )) --DOC_HIDE
|
||||
local fifth = wibox.widget(generic_widget( "fifth" )) --DOC_HIDE
|
||||
local lorem = wibox.widget(generic_widget("Lorem ipsum dolor sit amet, consectetur " .. --DOC_HIDE
|
||||
"adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")) --DOC_HIDE
|
||||
|
||||
local l = wibox.widget {
|
||||
homogeneous = true,
|
||||
spacing = 5,
|
||||
min_cols_size = 10,
|
||||
min_rows_size = 10,
|
||||
layout = wibox.layout.grid,
|
||||
}
|
||||
l:add_widget_at(first , 2, 1, 1, 2)
|
||||
l:add_widget_at(second, 3, 1, 1, 2)
|
||||
l:add_widget_at(third , 2, 3, 2, 1)
|
||||
l:add_widget_at(fourth, 4, 1, 1, 1)
|
||||
l:add_widget_at(fifth , 4, 2, 1, 2)
|
||||
l:insert_row(1)
|
||||
l:add_widget_at(lorem, 1, 1, 1, 3)
|
||||
|
||||
return l, l:fit({dpi=96}, 300, 200) --DOC_HIDE
|
|
@ -0,0 +1,12 @@
|
|||
local _, generic_before_after = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
|
||||
print("l:insert_column(2)") --DOC_HIDE
|
||||
|
||||
local w = generic_before_after(wibox.layout.grid, {
|
||||
forced_num_cols = 3,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
}
|
||||
, 6, "insert_column", {2}) --DOC_HIDE
|
||||
return w, w:fit({dpi=96}, 9999, 9999) --DOC_HIDE
|
|
@ -0,0 +1,49 @@
|
|||
local generic_widget = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
local beautiful = require("beautiful") --DOC_HIDE
|
||||
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
markup = "<b>min_cols_size</b> = <i>0</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "first" ),
|
||||
generic_widget( "second" ),
|
||||
forced_num_cols = 2,
|
||||
min_cols_size = 0,
|
||||
homogeneous = true,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
{
|
||||
markup = "<b>min_cols_size</b> = <i>100</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "first" ),
|
||||
generic_widget( "second" ),
|
||||
forced_num_cols = 2,
|
||||
min_cols_size = 100,
|
||||
homogeneous = true,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
}
|
||||
return w, w:fit({dpi=96}, 9999, 9999)
|
||||
--return w, 500, 50
|
|
@ -0,0 +1,71 @@
|
|||
local generic_widget = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
local beautiful = require("beautiful") --DOC_HIDE
|
||||
|
||||
print([[l = wibox.layout {
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
layout = wibox.layout.grid
|
||||
}
|
||||
l:set_orientation("vertical") -- change to "horizontal"
|
||||
l:add(...)
|
||||
]]) --DOC_HIDE
|
||||
|
||||
return --DOC_HIDE
|
||||
wibox.widget {
|
||||
{
|
||||
{
|
||||
markup = "<b>orientation</b> = <i>'vertical'</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "first" ),
|
||||
generic_widget( "second" ),
|
||||
generic_widget( "third" ),
|
||||
generic_widget( "fourth" ),
|
||||
generic_widget( "fifth" ),
|
||||
generic_widget( "sixth" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
orientation = "vertical",
|
||||
expand = false,
|
||||
homogeneous = true,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
{
|
||||
markup = "<b>orientation</b> = <i>'horizontal'</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "first" ),
|
||||
generic_widget( "second" ),
|
||||
generic_widget( "third" ),
|
||||
generic_widget( "fourth" ),
|
||||
generic_widget( "fifth" ),
|
||||
generic_widget( "sixth" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
orientation = 'horizontal',
|
||||
expand = false,
|
||||
homogeneous = true,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
layout = wibox.layout.fixed.horizontal
|
||||
}
|
||||
, 300, 90 --DOC_HIDE
|
|
@ -0,0 +1,12 @@
|
|||
local _, generic_before_after = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
|
||||
print("l:remove_widgets_at(1,1)") --DOC_HIDE
|
||||
|
||||
local w = generic_before_after(wibox.layout.grid, {
|
||||
forced_num_cols = 3,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
}, 6, "remove_widgets_at", {1, 1}) --DOC_HIDE
|
||||
|
||||
return w, w:fit({dpi=96}, 9999, 9999) --DOC_HIDE
|
|
@ -0,0 +1,12 @@
|
|||
local _, generic_before_after = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
|
||||
print("l:remove_column(2)") --DOC_HIDE
|
||||
|
||||
local w = generic_before_after(wibox.layout.grid, {
|
||||
forced_num_cols = 3,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
}, 6, "remove_column", {2} --DOC_HIDE
|
||||
)
|
||||
return w, w:fit({dpi=96}, 9999, 9999) --DOC_HIDE
|
|
@ -0,0 +1,56 @@
|
|||
local generic_widget = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox") --DOC_HIDE
|
||||
local beautiful = require("beautiful") --DOC_HIDE
|
||||
|
||||
local w = wibox.widget {
|
||||
{
|
||||
{
|
||||
markup = "<b>spacing</b> = <i>0</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "first" ),
|
||||
generic_widget( "second" ),
|
||||
generic_widget( "third" ),
|
||||
generic_widget( "fourth" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
spacing = 0,
|
||||
padding = 0,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
{
|
||||
{
|
||||
markup = "<b>spacing</b> = <i>10</i>",
|
||||
widget = wibox.widget.textbox
|
||||
},
|
||||
{
|
||||
{
|
||||
generic_widget( "first" ),
|
||||
generic_widget( "second" ),
|
||||
generic_widget( "third" ),
|
||||
generic_widget( "fourth" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
homogeneous = true,
|
||||
spacing = 10,
|
||||
padding = 0,
|
||||
layout = wibox.layout.grid,
|
||||
},
|
||||
margins = 1,
|
||||
color = beautiful.border_color,
|
||||
layout = wibox.container.margin,
|
||||
},
|
||||
layout = wibox.layout.fixed.vertical
|
||||
},
|
||||
layout = wibox.layout.flex.horizontal
|
||||
}
|
||||
return w, w:fit({dpi=96}, 9999, 9999)
|
|
@ -0,0 +1,20 @@
|
|||
local generic_widget = ... --DOC_HIDE_ALL
|
||||
local wibox = require("wibox")
|
||||
local beautiful = require("beautiful")
|
||||
|
||||
local w = wibox.widget {
|
||||
generic_widget( "first" ),
|
||||
generic_widget( "second" ),
|
||||
generic_widget( "third" ),
|
||||
generic_widget( "fourth" ),
|
||||
forced_num_cols = 2,
|
||||
forced_num_rows = 2,
|
||||
superpose = true,
|
||||
homogeneous = true,
|
||||
layout = wibox.layout.grid,
|
||||
}
|
||||
w:add_widget_at(wibox.widget(
|
||||
generic_widget("fifth",beautiful.bg_highlight)
|
||||
), 1, 1, 1, 2)
|
||||
|
||||
return w, w:fit({dpi=96}, 9999, 9999)
|
Loading…
Reference in New Issue