2010-10-06 12:42:56 +02:00
|
|
|
---------------------------------------------------------------------------
|
2016-05-25 21:17:16 +02:00
|
|
|
--
|
|
|
|
--@DOC_wibox_layout_defaults_fixed_EXAMPLE@
|
2010-10-06 12:42:56 +02:00
|
|
|
-- @author Uli Schlachter
|
|
|
|
-- @copyright 2010 Uli Schlachter
|
2019-06-06 08:19:03 +02:00
|
|
|
-- @layoutmod wibox.layout.fixed
|
2021-03-27 20:05:10 +01:00
|
|
|
-- @supermodule wibox.widget.base
|
2010-10-06 12:42:56 +02:00
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
2016-02-27 13:55:34 +01:00
|
|
|
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
|
2016-01-18 08:51:09 +01:00
|
|
|
local base = require("wibox.widget.base")
|
2010-10-06 12:42:56 +02:00
|
|
|
local table = table
|
|
|
|
local pairs = pairs
|
2017-03-08 21:18:33 +01:00
|
|
|
local gtable = require("gears.table")
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2012-06-12 15:29:52 +02:00
|
|
|
local fixed = {}
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2016-05-09 07:36:32 +02:00
|
|
|
-- Layout a fixed layout. Each widget gets just the space it asks for.
|
2015-08-08 13:18:54 +02:00
|
|
|
-- @param context The context in which we are drawn.
|
2010-10-06 12:42:56 +02:00
|
|
|
-- @param width The available width.
|
|
|
|
-- @param height The available height.
|
2015-06-14 16:12:44 +02:00
|
|
|
function fixed:layout(context, width, height)
|
|
|
|
local result = {}
|
layout/fixed: Prevent overloading widgets with negative spacing
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
2021-01-01 20:13:19 +01:00
|
|
|
local spacing = self._private.spacing or 0
|
2017-08-07 22:12:29 +02:00
|
|
|
local is_y = self._private.dir == "y"
|
|
|
|
local is_x = not is_y
|
|
|
|
local abspace = math.abs(spacing)
|
|
|
|
local spoffset = spacing < 0 and 0 or spacing
|
layout/fixed: Prevent overloading widgets with negative spacing
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
2021-01-01 20:13:19 +01:00
|
|
|
local widgets_nr = #self._private.widgets
|
|
|
|
local spacing_widget
|
|
|
|
local x, y = 0, 0
|
|
|
|
|
|
|
|
spacing_widget = spacing ~= 0 and self._private.spacing_widget or nil
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2016-05-27 01:41:58 +02:00
|
|
|
for k, v in pairs(self._private.widgets) do
|
layout/fixed: Prevent overloading widgets with negative spacing
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
2021-01-01 20:13:19 +01:00
|
|
|
local w, h = width - x, height - y
|
|
|
|
|
2017-08-07 22:12:29 +02:00
|
|
|
if is_y then
|
layout/fixed: Prevent overloading widgets with negative spacing
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
2021-01-01 20:13:19 +01:00
|
|
|
if k ~= widgets_nr or not self._private.fill_space then
|
|
|
|
h = select(2, base.fit_widget(self, context, v, w, h))
|
|
|
|
end
|
|
|
|
|
|
|
|
if y - spacing >= height then
|
|
|
|
-- pop the spacing widget added in previous iteration if used
|
|
|
|
if spacing_widget then
|
|
|
|
table.remove(result)
|
|
|
|
end
|
|
|
|
break
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
else
|
layout/fixed: Prevent overloading widgets with negative spacing
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
2021-01-01 20:13:19 +01:00
|
|
|
if k ~= widgets_nr or not self._private.fill_space then
|
|
|
|
w = select(1, base.fit_widget(self, context, v, w, h))
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
layout/fixed: Prevent overloading widgets with negative spacing
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
2021-01-01 20:13:19 +01:00
|
|
|
if x - spacing >= width then
|
|
|
|
-- pop the spacing widget added in previous iteration if used
|
|
|
|
if spacing_widget then
|
|
|
|
table.remove(result)
|
|
|
|
end
|
|
|
|
break
|
|
|
|
end
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
2017-08-07 22:12:29 +02:00
|
|
|
|
layout/fixed: Prevent overloading widgets with negative spacing
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
2021-01-01 20:13:19 +01:00
|
|
|
-- Place widget
|
|
|
|
table.insert(result, base.place_widget_at(v, x, y, w, h))
|
|
|
|
|
|
|
|
x = is_x and x + w + spacing or x
|
|
|
|
y = is_y and y + h + spacing or y
|
|
|
|
|
|
|
|
-- Add the spacing widget (if needed)
|
|
|
|
if k < widgets_nr and spacing_widget then
|
2017-08-07 22:12:29 +02:00
|
|
|
table.insert(result, base.place_widget_at(
|
|
|
|
spacing_widget, is_x and (x - spoffset) or x, is_y and (y - spoffset) or y,
|
|
|
|
is_x and abspace or w, is_y and abspace or h
|
|
|
|
))
|
|
|
|
end
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
layout/fixed: Prevent overloading widgets with negative spacing
For each widget, the layout function checks whether placing it would
make the function exceed the allowed geometry.
If not, the function places both the widget and a spacing widget.
This check ignores the size of the spacing widget itself, this can cause
overloading of widgets on top of each other.
For example, the following scenario with these widgets:
widgets: widget1 { width = 10, height = 10 }
widget2 { width = 10, height = 10 }
widget3 { width = 10, height = 10 }
and a call to horizontal layout with the
{ width = 10, height = 10, spacing = -5 } parameters.
The function would layout the widgets the following way:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget2: { x = 5, y = 0, width = 5, height = 10 }
spacing: { x = 5, y = 0, width = 5, height = 10 }
widget3: { x = 5, y = 0, width = 5, height = 10 }
}
This behaviour would be the same for any number of widgets for negative
layout.
This patch changes the layout function to check whether the current
widget uses up the whole space.
It also removes 'pos' variable. Its purpose isn't intuitive in the
presence of x and y. This helps to understand where each widget is
placed now that x, y don't hold the end location of the widget in the
previous loop iteration.
The result of the previous example becomes:
{
widget1: { x = 0, y = 0, width = 10, height = 10 }
}
While this might not be the wanted behaviour exactly, distinguishing
between the scenario where 2 widgets are drawn and a scenario where 3
are drawn might complicate the layout function too much.
This patch also adds unit testing that catches the described behaviour.
Signed-off-by: Shay Agroskin <agrosshay@gmail.com>
2021-01-01 20:13:19 +01:00
|
|
|
|
2015-06-14 16:12:44 +02:00
|
|
|
return result
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
2019-11-29 07:22:50 +01:00
|
|
|
--- Add some widgets to the given layout.
|
|
|
|
--
|
2019-06-06 22:32:53 +02:00
|
|
|
-- @method add
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @tparam widget ... Widgets that should be added (must at least be one).
|
|
|
|
-- @interface layout
|
2015-09-28 21:00:49 +02:00
|
|
|
function fixed:add(...)
|
|
|
|
-- No table.pack in Lua 5.1 :-(
|
|
|
|
local args = { n=select('#', ...), ... }
|
|
|
|
assert(args.n > 0, "need at least one widget to add")
|
|
|
|
for i=1, args.n do
|
2018-12-27 05:54:10 +01:00
|
|
|
local w = base.make_widget_from_value(args[i])
|
|
|
|
base.check_widget(w)
|
|
|
|
table.insert(self._private.widgets, w)
|
2015-09-28 21:00:49 +02:00
|
|
|
end
|
2015-06-14 16:12:44 +02:00
|
|
|
self:emit_signal("widget::layout_changed")
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
2016-01-18 05:23:50 +01:00
|
|
|
|
2019-11-29 07:22:50 +01:00
|
|
|
--- Remove a widget from the layout.
|
|
|
|
--
|
2019-06-06 22:32:53 +02:00
|
|
|
-- @method remove
|
2016-01-18 05:23:50 +01:00
|
|
|
-- @tparam number index The widget index to remove
|
|
|
|
-- @treturn boolean index If the operation is successful
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @interface layout
|
2016-01-18 05:23:50 +01:00
|
|
|
function fixed:remove(index)
|
2016-05-27 01:41:58 +02:00
|
|
|
if not index or index < 1 or index > #self._private.widgets then return false end
|
2016-01-18 05:23:50 +01:00
|
|
|
|
2016-05-27 01:41:58 +02:00
|
|
|
table.remove(self._private.widgets, index)
|
2016-01-18 05:23:50 +01:00
|
|
|
|
|
|
|
self:emit_signal("widget::layout_changed")
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2019-11-29 07:22:50 +01:00
|
|
|
--- Remove one or more widgets from the layout.
|
|
|
|
--
|
2016-01-18 05:23:50 +01:00
|
|
|
-- The last parameter can be a boolean, forcing a recursive seach of the
|
|
|
|
-- widget(s) to remove.
|
2019-06-06 22:32:53 +02:00
|
|
|
-- @method remove_widgets
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @tparam widget ... Widgets that should be removed (must at least be one)
|
2016-01-18 05:23:50 +01:00
|
|
|
-- @treturn boolean If the operation is successful
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @interface layout
|
2016-01-18 05:23:50 +01:00
|
|
|
function fixed:remove_widgets(...)
|
|
|
|
local args = { ... }
|
|
|
|
|
|
|
|
local recursive = type(args[#args]) == "boolean" and args[#args]
|
|
|
|
|
|
|
|
local ret = true
|
|
|
|
for k, rem_widget in ipairs(args) do
|
|
|
|
if recursive and k == #args then break end
|
|
|
|
|
|
|
|
local idx, l = self:index(rem_widget, recursive)
|
|
|
|
|
|
|
|
if idx and l and l.remove then
|
|
|
|
l:remove(idx, false)
|
|
|
|
else
|
|
|
|
ret = false
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
return #args > (recursive and 1 or 0) and ret
|
|
|
|
end
|
|
|
|
|
|
|
|
function fixed:get_children()
|
2016-05-27 01:41:58 +02:00
|
|
|
return self._private.widgets
|
2016-01-18 05:23:50 +01:00
|
|
|
end
|
|
|
|
|
2016-02-04 07:11:10 +01:00
|
|
|
function fixed:set_children(children)
|
2016-02-27 13:55:34 +01:00
|
|
|
self:reset()
|
|
|
|
if #children > 0 then
|
|
|
|
self:add(unpack(children))
|
|
|
|
end
|
2016-02-04 07:11:10 +01:00
|
|
|
end
|
|
|
|
|
2019-11-29 07:22:50 +01:00
|
|
|
--- Replace the first instance of `widget` in the layout with `widget2`.
|
2019-06-06 22:32:53 +02:00
|
|
|
-- @method replace_widget
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @tparam widget widget The widget to replace
|
|
|
|
-- @tparam widget widget2 The widget to replace `widget` with
|
2016-01-18 05:23:50 +01:00
|
|
|
-- @tparam[opt=false] boolean recursive Digg in all compatible layouts to find the widget.
|
|
|
|
-- @treturn boolean If the operation is successful
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @interface layout
|
2016-01-18 05:23:50 +01:00
|
|
|
function fixed:replace_widget(widget, widget2, recursive)
|
|
|
|
local idx, l = self:index(widget, recursive)
|
|
|
|
|
|
|
|
if idx and l then
|
|
|
|
l:set(idx, widget2)
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
function fixed:swap(index1, index2)
|
2016-05-27 01:41:58 +02:00
|
|
|
if not index1 or not index2 or index1 > #self._private.widgets
|
|
|
|
or index2 > #self._private.widgets then
|
2016-01-18 05:23:50 +01:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2016-05-27 01:41:58 +02:00
|
|
|
local widget1, widget2 = self._private.widgets[index1], self._private.widgets[index2]
|
2016-01-18 05:23:50 +01:00
|
|
|
|
|
|
|
self:set(index1, widget2)
|
|
|
|
self:set(index2, widget1)
|
|
|
|
|
2016-08-08 08:39:43 +02:00
|
|
|
self:emit_signal("widget::swapped", widget1, widget2, index2, index1)
|
|
|
|
|
2016-01-18 05:23:50 +01:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function fixed:swap_widgets(widget1, widget2, recursive)
|
|
|
|
base.check_widget(widget1)
|
|
|
|
base.check_widget(widget2)
|
|
|
|
|
|
|
|
local idx1, l1 = self:index(widget1, recursive)
|
|
|
|
local idx2, l2 = self:index(widget2, recursive)
|
|
|
|
|
2016-03-04 06:24:38 +01:00
|
|
|
if idx1 and l1 and idx2 and l2 and (l1.set or l1.set_widget) and (l2.set or l2.set_widget) then
|
|
|
|
if l1.set then
|
|
|
|
l1:set(idx1, widget2)
|
2016-08-08 08:39:43 +02:00
|
|
|
if l1 == self then
|
|
|
|
self:emit_signal("widget::swapped", widget1, widget2, idx2, idx1)
|
|
|
|
end
|
2016-03-04 06:24:38 +01:00
|
|
|
elseif l1.set_widget then
|
|
|
|
l1:set_widget(widget2)
|
|
|
|
end
|
|
|
|
if l2.set then
|
|
|
|
l2:set(idx2, widget1)
|
2016-08-08 08:39:43 +02:00
|
|
|
if l2 == self then
|
|
|
|
self:emit_signal("widget::swapped", widget1, widget2, idx2, idx1)
|
|
|
|
end
|
2016-03-04 06:24:38 +01:00
|
|
|
elseif l2.set_widget then
|
|
|
|
l2:set_widget(widget1)
|
|
|
|
end
|
2016-01-18 05:23:50 +01:00
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
function fixed:set(index, widget2)
|
2016-05-27 01:41:58 +02:00
|
|
|
if (not widget2) or (not self._private.widgets[index]) then return false end
|
2016-01-18 05:23:50 +01:00
|
|
|
|
|
|
|
base.check_widget(widget2)
|
|
|
|
|
2016-08-08 08:39:43 +02:00
|
|
|
local w = self._private.widgets[index]
|
|
|
|
|
2016-05-27 01:41:58 +02:00
|
|
|
self._private.widgets[index] = widget2
|
2016-01-18 05:23:50 +01:00
|
|
|
|
|
|
|
self:emit_signal("widget::layout_changed")
|
2016-08-08 08:39:43 +02:00
|
|
|
self:emit_signal("widget::replaced", widget2, w, index)
|
2016-01-18 05:23:50 +01:00
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2017-08-07 22:12:29 +02:00
|
|
|
--- The widget used to fill the spacing between the layout elements.
|
|
|
|
--
|
|
|
|
-- By default, no widget is used.
|
|
|
|
--
|
|
|
|
--@DOC_wibox_layout_fixed_spacing_widget_EXAMPLE@
|
|
|
|
--
|
|
|
|
-- @property spacing_widget
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @tparam widget spacing_widget
|
|
|
|
-- @propemits true false
|
|
|
|
-- @interface layout
|
2017-08-07 22:12:29 +02:00
|
|
|
|
|
|
|
function fixed:set_spacing_widget(wdg)
|
|
|
|
self._private.spacing_widget = base.make_widget_from_value(wdg)
|
|
|
|
self:emit_signal("widget::layout_changed")
|
2019-11-29 07:22:50 +01:00
|
|
|
self:emit_signal("property::spacing_widget", wdg)
|
2017-08-07 22:12:29 +02:00
|
|
|
end
|
|
|
|
|
2019-06-06 22:32:53 +02:00
|
|
|
--- Insert a new widget in the layout at position `index`.
|
2019-11-29 07:22:50 +01:00
|
|
|
--
|
2019-06-06 22:32:53 +02:00
|
|
|
-- @method insert
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @tparam number index The position.
|
|
|
|
-- @tparam widget widget The widget.
|
|
|
|
-- @treturn boolean If the operation is successful.
|
|
|
|
-- @emits widget::inserted
|
|
|
|
-- @emitstparam widget::inserted widget self The fixed layout.
|
|
|
|
-- @emitstparam widget::inserted widget widget index The inserted widget.
|
|
|
|
-- @emitstparam widget::inserted number count The widget count.
|
|
|
|
-- @interface layout
|
2016-01-18 05:23:50 +01:00
|
|
|
function fixed:insert(index, widget)
|
2016-05-27 01:41:58 +02:00
|
|
|
if not index or index < 1 or index > #self._private.widgets + 1 then return false end
|
2016-01-18 05:23:50 +01:00
|
|
|
|
|
|
|
base.check_widget(widget)
|
2016-05-27 01:41:58 +02:00
|
|
|
table.insert(self._private.widgets, index, widget)
|
2016-01-18 05:23:50 +01:00
|
|
|
self:emit_signal("widget::layout_changed")
|
2016-08-08 08:39:43 +02:00
|
|
|
self:emit_signal("widget::inserted", widget, #self._private.widgets)
|
2016-01-18 05:23:50 +01:00
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2019-06-06 22:32:53 +02:00
|
|
|
-- Fit the fixed layout into the given space.
|
2015-08-08 13:43:35 +02:00
|
|
|
-- @param context The context in which we are fit.
|
2010-10-06 12:42:56 +02:00
|
|
|
-- @param orig_width The available width.
|
|
|
|
-- @param orig_height The available height.
|
2015-08-08 13:43:35 +02:00
|
|
|
function fixed:fit(context, orig_width, orig_height)
|
2021-01-01 20:05:39 +01:00
|
|
|
local width_left, height_left = orig_width, orig_height
|
|
|
|
local spacing = self._private.spacing or 0
|
2021-01-01 18:07:33 +01:00
|
|
|
local widgets_nr = #self._private.widgets
|
2021-01-01 20:05:39 +01:00
|
|
|
local is_y = self._private.dir == "y"
|
|
|
|
local used_max = 0
|
|
|
|
|
|
|
|
-- when no widgets exist the function can be called with orig_width or
|
|
|
|
-- orig_height equal to nil. Exit early in this case.
|
2021-01-01 18:07:33 +01:00
|
|
|
if widgets_nr == 0 then
|
2021-01-01 20:05:39 +01:00
|
|
|
return 0, 0
|
|
|
|
end
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2021-01-01 18:07:33 +01:00
|
|
|
for k, v in pairs(self._private.widgets) do
|
2021-01-01 20:05:39 +01:00
|
|
|
local w, h = base.fit_widget(self, context, v, width_left, height_left)
|
|
|
|
local max
|
|
|
|
|
|
|
|
if is_y then
|
|
|
|
max = w
|
|
|
|
height_left = height_left - h
|
2010-10-06 12:42:56 +02:00
|
|
|
else
|
2021-01-01 20:05:39 +01:00
|
|
|
max = h
|
|
|
|
width_left = width_left - w
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
2021-01-01 20:05:39 +01:00
|
|
|
|
2010-10-06 12:42:56 +02:00
|
|
|
if max > used_max then
|
|
|
|
used_max = max
|
|
|
|
end
|
|
|
|
|
2021-01-01 18:07:33 +01:00
|
|
|
if k < widgets_nr then
|
|
|
|
if is_y then
|
|
|
|
height_left = height_left - spacing
|
2010-10-06 12:42:56 +02:00
|
|
|
else
|
2021-01-01 18:07:33 +01:00
|
|
|
width_left = width_left - spacing
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-01-01 20:05:39 +01:00
|
|
|
if width_left <= 0 or height_left <= 0 then
|
2021-01-01 18:07:33 +01:00
|
|
|
-- this complicated two lines determine whether we're out-of-space
|
|
|
|
-- because of spacing, or if the last widget doesn't fit in
|
2021-01-01 20:05:39 +01:00
|
|
|
if is_y then
|
2021-01-01 18:07:33 +01:00
|
|
|
height_left = k < widgets_nr and height_left + spacing or height_left
|
|
|
|
height_left = height_left < 0 and 0 or height_left
|
2010-10-06 12:42:56 +02:00
|
|
|
else
|
2021-01-01 18:07:33 +01:00
|
|
|
width_left = k < widgets_nr and width_left + spacing or width_left
|
|
|
|
width_left = width_left < 0 and 0 or width_left
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-01-01 20:05:39 +01:00
|
|
|
if is_y then
|
2021-01-01 18:07:33 +01:00
|
|
|
return used_max, orig_height - height_left
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
2021-01-01 20:05:39 +01:00
|
|
|
|
2021-01-01 18:07:33 +01:00
|
|
|
return orig_width - width_left, used_max
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
2012-11-18 20:44:03 +01:00
|
|
|
function fixed:reset()
|
2016-05-27 01:41:58 +02:00
|
|
|
self._private.widgets = {}
|
2015-06-14 16:12:44 +02:00
|
|
|
self:emit_signal("widget::layout_changed")
|
2016-08-08 08:39:43 +02:00
|
|
|
self:emit_signal("widget::reseted")
|
2019-11-29 07:22:50 +01:00
|
|
|
self:emit_signal("widget::reset")
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Set the layout's fill_space property. If this property is true, the last
|
|
|
|
-- widget will get all the space that is left. If this is false, the last widget
|
|
|
|
-- won't be handled specially and there can be space left unused.
|
2016-05-27 01:41:58 +02:00
|
|
|
-- @property fill_space
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @tparam boolean fill_space
|
|
|
|
-- @propemits true false
|
2016-05-27 01:41:58 +02:00
|
|
|
|
2012-11-18 20:44:03 +01:00
|
|
|
function fixed:fill_space(val)
|
2016-05-27 01:41:58 +02:00
|
|
|
if self._private.fill_space ~= val then
|
|
|
|
self._private.fill_space = not not val
|
2015-06-21 14:58:13 +02:00
|
|
|
self:emit_signal("widget::layout_changed")
|
2019-11-29 07:22:50 +01:00
|
|
|
self:emit_signal("property::fill_space", val)
|
2015-06-21 14:58:13 +02:00
|
|
|
end
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
2015-09-28 21:00:49 +02:00
|
|
|
local function get_layout(dir, widget1, ...)
|
2016-05-27 01:41:58 +02:00
|
|
|
local ret = base.make_widget(nil, nil, {enable_properties = true})
|
2013-01-05 16:12:47 +01:00
|
|
|
|
2017-03-08 21:18:33 +01:00
|
|
|
gtable.crush(ret, fixed, true)
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2016-05-27 01:41:58 +02:00
|
|
|
ret._private.dir = dir
|
|
|
|
ret._private.widgets = {}
|
2015-06-21 14:58:13 +02:00
|
|
|
ret:set_spacing(0)
|
|
|
|
ret:fill_space(false)
|
2010-10-06 12:42:56 +02:00
|
|
|
|
2015-09-28 21:00:49 +02:00
|
|
|
if widget1 then
|
|
|
|
ret:add(widget1, ...)
|
|
|
|
end
|
|
|
|
|
2010-10-06 12:42:56 +02:00
|
|
|
return ret
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Returns a new horizontal fixed layout. Each widget will get as much space as it
|
|
|
|
-- asks for and each widget will be drawn next to its neighboring widget.
|
2015-09-28 21:00:49 +02:00
|
|
|
-- Widgets can be added via :add() or as arguments to this function.
|
2017-02-22 04:03:21 +01:00
|
|
|
-- Note that widgets ignore `forced_height`. They will use the preferred/minimum width
|
|
|
|
-- on the horizontal axis, and a stretched height on the vertical axis.
|
2015-09-28 21:00:49 +02:00
|
|
|
-- @tparam widget ... Widgets that should be added to the layout.
|
2019-06-07 20:59:34 +02:00
|
|
|
-- @constructorfct wibox.layout.fixed.horizontal
|
2015-09-28 21:00:49 +02:00
|
|
|
function fixed.horizontal(...)
|
|
|
|
return get_layout("x", ...)
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Returns a new vertical fixed layout. Each widget will get as much space as it
|
|
|
|
-- asks for and each widget will be drawn next to its neighboring widget.
|
2015-09-28 21:00:49 +02:00
|
|
|
-- Widgets can be added via :add() or as arguments to this function.
|
2017-02-22 04:03:21 +01:00
|
|
|
-- Note that widgets ignore `forced_width`. They will use the preferred/minimum height
|
|
|
|
-- on the vertical axis, and a stretched width on the horizontal axis.
|
2015-09-28 21:00:49 +02:00
|
|
|
-- @tparam widget ... Widgets that should be added to the layout.
|
2019-06-07 20:59:34 +02:00
|
|
|
-- @constructorfct wibox.layout.fixed.vertical
|
2015-09-28 21:00:49 +02:00
|
|
|
function fixed.vertical(...)
|
|
|
|
return get_layout("y", ...)
|
2010-10-06 12:42:56 +02:00
|
|
|
end
|
|
|
|
|
2017-08-07 22:12:29 +02:00
|
|
|
--- Add spacing between each layout widgets.
|
|
|
|
--
|
|
|
|
--@DOC_wibox_layout_fixed_spacing_EXAMPLE@
|
|
|
|
--
|
2016-05-27 01:41:58 +02:00
|
|
|
-- @property spacing
|
|
|
|
-- @tparam number spacing Spacing between widgets.
|
2019-11-29 07:22:50 +01:00
|
|
|
-- @propemits true false
|
|
|
|
-- @interface layout
|
2016-05-27 01:41:58 +02:00
|
|
|
|
2014-10-18 07:17:46 +02:00
|
|
|
function fixed:set_spacing(spacing)
|
2016-05-27 01:41:58 +02:00
|
|
|
if self._private.spacing ~= spacing then
|
|
|
|
self._private.spacing = spacing
|
2015-06-21 14:58:13 +02:00
|
|
|
self:emit_signal("widget::layout_changed")
|
2019-11-29 07:22:50 +01:00
|
|
|
self:emit_signal("property::spacing", spacing)
|
2015-06-21 14:58:13 +02:00
|
|
|
end
|
2014-10-18 07:17:46 +02:00
|
|
|
end
|
|
|
|
|
2016-05-27 01:41:58 +02:00
|
|
|
function fixed:get_spacing()
|
|
|
|
return self._private.spacing or 0
|
|
|
|
end
|
|
|
|
|
2017-10-21 01:54:36 +02:00
|
|
|
--@DOC_fixed_COMMON@
|
|
|
|
|
2012-06-12 15:29:52 +02:00
|
|
|
return fixed
|
|
|
|
|
2011-09-11 16:50:01 +02:00
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|