1 -------------------------------------------------------------------------
2 -- @author Sébastien Gross <seb•ɱɩɲʋʃ•awesome•ɑƬ•chezwam•ɖɵʈ•org>
3 -- @copyright 2009 Sébastien Gross
4 -- @release @AWESOME_VERSION@
5 -------------------------------------------------------------------------
12 local a_placement
= require("awful.placement")
13 local beautiful
= require("beautiful")
14 local setmetatable
= setmetatable
17 --- Tooltip module for awesome objects.
18 -- A tooltip is a small hint displayed when the mouse cursor
19 -- hovers a specific item.
20 -- In awesome, a tooltip can be linked with almost any
21 -- object having a <code>add_signal()</code> method and receiving
22 -- <code>mouse::enter</code> and <code>mouse::leave</code> signals.
23 -- <p>How to create a tooltip?<br/>
25 -- myclock = awful.widget.textclock({}, "%T", 1)<br/>
26 -- myclock_t = awful.tooltip({<br/>
27 -- objects = { K },<br/>
28 -- timer_function = function()<br/>
29 -- return os.date("Today is %A %B %d %Y\nThe time is %T")<br/>
34 -- <p>How to add the same tooltip to several objects?<br/>
36 -- myclock_t:add_to_object(obj1)<br/>
37 -- myclock_t:add_to_object(obj2)<br/>
39 -- Now the same tooltip is attached to <code>K</code>, <code>obj1</code>,
40 -- <code>obj2</code>.<br/>
42 -- <p>How to remove tooltip from many objects?<br/>
44 -- myclock_t:remove_from_object(obj1)<br/>
45 -- myclock_t:remove_from_object(obj2)<br/>
47 -- Now the same tooltip is only attached to <code>K</code>.<br/>
49 module("awful.tooltip")
51 local data
= setmetatable({}, { __mode
= 'k' })
53 --- Tooltip object definition.
55 -- @field wibox The wibox displaying the tooltip.
56 -- @field visible True if tooltip is visible.
59 -- Tooltip private data.
60 -- @name awful.tooltip.data
61 -- @field fg tooltip foreground color.
62 -- @field font Tooltip font.
63 -- @field hide The hide() function.
64 -- @field show The show() function.
65 -- @field timer The text update timer.
66 -- @field timer_function The text update timer function.
68 -- Place to tooltip on th screen.
69 -- @param self A tooltip object.
70 local function place(self
)
71 a_placement
.under_mouse(self
.wibox
)
72 a_placement
.no_offscreen(self
.wibox
)
75 -- Place the tooltip under the mouse.
76 -- @param self A tooltip object.
77 local function set_geometry(self
)
78 local my_geo
= self
.wibox
:geometry()
79 -- calculate width / height
80 n_s
= self
.wibox
.widgets
[1]:extents()
81 if my_geo
.width
~= n_s
.width
or my_geo
.height
~= n_s
.height
then
82 self
.wibox
:geometry(n_s
)
85 if not self
.wibox
.visible
then
91 -- @param self The tooltip to show.
92 local function show(self
)
93 -- do nothing if the tooltip is already shown
94 if self
.visible
then return end
95 -- make sure the tooltip is on the same screen as the mouse
96 self
.wibox
.screen
= mouse
.screen
97 if data
[self
].timer
then
98 if not data
[self
].timer
.started
then
99 data
[self
].timer_function()
100 data
[self
].timer
:start()
104 self
.wibox
.visible
= true
109 -- @param self The tooltip to hide.
110 local function hide(self
)
111 -- do nothing if the tooltip is already hidden
112 if not self
.visible
then return end
113 if data
[self
].timer
then
114 if data
[self
].timer
.started
then
115 data
[self
].timer
:stop()
119 self
.wibox
.visible
= false
122 --- Change displayed text.
123 -- @param self The tooltip object.
124 -- @param text New tooltip text.
125 local function set_text(self
, text
)
126 self
.wibox
.widgets
[1].text
= '<span color="' .. data
[self
].fg
127 .. '" font_desc="' .. data
[self
].font
.. '">' .. text
.. "</span>"
130 --- Change the tooltip's update interval.
131 -- @param self A tooltip object.
132 -- @param timeout The timeout value.
133 local function set_timeout(self
, timeout
)
134 if data
[self
].timer
then
135 data
[self
].timer
.timeout
= timeout
139 -- Load Default values.
140 -- @param self A tooltip object.
141 local function set_defaults(self
)
142 self
.wibox
.border_width
= beautiful
.tooltip_border_width
or beautiful
.border_width
or 1
143 self
.wibox
.border_color
= beautiful
.tooltip_border_color
or beautiful
.border_normal
or "#ffcb60"
144 self
.wibox
.opacity
= beautiful
.tooltip_opacity
or 1
145 self
.wibox
.bg
= beautiful
.tooltip_bg_color
or beautiful
.bg_focus
or "#ffcb60"
146 data
[self
].fg
= beautiful
.tooltip_fg_color
or beautiful
.fg_focus
or "#000000"
147 data
[self
].font
= beautiful
.tooltip_font
or beautiful
.font
or "terminus 6"
150 --- Add tooltip to an object.
151 -- @param self The tooltip.
152 -- @param object An object.
153 local function add_to_object(self
, object
)
154 object
:add_signal("mouse::enter", data
[self
].show
)
155 object
:add_signal("mouse::leave", data
[self
].hide
)
158 --- Remove tooltip from an object.
159 -- @param self The tooltip.
160 -- @param object An object.
161 local function remove_from_object(self
, object
)
162 object
:remove_signal("mouse::enter", data
[self
].show
)
163 object
:remove_signal("mouse::leave", data
[self
].hide
)
167 --- Create a new tooltip and link it to a widget.
168 -- @param args Arguments for tooltip creation may containt:<br/>
169 -- <code>timeout</code>: The timeout value for update_func.<br/>
170 -- <code>timer_function</code>: A function to dynamicaly change the tooltip
172 -- <code>objects</code>: A list of objects linked to the tooltip.<br/>
173 -- @return The created tooltip.
174 -- @see add_to_object
177 local function new(args
)
183 local my_textbox
= widget({
185 name
= "tooltip_textbox",
190 show
= function() show(self
) end,
191 hide
= function() hide(self
) end
195 self
.set_text
= set_text
196 self
.set_timeout
= set_timeout
197 self
.add_to_object
= add_to_object
198 self
.remove_from_object
= remove_from_object
202 -- setup the timer action only if needed
203 if args
.timer_function
then
204 data
[self
].timer
= timer
{ timeout
= args
.timeout
and args
.timeout
or 1 }
205 data
[self
].timer_function
= function()
206 self
:set_text(args
.timer_function())
209 data
[self
].timer
:add_signal("timeout", data
[self
].timer_function
)
212 -- set tooltip properties
213 self
.wibox
.visible
= false
214 -- Who want a non ontop tooltip ?
215 self
.wibox
.ontop
= true
216 self
.wibox
.widgets
= { my_textbox
}
218 -- add some signals on both the tooltip and widget
219 self
.wibox
:add_signal("mouse::enter", data
[self
].hide
)
221 -- Add tooltip to objects
223 for _
, object
in ipairs(args
.objects
) do
224 self
:add_to_object(object
)
231 setmetatable(_M
, { __call
= function(_
, ...) return new(...) end })
233 -- vim: ft=lua:et:sw=4:ts=4:sts=4:enc=utf-8:tw=78