Merge pull request #486 from Elv13/new_widget_syntax
widget: Add a new container declaration syntax
This commit is contained in:
commit
cd584fda55
|
@ -34,6 +34,11 @@ set(AWE_DOC_FILES
|
||||||
${AWE_DOC_DIR}/02-contributing.md
|
${AWE_DOC_DIR}/02-contributing.md
|
||||||
${SOURCE_DIR}/LICENSE)
|
${SOURCE_DIR}/LICENSE)
|
||||||
|
|
||||||
|
set(AWE_DOC_IMAGES
|
||||||
|
${AWE_DOC_DIR}/images/widgetlayout1.png
|
||||||
|
${AWE_DOC_DIR}/images/widgetlayout2.png
|
||||||
|
)
|
||||||
|
|
||||||
set(AWE_SRCS
|
set(AWE_SRCS
|
||||||
${BUILD_DIR}/awesome.c
|
${BUILD_DIR}/awesome.c
|
||||||
${BUILD_DIR}/banning.c
|
${BUILD_DIR}/banning.c
|
||||||
|
@ -259,6 +264,9 @@ if(GENERATE_DOC)
|
||||||
file(GLOB_RECURSE AWE_LUA_FILES ${BUILD_DIR}/lib/*.lua)
|
file(GLOB_RECURSE AWE_LUA_FILES ${BUILD_DIR}/lib/*.lua)
|
||||||
file(GLOB_RECURSE AWE_MD_FILES ${AWE_DOC_DIR}/*.md)
|
file(GLOB_RECURSE AWE_MD_FILES ${AWE_DOC_DIR}/*.md)
|
||||||
|
|
||||||
|
# Copy the images to the build directory
|
||||||
|
file(COPY ${SOURCE_DIR}/docs/images DESTINATION ${AWE_DOC_DIR})
|
||||||
|
|
||||||
# Run ldoc and make it fail if any warnings are generated. The
|
# Run ldoc and make it fail if any warnings are generated. The
|
||||||
# redirection-magic swaps stdout and stderr and awk exits with a non-zero
|
# redirection-magic swaps stdout and stderr and awk exits with a non-zero
|
||||||
# status if it sees at least one line of input.
|
# status if it sees at least one line of input.
|
||||||
|
@ -342,6 +350,7 @@ install(DIRECTORY ${SOURCE_DIR}/themes DESTINATION ${AWESOME_DATA_PATH}
|
||||||
install(DIRECTORY ${BUILD_DIR}/themes DESTINATION ${AWESOME_DATA_PATH}
|
install(DIRECTORY ${BUILD_DIR}/themes DESTINATION ${AWESOME_DATA_PATH}
|
||||||
PATTERN "*.lua")
|
PATTERN "*.lua")
|
||||||
install(FILES ${AWE_DOC_FILES} DESTINATION ${AWESOME_DOC_PATH})
|
install(FILES ${AWE_DOC_FILES} DESTINATION ${AWESOME_DOC_PATH})
|
||||||
|
install(FILES ${AWE_DOC_IMAGES} DESTINATION ${AWESOME_DOC_PATH}/images)
|
||||||
install(FILES "awesome.desktop" DESTINATION ${AWESOME_XSESSION_PATH})
|
install(FILES "awesome.desktop" DESTINATION ${AWESOME_XSESSION_PATH})
|
||||||
if(GENERATE_DOC)
|
if(GENERATE_DOC)
|
||||||
install(DIRECTORY ${BUILD_DIR}/doc DESTINATION ${AWESOME_DOC_PATH})
|
install(DIRECTORY ${BUILD_DIR}/doc DESTINATION ${AWESOME_DOC_PATH})
|
||||||
|
|
|
@ -195,27 +195,24 @@ for s = 1, screen.count() do
|
||||||
-- Create the wibox
|
-- Create the wibox
|
||||||
mywibox[s] = awful.wibox({ position = "top", screen = s })
|
mywibox[s] = awful.wibox({ position = "top", screen = s })
|
||||||
|
|
||||||
-- Widgets that are aligned to the left
|
-- Add widgets to the wibox
|
||||||
local left_layout = wibox.layout.fixed.horizontal()
|
mywibox[s]:setup {
|
||||||
left_layout:add(mylauncher)
|
layout = wibox.layout.align.horizontal,
|
||||||
left_layout:add(mytaglist[s])
|
{ -- Left widgets
|
||||||
left_layout:add(mypromptbox[s])
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
mylauncher,
|
||||||
-- Widgets that are aligned to the right
|
mytaglist[s],
|
||||||
local right_layout = wibox.layout.fixed.horizontal()
|
mypromptbox[s],
|
||||||
right_layout:add(mykeyboardlayout)
|
},
|
||||||
|
mytasklist[s], -- Middle widget
|
||||||
if s == 1 then right_layout:add(wibox.widget.systray()) end
|
{ -- Right widgets
|
||||||
right_layout:add(mytextclock)
|
layout = wibox.layout.fixed.horizontal,
|
||||||
right_layout:add(mylayoutbox[s])
|
mykeyboardlayout,
|
||||||
|
s == 1 and wibox.widget.systray(),
|
||||||
-- Now bring it all together (with the tasklist in the middle)
|
mytextclock,
|
||||||
local layout = wibox.layout.align.horizontal()
|
mylayoutbox[s],
|
||||||
layout:set_left(left_layout)
|
},
|
||||||
layout:set_middle(mytasklist[s])
|
}
|
||||||
layout:set_right(right_layout)
|
|
||||||
|
|
||||||
mywibox[s]:set_widget(layout)
|
|
||||||
end
|
end
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
|
@ -494,33 +491,30 @@ client.connect_signal("manage", function (c)
|
||||||
end)
|
end)
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Widgets that are aligned to the left
|
awful.titlebar(c) : setup {
|
||||||
local left_layout = wibox.layout.fixed.horizontal()
|
{ -- Left
|
||||||
left_layout:add(awful.titlebar.widget.iconwidget(c))
|
awful.titlebar.widget.iconwidget(c),
|
||||||
left_layout:buttons(buttons)
|
buttons = buttons,
|
||||||
|
layout = wibox.layout.fixed.horizontal
|
||||||
-- Widgets that are aligned to the right
|
},
|
||||||
local right_layout = wibox.layout.fixed.horizontal()
|
{ -- Middle
|
||||||
right_layout:add(awful.titlebar.widget.floatingbutton(c))
|
{ -- Title
|
||||||
right_layout:add(awful.titlebar.widget.maximizedbutton(c))
|
align = "center",
|
||||||
right_layout:add(awful.titlebar.widget.stickybutton(c))
|
widget = awful.titlebar.widget.titlewidget(c)
|
||||||
right_layout:add(awful.titlebar.widget.ontopbutton(c))
|
},
|
||||||
right_layout:add(awful.titlebar.widget.closebutton(c))
|
buttons = buttons,
|
||||||
|
layout = wibox.layout.flex.horizontal
|
||||||
-- The title goes in the middle
|
},
|
||||||
local middle_layout = wibox.layout.flex.horizontal()
|
{ -- Right
|
||||||
local title = awful.titlebar.widget.titlewidget(c)
|
awful.titlebar.widget.floatingbutton (c),
|
||||||
title:set_align("center")
|
awful.titlebar.widget.maximizedbutton(c),
|
||||||
middle_layout:add(title)
|
awful.titlebar.widget.stickybutton (c),
|
||||||
middle_layout:buttons(buttons)
|
awful.titlebar.widget.ontopbutton (c),
|
||||||
|
awful.titlebar.widget.closebutton (c),
|
||||||
-- Now bring it all together
|
layout = wibox.layout.fixed.horizontal()
|
||||||
local layout = wibox.layout.align.horizontal()
|
},
|
||||||
layout:set_left(left_layout)
|
layout = wibox.layout.align.horizontal
|
||||||
layout:set_right(right_layout)
|
}
|
||||||
layout:set_middle(middle_layout)
|
|
||||||
|
|
||||||
awful.titlebar(c):set_widget(layout)
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,263 @@
|
||||||
|
# The declarative layout system
|
||||||
|
|
||||||
|
This system provide an alternative to the system used in Awesome 3.5 and is
|
||||||
|
inspired by the one once used by Awesome 3.2-3.4 and Qt QML system.
|
||||||
|
|
||||||
|
## A simple layout
|
||||||
|
|
||||||
|
* Display `my_first_widget` only on screen one
|
||||||
|
* Add a background color to `my_third_widget`
|
||||||
|
* Dispose in a `wibox.layout.fixed.horizontal` layout
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
mywibox[s] : setup {
|
||||||
|
s == 1 and my_first_widget, -- Only display on screen 1
|
||||||
|
my_second_widget,
|
||||||
|
{ -- Add a background color/pattern for my_third_widget
|
||||||
|
my_third_widget,
|
||||||
|
bg = beautiful.bg_focus,
|
||||||
|
widget = wibox.widget.background,
|
||||||
|
},
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
In this example `s == 1` is an inline expression. In the default `rc.lua`,
|
||||||
|
there is an `s` variable represent to define the current screen. Any lua
|
||||||
|
logic expression can be used as long as it return a valid widget, or a
|
||||||
|
declarative layout, or `nil`.
|
||||||
|
|
||||||
|
|
||||||
|
## Define widgets inline and place them
|
||||||
|
|
||||||
|
* Create a `wibox.widget.textbox` with various properties
|
||||||
|
* Force the textbox size using `wibox.layout.constraint`
|
||||||
|
* Add a margin around another textbox
|
||||||
|
* Add a `wibox.widget.background` (for visualization)
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
mywibox[s] : setup {
|
||||||
|
{
|
||||||
|
-- Force the textbox to always be 300 pixel long
|
||||||
|
{
|
||||||
|
{
|
||||||
|
markup = "<b>Hello World!</b>",
|
||||||
|
align = "center",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
bg = "#ff0000",
|
||||||
|
widget = wibox.widget.background,
|
||||||
|
},
|
||||||
|
width = 300,
|
||||||
|
strategy = "min",
|
||||||
|
layout = wibox.layout.constraint
|
||||||
|
},
|
||||||
|
{
|
||||||
|
-- Add a border around the background
|
||||||
|
{
|
||||||
|
{
|
||||||
|
markup = "Foobar",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
bg = "#0000ff",
|
||||||
|
widget = wibox.widget.background
|
||||||
|
},
|
||||||
|
left = 10,
|
||||||
|
right = 10,
|
||||||
|
top = 1,
|
||||||
|
bottom = 2,
|
||||||
|
layout = wibox.layout.margin
|
||||||
|
},
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result:
|
||||||
|
![Example2 screenshot](../../docs/images/widgetlayout1.png)
|
||||||
|
|
||||||
|
|
||||||
|
## Use an `wibox.layout.align` layout
|
||||||
|
The `wibox.layout.align` is a little different. While most layouts will
|
||||||
|
ignore any `nil` lines, the `align` layout rely on them so `left`, `middle`
|
||||||
|
and `right` can be defined
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
mywibox[s] : setup {
|
||||||
|
my_textbox1, -- Left
|
||||||
|
nil, -- Nothing in the middle
|
||||||
|
my_textbox2, -- Right
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Define new widgets
|
||||||
|
|
||||||
|
New trivial widgets can be created directly in the layout declaration. Here
|
||||||
|
is a simple circle widget:
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
mywibox[s] : setup {
|
||||||
|
fit = function(self, context, width, height)
|
||||||
|
return height, height -- A square taking the full height
|
||||||
|
end,
|
||||||
|
draw = function(self, context, cr, width, height)
|
||||||
|
cr:set_source_rgb(1, 0, 0) -- Red
|
||||||
|
cr:arc(height/2, height/2, height/2, 0, math.pi*2)
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
layout = wibox.widget.base.make_widget,
|
||||||
|
}
|
||||||
|
|
||||||
|
Result:
|
||||||
|
![Example4 screenshot](../../docs/images/widgetlayout2.png)
|
||||||
|
|
||||||
|
For more information about how to draw widgets, refer to the `Cairo` api:
|
||||||
|
|
||||||
|
* [Path](http://cairographics.org/manual/cairo-Paths.html)
|
||||||
|
* [Context](http://cairographics.org/manual/cairo-cairo-t.html)
|
||||||
|
* [Pattern](http://cairographics.org/manual/cairo-cairo-pattern-t.html)
|
||||||
|
* [transformation](http://cairographics.org/manual/cairo-Transformations.html)
|
||||||
|
* [Operator](http://cairographics.org/operators/)
|
||||||
|
* [Pango text](https://developer.gnome.org/pango/stable/)
|
||||||
|
|
||||||
|
|
||||||
|
## Externally defined widgets and layouts
|
||||||
|
|
||||||
|
This is useful when the widget is provided by an external module or when it
|
||||||
|
requires complex manipulations which would make the declaration unreadable.
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
local tb = wibox.widget.textbox()
|
||||||
|
tb:set_markup("Hello world! ")
|
||||||
|
|
||||||
|
-- Repeat "tb" 3 times
|
||||||
|
mywibox[s] : setup {
|
||||||
|
tb,
|
||||||
|
tb,
|
||||||
|
tb,
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Accessing widgets
|
||||||
|
|
||||||
|
For each widget or container, it is possible to add an `identifier` attribute
|
||||||
|
so the widget can be accessed later.
|
||||||
|
|
||||||
|
Widgets defined using `setup` can be access by 3 means:
|
||||||
|
|
||||||
|
* Avoid the issue by using externally created widgets
|
||||||
|
* Use `my_wibox.my_first_widget.my_second_widget` style access
|
||||||
|
* Use JavaScript like `my_wibox:get_children_by_id("my_second_widget")[1]`
|
||||||
|
|
||||||
|
The first method mixes the imperative and declarative syntax, but makes the code
|
||||||
|
less readable. The second is a little verbose and only works if every node in
|
||||||
|
the chain have a valid identifier. The last one doesn't require long paths,
|
||||||
|
but it is not easy to get a specific instance if multiple widgets have the
|
||||||
|
same identifier.
|
||||||
|
|
||||||
|
WARNING: The widget identifier must not use reseved name. This include all
|
||||||
|
method names, existing widget attributes, `layout` and `widget`. Names should
|
||||||
|
also respect the lua variable name policies (case sensitive, alphanumeric and
|
||||||
|
underscore characters and non-numeric first character)
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
mywibox[s] : setup {
|
||||||
|
{
|
||||||
|
id = "second",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id = "third",
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
id = "first",
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
}
|
||||||
|
|
||||||
|
mywibox[s].first.second:set_markup("changed!")
|
||||||
|
mywibox[s]:get_children_by_id("third")[1]:set_markup("Also changed!")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Extending the system
|
||||||
|
|
||||||
|
This system is very flexible. Each section attribute (the entries with string
|
||||||
|
keys) is directly linked to the layout or widget API. When setting the
|
||||||
|
imaginary `myproperty`, it will first check if `set_myproperty` exist. If it
|
||||||
|
doesn't, it will check if there is a `myproperty` method. Finally, it will
|
||||||
|
just set the `mywidget.myproperty` directly in case it is used later or
|
||||||
|
catched by a lua `metatable` (operator overload).
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
-- "Monkeypatch" a new function to wibox.widget.textbox to add vicious
|
||||||
|
-- extension support
|
||||||
|
function wibox.widget.textbox:vicious(args)
|
||||||
|
local f = unpack or table.unpack -- Lua 5.1 compat
|
||||||
|
vicious.register(w, f(args))
|
||||||
|
end
|
||||||
|
|
||||||
|
mywibox[s] : setup {
|
||||||
|
{
|
||||||
|
vicious = {vicious.widgets.cpu, "CPU: $1%", 3},
|
||||||
|
widget = wibox.widget.textbox
|
||||||
|
},
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
In this example, the system is extended to that the popular
|
||||||
|
[Vicious](http://awesome.naquadah.org/wiki/Vicious) extension module can be
|
||||||
|
used directly in the layout declaration. This example will update the textbox
|
||||||
|
every 3 seconds to show the CPU usage.
|
||||||
|
|
||||||
|
|
||||||
|
## Handling sections
|
||||||
|
|
||||||
|
The system allows sections to be defined externally, then composed into
|
||||||
|
the final layout declaration. Here is an example re-using one of the above
|
||||||
|
example:
|
||||||
|
|
||||||
|
Code:
|
||||||
|
|
||||||
|
local circle = {
|
||||||
|
fit = function(self, context, width, height)
|
||||||
|
return height, height -- A square taking the full height
|
||||||
|
end,
|
||||||
|
draw = function(self, context, cr, width, height)
|
||||||
|
cr:set_source_rgb(1, 0, 0) -- Red
|
||||||
|
cr:arc(height/2, height/2, height/2, 0, math.pi*2)
|
||||||
|
cr:fill()
|
||||||
|
end,
|
||||||
|
layout = wibox.widget.base.make_widget,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Define a layout with the imperative syntax
|
||||||
|
local l = wibox.widget.align()
|
||||||
|
|
||||||
|
-- 3 circle
|
||||||
|
mywibox[s] : setup {
|
||||||
|
circle,
|
||||||
|
circle,
|
||||||
|
circle,
|
||||||
|
l,
|
||||||
|
layout = wibox.layout.align.horizontal
|
||||||
|
}
|
||||||
|
|
||||||
|
-- This can be done instead
|
||||||
|
local three_circle = {layout = wibox.layout.align.horizontal}
|
||||||
|
for i=1, 3 do
|
||||||
|
table.insert(three_circle, circle)
|
||||||
|
end
|
||||||
|
|
||||||
|
mywibox[s] : setup (three_circle)
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
# Creating new widget
|
||||||
|
|
||||||
|
All widgets have to be generated via this function so that
|
||||||
|
the needed signals are added and mouse input handling is set up.
|
||||||
|
|
||||||
|
The returned widget will have a `:buttons` member function that can be used to
|
||||||
|
register a set of mouse button events with the widget.
|
||||||
|
|
||||||
|
To implement your own widget, you can implement some member functions on a
|
||||||
|
freshly-created widget. Note that all of these functions should be deterministic
|
||||||
|
in the sense that they will show the same behavior if they are repeatedly called
|
||||||
|
with the same arguments (same width and height). If your widget is updated and
|
||||||
|
needs to change, suitable signals have to be emitted. This will be explained
|
||||||
|
later.
|
||||||
|
|
||||||
|
The first callback is `:fit`. This function is called to select the size of your
|
||||||
|
widget. The arguments to this function is the available space and it should
|
||||||
|
return its desired size. Note that this function only provides a hint which is
|
||||||
|
not necessarily followed. The widget must also be able to draw itself at
|
||||||
|
different sizes than the one requested.
|
||||||
|
|
||||||
|
function widget:fit(context, width, height)
|
||||||
|
-- Find the maximum square available
|
||||||
|
local m = math.min(width, height)
|
||||||
|
return m, m
|
||||||
|
end
|
||||||
|
|
||||||
|
The next callback is `:draw`. As the name suggests, this function is called to
|
||||||
|
draw the widget. The arguments to this widget are the context that the widget is
|
||||||
|
drawn in, the cairo context on which it should be drawn and the widget's size.
|
||||||
|
The cairo context is set up in such a way that the widget as its top-left corner
|
||||||
|
at (0, 0) and its bottom-right corner at (width, height). In other words, no
|
||||||
|
special transformation needs to be done. Note that during this callback a
|
||||||
|
suitable clip will already be applied to the cairo context so that this callback
|
||||||
|
will not be able to draw outside of the area that was registered for the widget
|
||||||
|
by the layout that placed this widget. You should not call `cr:reset_clip()`, as
|
||||||
|
redraws will not be handled correctly in this case.
|
||||||
|
|
||||||
|
function widget:draw(context, cr, width, height)
|
||||||
|
cr:move_to(0, 0)
|
||||||
|
cr:line_to(width, height)
|
||||||
|
cr:move_to(0, height)
|
||||||
|
cr:line_to(width, 0)
|
||||||
|
cr:stroke()
|
||||||
|
end
|
||||||
|
|
||||||
|
There are two signals configured for a widget. When the result that `:fit` would
|
||||||
|
return changes, the `widget::layout_changed` signal has to be emitted. If this
|
||||||
|
actually causes layout changes, the affected areas will be redrawn. The other
|
||||||
|
signal is `widget::redraw_needed`. This signal signals that `:draw` has to be
|
||||||
|
called to redraw the widget, but it is safe to assume that `:fit` does still
|
||||||
|
return the same values as before. If in doubt, you can emit both signals to be
|
||||||
|
safe.
|
||||||
|
|
||||||
|
If your widget only needs to draw something to the screen, the above is all that
|
||||||
|
is needed. The following callbacks can be used when implementing layouts which
|
||||||
|
place other widgets on the screen.
|
||||||
|
|
||||||
|
The `:layout` callback is used to figure out which other widgets should be drawn
|
||||||
|
relative to this widget. Note that it is allowed to place widgets outside of the
|
||||||
|
extents of your own widget, for example at a negative position or at twice the
|
||||||
|
size of this widget. Use this mechanism if your widget needs to draw outside of
|
||||||
|
its own extents. If the result of this callback changes,
|
||||||
|
`widget::layout_changed` has to be emitted. You can use `:fit_widget` to call
|
||||||
|
the `:fit` callback of other widgets. Never call `:fit` directly! For example,
|
||||||
|
if you want to place another widget `child` inside of your widget, you can do it
|
||||||
|
like this:
|
||||||
|
|
||||||
|
-- For readability
|
||||||
|
local base = wibox.widget.base
|
||||||
|
function widget:layout(width, height)
|
||||||
|
local result = {}
|
||||||
|
table.insert(result, base.place_widget_at(child, width/2, 0, width/2, height)
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
Finally, if you want to influence how children are drawn, there are four
|
||||||
|
callbacks available that all get similar arguments:
|
||||||
|
|
||||||
|
function widget:before_draw_children(context, cr, width, height)
|
||||||
|
function widget:after_draw_children(context, cr, width, height)
|
||||||
|
function widget:before_draw_child(context, index, child, cr, width, height)
|
||||||
|
function widget:after_draw_child(context, index, child, cr, width, height)
|
||||||
|
|
||||||
|
All of these are called with the same arguments as the `:draw()` method. Please
|
||||||
|
note that a larger clip will be active during these callbacks that also contains
|
||||||
|
the area of all children. These callbacks can be used to influence the way in
|
||||||
|
which children are drawn, but they should not cause the drawing to cover a
|
||||||
|
different area. As an example, these functions can be used to draw children
|
||||||
|
translucently:
|
||||||
|
|
||||||
|
function widget:before_draw_children(context, cr, width, height)
|
||||||
|
cr:push_group()
|
||||||
|
end
|
||||||
|
function widget:after_draw_children(context, cr, width, height)
|
||||||
|
cr:pop_group_to_source()
|
||||||
|
cr:paint_with_alpha(0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
In pseudo-code, the call sequence for the drawing callbacks during a redraw
|
||||||
|
looks like this:
|
||||||
|
|
||||||
|
widget:draw(context, cr, width, height)
|
||||||
|
widget:before_draw_children(context, cr, width, height)
|
||||||
|
for child do
|
||||||
|
widget:before_draw_child(context, cr, child_index, child, width, height)
|
||||||
|
cr:save()
|
||||||
|
-- Draw child and all of its children recursively, taking into account the
|
||||||
|
-- position and size given to base.place_widget_at() in :layout().
|
||||||
|
cr:restore()
|
||||||
|
widget:after_draw_child(context, cr, child_index, child, width, height)
|
||||||
|
end
|
||||||
|
widget:after_draw_children(context, cr, width, height)
|
|
@ -19,6 +19,8 @@ topics={
|
||||||
'00-authors.md',
|
'00-authors.md',
|
||||||
'01-readme.md',
|
'01-readme.md',
|
||||||
'02-contributing.md',
|
'02-contributing.md',
|
||||||
|
'03-declarative-layout.md',
|
||||||
|
'04-new-widgets.md',
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Setup @client to be an alias for "@tparam client.object"
|
-- Setup @client to be an alias for "@tparam client.object"
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 587 B |
|
@ -26,6 +26,12 @@ local titlebar = {
|
||||||
widget = {}
|
widget = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Set a declarative widget hierarchy description.
|
||||||
|
-- See [The declarative layout system](../documentation/03-declarative-layout.md.html)
|
||||||
|
-- @param args An array containing the widgets disposition
|
||||||
|
-- @name setup
|
||||||
|
-- @class function
|
||||||
|
|
||||||
--- Show tooltips when hover on titlebar buttons (defaults to 'true')
|
--- Show tooltips when hover on titlebar buttons (defaults to 'true')
|
||||||
titlebar.enable_tooltip = true
|
titlebar.enable_tooltip = true
|
||||||
|
|
||||||
|
@ -108,6 +114,9 @@ local function new(c, args)
|
||||||
-- Make sure the titlebar has the right colors applied
|
-- Make sure the titlebar has the right colors applied
|
||||||
bars[position].update_colors()
|
bars[position].update_colors()
|
||||||
|
|
||||||
|
-- Handle declarative/recursive widget container
|
||||||
|
ret.setup = base.widget.setup
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ local sort = require("gears.sort")
|
||||||
local beautiful = require("beautiful")
|
local beautiful = require("beautiful")
|
||||||
local surface = require("gears.surface")
|
local surface = require("gears.surface")
|
||||||
local cairo = require("lgi").cairo
|
local cairo = require("lgi").cairo
|
||||||
|
local base = require("wibox.widget.base")
|
||||||
|
|
||||||
--- This provides widget box windows. Every wibox can also be used as if it were
|
--- This provides widget box windows. Every wibox can also be used as if it were
|
||||||
-- a drawin. All drawin functions and properties are also available on wiboxes!
|
-- a drawin. All drawin functions and properties are also available on wiboxes!
|
||||||
|
@ -36,6 +37,13 @@ function wibox:set_widget(widget)
|
||||||
self._drawable:set_widget(widget)
|
self._drawable:set_widget(widget)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set a declarative widget hierarchy description.
|
||||||
|
-- See [The declarative layout system](../documentation/03-declarative-layout.md.html)
|
||||||
|
-- @param args An array containing the widgets disposition
|
||||||
|
-- @name setup
|
||||||
|
-- @class function
|
||||||
|
wibox.setup = base.widget.setup
|
||||||
|
|
||||||
--- Set the background of the wibox
|
--- Set the background of the wibox
|
||||||
-- @param c The background to use. This must either be a cairo pattern object,
|
-- @param c The background to use. This must either be a cairo pattern object,
|
||||||
-- nil or a string that gears.color() understands.
|
-- nil or a string that gears.color() understands.
|
||||||
|
|
|
@ -171,6 +171,17 @@ function align:get_children()
|
||||||
return util.from_sparse {self.first, self.second, self.third}
|
return util.from_sparse {self.first, self.second, self.third}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- This layout only accept three children, all others will be ignored
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function align:set_children(children)
|
||||||
|
if not children then return self:reset() end
|
||||||
|
self.first = children[1]
|
||||||
|
self.second = children[2]
|
||||||
|
self.third = children[3]
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
--- Fit the align layout into the given space. The align layout will
|
--- Fit the align layout into the given space. The align layout will
|
||||||
-- ask for the sum of the sizes of its sub-widgets in its direction
|
-- ask for the sum of the sizes of its sub-widgets in its direction
|
||||||
-- and the largest sized sub widget in the other direction.
|
-- and the largest sized sub widget in the other direction.
|
||||||
|
@ -243,6 +254,9 @@ local function get_layout(dir, first, second, third)
|
||||||
ret:set_second(second)
|
ret:set_second(second)
|
||||||
ret:set_third(third)
|
ret:set_third(third)
|
||||||
|
|
||||||
|
-- An align layout allow set_children to have empty entries
|
||||||
|
ret.allow_empty_widget = true
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,14 @@ function constraint:get_children()
|
||||||
return {self.widget}
|
return {self.widget}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- This layout only accept one children, all others will be ignored
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function constraint:set_children(children)
|
||||||
|
self.widget = children and children[1]
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
--- Set the strategy to use for the constraining. Valid values are 'max',
|
--- Set the strategy to use for the constraining. Valid values are 'max',
|
||||||
-- 'min' or 'exact'. Throws an error on invalid values.
|
-- 'min' or 'exact'. Throws an error on invalid values.
|
||||||
function constraint:set_strategy(val)
|
function constraint:set_strategy(val)
|
||||||
|
|
|
@ -110,6 +110,14 @@ function fixed:get_children()
|
||||||
return self.widgets
|
return self.widgets
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function fixed:set_children(children)
|
||||||
|
if not children then return self:reset() end
|
||||||
|
self.widgets = children
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
--- Replace the first instance of `widget` in the layout with `widget2`
|
--- Replace the first instance of `widget` in the layout with `widget2`
|
||||||
-- @param widget The widget to replace
|
-- @param widget The widget to replace
|
||||||
-- @param widget2 The widget to replace `widget` with
|
-- @param widget2 The widget to replace `widget` with
|
||||||
|
|
|
@ -31,6 +31,11 @@ local flex = {}
|
||||||
-- @name get_children
|
-- @name get_children
|
||||||
-- @class function
|
-- @class function
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
-- @name set_children
|
||||||
|
-- @class function
|
||||||
|
|
||||||
--- Add some widgets to the given fixed layout
|
--- Add some widgets to the given fixed layout
|
||||||
-- @param layout The layout you are modifying.
|
-- @param layout The layout you are modifying.
|
||||||
-- @tparam widget ... Widgets that should be added (must at least be one)
|
-- @tparam widget ... Widgets that should be added (must at least be one)
|
||||||
|
|
|
@ -78,6 +78,14 @@ function margin:get_children()
|
||||||
return {self.widget}
|
return {self.widget}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- This layout only accept one children, all others will be ignored
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function margin:set_children(children)
|
||||||
|
self.widget = children and children[1]
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
--- Set all the margins to val.
|
--- Set all the margins to val.
|
||||||
function margin:set_margins(val)
|
function margin:set_margins(val)
|
||||||
self.left = val
|
self.left = val
|
||||||
|
|
|
@ -64,6 +64,14 @@ function mirror:get_children()
|
||||||
return {self.widget}
|
return {self.widget}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- This layout only accept one children, all others will be ignored
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function mirror:set_children(children)
|
||||||
|
self.widget = children and children[1]
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
--- Reset this layout. The widget will be removed and the axes reset.
|
--- Reset this layout. The widget will be removed and the axes reset.
|
||||||
function mirror:reset()
|
function mirror:reset()
|
||||||
self.horizontal = false
|
self.horizontal = false
|
||||||
|
|
|
@ -72,6 +72,14 @@ function rotate:get_children()
|
||||||
return {self.widget}
|
return {self.widget}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- This layout only accept one children, all others will be ignored
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function rotate:set_children(children)
|
||||||
|
self.widget = children and children[1]
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
--- Reset this layout. The widget will be removed and the rotation reset.
|
--- Reset this layout. The widget will be removed and the rotation reset.
|
||||||
function rotate:reset()
|
function rotate:reset()
|
||||||
self.direction = nil
|
self.direction = nil
|
||||||
|
|
|
@ -267,6 +267,14 @@ function scroll:get_children()
|
||||||
return {self.widget}
|
return {self.widget}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- This layout only accept one children, all others will be ignored
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function scroll:set_children(children)
|
||||||
|
self.widget = children and children[1]
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
--- Specify the expand mode that is used for extra space.
|
--- Specify the expand mode that is used for extra space.
|
||||||
-- @tparam boolean expand If true, the widget is expanded to include the extra
|
-- @tparam boolean expand If true, the widget is expanded to include the extra
|
||||||
-- space. If false, the extra space is simply left empty.
|
-- space. If false, the extra space is simply left empty.
|
||||||
|
|
|
@ -101,6 +101,14 @@ function background:get_children()
|
||||||
return {self.widget}
|
return {self.widget}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- This layout only accept one children, all others will be ignored
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function background:set_children(children)
|
||||||
|
self.widget = children and children[1]
|
||||||
|
self:emit_signal("widget::layout_changed")
|
||||||
|
end
|
||||||
|
|
||||||
--- Set the background to use
|
--- Set the background to use
|
||||||
function background:set_bg(bg)
|
function background:set_bg(bg)
|
||||||
if bg then
|
if bg then
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
local object = require("gears.object")
|
local object = require("gears.object")
|
||||||
local cache = require("gears.cache")
|
local cache = require("gears.cache")
|
||||||
local matrix = require("gears.matrix")
|
local matrix = require("gears.matrix")
|
||||||
|
local util = require("awful.util")
|
||||||
local setmetatable = setmetatable
|
local setmetatable = setmetatable
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
local type = type
|
local type = type
|
||||||
|
@ -80,6 +81,14 @@ function base.widget:get_children()
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Replace the layout children
|
||||||
|
-- The default implementation does nothing, this must be re-implemented by
|
||||||
|
-- all layout and container widgets.
|
||||||
|
-- @tparam table children A table composed of valid widgets
|
||||||
|
function base.widget:set_children(children)
|
||||||
|
-- Nothing on purpose
|
||||||
|
end
|
||||||
|
|
||||||
-- It could have been merged into `get_all_children`, but it's not necessary
|
-- It could have been merged into `get_all_children`, but it's not necessary
|
||||||
local function digg_children(ret, tlw)
|
local function digg_children(ret, tlw)
|
||||||
for k, w in ipairs(tlw:get_children()) do
|
for k, w in ipairs(tlw:get_children()) do
|
||||||
|
@ -321,126 +330,121 @@ function base.place_widget_at(widget, x, y, width, height)
|
||||||
return base.place_widget_via_matrix(widget, matrix.create_translate(x, y), width, height)
|
return base.place_widget_via_matrix(widget, matrix.create_translate(x, y), width, height)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[--
|
-- Read the table, separate attributes from widgets
|
||||||
Create a new widget. All widgets have to be generated via this function so that
|
local function parse_table(t, leave_empty)
|
||||||
the needed signals are added and mouse input handling is set up.
|
local keys= {}
|
||||||
|
local max = 0
|
||||||
The returned widget will have a :buttons member function that can be used to
|
local attributes, widgets = {}, {}
|
||||||
register a set of mouse button events with the widget.
|
for k,v in pairs(t) do
|
||||||
|
if type(k) == "number" then
|
||||||
To implement your own widget, you can implement some member functions on a
|
-- As `ipairs` doesn't always work on sparse tables, update the
|
||||||
freshly-created widget. Note that all of these functions should be deterministic
|
-- maximum
|
||||||
in the sense that they will show the same behavior if they are repeatedly called
|
if k > max then
|
||||||
with the same arguments (same width and height). If your widget is updated and
|
max = k
|
||||||
needs to change, suitable signals have to be emitted. This will be explained
|
|
||||||
later.
|
|
||||||
|
|
||||||
The first callback is :fit. This function is called to select the size of your
|
|
||||||
widget. The arguments to this function is the available space and it should
|
|
||||||
return its desired size. Note that this function only provides a hint which is
|
|
||||||
not necessarily followed. The widget must also be able to draw itself at
|
|
||||||
different sizes than the one requested.
|
|
||||||
|
|
||||||
function widget:fit(context, width, height)
|
|
||||||
-- Find the maximum square available
|
|
||||||
local m = math.min(width, height)
|
|
||||||
return m, m
|
|
||||||
end
|
end
|
||||||
|
|
||||||
The next callback is :draw. As the name suggests, this function is called to
|
widgets[k] = v
|
||||||
draw the widget. The arguments to this widget are the context that the widget is
|
else
|
||||||
drawn in, the cairo context on which it should be drawn and the widget's size.
|
attributes[k] = v
|
||||||
The cairo context is set up in such a way that the widget as its top-left corner
|
end
|
||||||
at (0, 0) and its bottom-right corner at (width, height). In other words, no
|
|
||||||
special transformation needs to be done. Note that during this callback a
|
|
||||||
suitable clip will already be applied to the cairo context so that this callback
|
|
||||||
will not be able to draw outside of the area that was registered for the widget
|
|
||||||
by the layout that placed this widget. You should not call `cr:reset_clip()`, as
|
|
||||||
redraws will not be handled correctly in this case.
|
|
||||||
|
|
||||||
function widget:draw(context, cr, width, height)
|
|
||||||
cr:move_to(0, 0)
|
|
||||||
cr:line_to(width, height)
|
|
||||||
cr:move_to(0, height)
|
|
||||||
cr:line_to(width, 0)
|
|
||||||
cr:stroke()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
There are two signals configured for a widget. When the result that :fit would
|
-- Pack the sparse table if the container doesn't support sparse tables
|
||||||
return changes, the `widget::layout_changed` signal has to be emitted. If this
|
if not leave_empty then
|
||||||
actually causes layout changes, the affected areas will be redrawn. The other
|
widgets = util.table.from_sparse(widgets)
|
||||||
signal is `widget::redraw_needed`. This signal signals that :draw has to be
|
max = #widgets
|
||||||
called to redraw the widget, but it is safe to assume that :fit does still
|
|
||||||
return the same values as before. If in doubt, you can emit both signals to be
|
|
||||||
safe.
|
|
||||||
|
|
||||||
If your widget only needs to draw something to the screen, the above is all that
|
|
||||||
is needed. The following callbacks can be used when implementing layouts which
|
|
||||||
place other widgets on the screen.
|
|
||||||
|
|
||||||
The :layout callback is used to figure out which other widgets should be drawn
|
|
||||||
relative to this widget. Note that it is allowed to place widgets outside of the
|
|
||||||
extents of your own widget, for example at a negative position or at twice the
|
|
||||||
size of this widget. Use this mechanism if your widget needs to draw outside of
|
|
||||||
its own extents. If the result of this callback changes,
|
|
||||||
`widget::layout_changed` has to be emitted. You can use @{fit_widget} to call
|
|
||||||
the `:fit` callback of other widgets. Never call `:fit` directly! For example,
|
|
||||||
if you want to place another widget `child` inside of your widget, you can do it
|
|
||||||
like this:
|
|
||||||
|
|
||||||
-- For readability
|
|
||||||
local base = wibox.widget.base
|
|
||||||
function widget:layout(width, height)
|
|
||||||
local result = {}
|
|
||||||
table.insert(result, base.place_widget_at(child, width/2, 0, width/2, height)
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Finally, if you want to influence how children are drawn, there are four
|
return max, attributes, widgets
|
||||||
callbacks available that all get similar arguments:
|
end
|
||||||
|
|
||||||
function widget:before_draw_children(context, cr, width, height)
|
-- Recursively build a container from a declarative table
|
||||||
function widget:after_draw_children(context, cr, width, height)
|
local function drill(ids, content)
|
||||||
function widget:before_draw_child(context, index, child, cr, width, height)
|
if not content then return end
|
||||||
function widget:after_draw_child(context, index, child, cr, width, height)
|
|
||||||
|
|
||||||
All of these are called with the same arguments as the :draw() method. Please
|
-- Alias `widget` to `layout` as they are handled the same way
|
||||||
note that a larger clip will be active during these callbacks that also contains
|
content.layout = content.layout or content.widget
|
||||||
the area of all children. These callbacks can be used to influence the way in
|
|
||||||
which children are drawn, but they should not cause the drawing to cover a
|
|
||||||
different area. As an example, these functions can be used to draw children
|
|
||||||
translucently:
|
|
||||||
|
|
||||||
function widget:before_draw_children(context, cr, width, height)
|
-- Make sure the layout is not indexed on a function
|
||||||
cr:push_group()
|
local layout = type(content.layout) == "function" and content.layout() or content.layout
|
||||||
end
|
|
||||||
function widget:after_draw_children(context, cr, width, height)
|
-- Create layouts based on metatable __call
|
||||||
cr:pop_group_to_source()
|
local l = layout.is_widget and layout or layout()
|
||||||
cr:paint_with_alpha(0.5)
|
|
||||||
|
-- Get the number of children widgets (including nil widgets)
|
||||||
|
local max, attributes, widgets = parse_table(content, l.allow_empty_widget)
|
||||||
|
|
||||||
|
-- Get the optional identifier to create a virtual widget tree to place
|
||||||
|
-- in an "access table" to be able to retrieve the widget
|
||||||
|
local id = attributes.id
|
||||||
|
|
||||||
|
-- Clear the internal attributes
|
||||||
|
attributes.id, attributes.layout, attributes.widget = nil, nil, nil
|
||||||
|
|
||||||
|
for k = 1, max do
|
||||||
|
-- ipairs cannot be used on sparse tables
|
||||||
|
local v, id2, e = widgets[k], id, nil
|
||||||
|
if v then
|
||||||
|
-- It is another declarative container, parse it
|
||||||
|
if not v.is_widget then
|
||||||
|
e, id2 = drill(ids, v)
|
||||||
|
widgets[k] = e
|
||||||
end
|
end
|
||||||
|
|
||||||
In pseudo-code, the call sequence for the drawing callbacks during a redraw
|
-- Place the widget in the access table
|
||||||
looks like this:
|
if id2 then
|
||||||
|
l [id2] = e
|
||||||
widget:draw(context, cr, width, height)
|
ids[id2] = ids[id2] or {}
|
||||||
widget:before_draw_children(context, cr, width, height)
|
table.insert(ids[id2], e)
|
||||||
for child do
|
end
|
||||||
widget:before_draw_child(context, cr, child_index, child, width, height)
|
end
|
||||||
cr:save()
|
|
||||||
-- Draw child and all of its children recursively, taking into account the
|
|
||||||
-- position and size given to base.place_widget_at() in :layout().
|
|
||||||
cr:restore()
|
|
||||||
widget:after_draw_child(context, cr, child_index, child, width, height)
|
|
||||||
end
|
end
|
||||||
widget:after_draw_children(context, cr, width, height)
|
|
||||||
|
|
||||||
@param proxy If this is set, the returned widget will be a proxy for this
|
-- Replace all children (if any) with the new ones
|
||||||
widget. It will be equivalent to this widget. This means it
|
l:set_children(widgets)
|
||||||
looks the same on the screen.
|
|
||||||
@tparam[opt] string widget_name Name of the widget. If not set, it will be
|
-- Set layouts attributes
|
||||||
set automatically via `gears.object.modulename`.
|
for attr, val in pairs(attributes) do
|
||||||
@see fit_widget
|
if l["set_"..attr] then
|
||||||
--]]--
|
l["set_"..attr](l, val)
|
||||||
|
elseif type(l[attr]) == "function" then
|
||||||
|
l[attr](l, val)
|
||||||
|
else
|
||||||
|
l[attr] = val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return l, id
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Only available when the declarative system is used
|
||||||
|
local function get_children_by_id(self, name)
|
||||||
|
return self._by_id[name] or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set a declarative widget hierarchy description.
|
||||||
|
-- See [The declarative layout system](../documentation/03-declarative-layout.md.html)
|
||||||
|
-- @param args An array containing the widgets disposition
|
||||||
|
function base.widget:setup(args)
|
||||||
|
local f,ids = self.set_widget or self.add or self.set_first,{}
|
||||||
|
local w, id = drill(ids, args)
|
||||||
|
f(self,w)
|
||||||
|
if id then
|
||||||
|
-- Avoid being dropped by wibox metatable -> drawin
|
||||||
|
rawset(self, id, w)
|
||||||
|
end
|
||||||
|
rawset(self, "_by_id", ids)
|
||||||
|
rawset(self, "get_children_by_id", get_children_by_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create an empty widget skeleton
|
||||||
|
-- See [Creating new widgets](../documentation/04-new-widget.md.html)
|
||||||
|
-- @param proxy If this is set, the returned widget will be a proxy for this
|
||||||
|
-- widget. It will be equivalent to this widget. This means it
|
||||||
|
-- looks the same on the screen.
|
||||||
|
-- @tparam[opt] string widget_name Name of the widget. If not set, it will be
|
||||||
|
-- set automatically via `gears.object.modulename`.
|
||||||
|
-- @see fit_widget
|
||||||
function base.make_widget(proxy, widget_name)
|
function base.make_widget(proxy, widget_name)
|
||||||
local ret = object()
|
local ret = object()
|
||||||
|
|
||||||
|
@ -470,6 +474,9 @@ function base.make_widget(proxy, widget_name)
|
||||||
-- Widget is fully opaque
|
-- Widget is fully opaque
|
||||||
ret.opacity = 1
|
ret.opacity = 1
|
||||||
|
|
||||||
|
-- Differentiate tables from widgets
|
||||||
|
ret.is_widget = true
|
||||||
|
|
||||||
-- Size is not restricted/forced
|
-- Size is not restricted/forced
|
||||||
ret._forced_width = nil
|
ret._forced_width = nil
|
||||||
ret._forced_height = nil
|
ret._forced_height = nil
|
||||||
|
|
Loading…
Reference in New Issue