Documentation overhaul for wibox.widget.base

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2015-06-21 14:27:44 +02:00
parent 26699d5ad7
commit 7acb30de71
1 changed files with 119 additions and 10 deletions

View File

@ -2,7 +2,7 @@
-- @author Uli Schlachter
-- @copyright 2010 Uli Schlachter
-- @release @AWESOME_VERSION@
-- @classmod wibox.widget.base
-- @module wibox.widget.base
---------------------------------------------------------------------------
local debug = require("gears.debug")
@ -91,7 +91,8 @@ function base:buttons(_buttons)
return self.widget_buttons
end
--- Handle a button event on a widget. This is used internally.
-- Handle a button event on a widget. This is used internally and should not be
-- called directly.
function base.handle_button(event, widget, x, y, button, modifiers, geometry)
local function is_any(mod)
return #mod == 1 and mod[1] == "Any"
@ -129,7 +130,7 @@ function base.handle_button(event, widget, x, y, button, modifiers, geometry)
end
--- Create widget placement information. This should be used for a widget's
-- :layout() callback.
-- `:layout()` callback.
-- @param widget The widget that should be placed.
-- @param mat A cairo matrix transforming from the parent widget's coordinate
-- system. For example, use cairo.Matrix.create_translate(1, 2) to draw a
@ -149,7 +150,7 @@ function base.place_widget_via_matrix(widget, mat, width, height)
end
--- Create widget placement information. This should be used for a widget's
-- :layout() callback.
-- `:layout()` callback.
-- @param widget The widget that should be placed.
-- @param x The x coordinate for the widget.
-- @param y The y coordinate for the widget.
@ -162,12 +163,120 @@ function base.place_widget_at(widget, x, y, width, height)
return base.place_widget_via_matrix(widget, Matrix.create_translate(x, y), width, height)
end
--- Create a 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.
-- @param proxy If this is set, the returned widget will be a proxy for this
-- widget. It will be equivalent to this widget.
-- @tparam[opt] string widget_name Name of the widget. If not set, it will be
-- set automatically via `gears.object.modulename`.
--[[--
Create a 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.
<pre><code>function widget:fit(context, width, height)
-- Find the maximum square available
local m = math.min(width, height)
return m, m
end</code></pre>
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
<code>cr:reset_clip()</code>, as redraws will not be handled correctly in this
case.
<pre><code>function widget:draw(wibox, 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</code></pre>
There are two signals configured for a widget. When the result that :fit would
return changes, the <code>widget::layout_changed</code> signal has to be
emitted. If this actually causes layout changes, the affected areas will be
redrawn. The other signal is <code>widget::redraw_needed</code>. 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,
<code>widget::layout_changed</code> 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 <code>child</code> inside of your
widget, you can do it like this:
<pre><code>-- 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</code></pre>
Finally, if you want to influence how children are drawn, there are four
callbacks available that all get similar arguments:
<pre><code>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)</code></pre>
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:
<pre><code>function widget:before_draw_children(wibox, cr, width, height)
cr:push_group()
end
function widget:after_draw_children(wibox, cr, width, height)
cr:pop_group_to_source()
cr:paint_with_alpha(0.5)
end</code></pre>
In pseudo-code, the call sequence for the drawing callbacks during a redraw
looks like this:
<pre><code>widget:draw(wibox, cr, width, height)
widget:before_draw_children(wibox, cr, width, height)
for child do
widget:before_draw_child(wibox, 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(wibox, cr, child_index, child, width, height)
end
widget:after_draw_children(wibox, cr, width, height)</code></pre>
@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)
local ret = object()