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
)
88 -- @param self The tooltip to show.
89 local function show(self
)
90 -- do nothing if the tooltip is already shown
91 if self
.visible
then return end
92 if data
[self
].timer
then
93 if not data
[self
].timer
.started
then
94 -- make sure the tooltip is on the same screen as the mouse
95 self
.wibox
.screen
= mouse
.screen
96 data
[self
].timer_function()
97 data
[self
].timer
:start()
101 self
.wibox
.visible
= true
106 -- @param self The tooltip to hide.
107 local function hide(self
)
108 -- do nothing if the tooltip is already hidden
109 if not self
.visible
then return end
110 if data
[self
].timer
then
111 if data
[self
].timer
.started
then
112 data
[self
].timer
:stop()
116 self
.wibox
.visible
= false
119 --- Change displayed text.
120 -- @param self The tooltip object.
121 -- @param text New tooltip text.
122 local function set_text(self
, text
)
123 self
.wibox
.widgets
[1].text
= '<span color="' .. data
[self
].fg
124 .. '" font_desc="' .. data
[self
].font
.. '">' .. text
.. "</span>"
127 --- Change the tooltip's update interval.
128 -- @param self A tooltip object.
129 -- @param timeout The timeout value.
130 local function set_timeout(self
, timeout
)
131 if data
[self
].timer
then
132 data
[self
].timer
.timeout
= timeout
136 -- Load Default values.
137 -- @param self A tooltip object.
138 local function set_defaults(self
)
139 self
.wibox
.border_width
= beautiful
.tooltip_border_width
or beautiful
.border_width
or 1
140 self
.wibox
.border_color
= beautiful
.tooltip_border_color
or beautiful
.border_normal
or "#ffcb60"
141 self
.wibox
.opacity
= beautiful
.tooltip_opacity
or 1
142 self
.wibox
.bg
= beautiful
.tooltip_bg_color
or beautiful
.bg_focus
or "#ffcb60"
143 data
[self
].fg
= beautiful
.tooltip_fg_color
or beautiful
.fg_focus
or "#000000"
144 data
[self
].font
= beautiful
.tooltip_font
or beautiful
.font
or "terminus 6"
147 --- Add tooltip to an object.
148 -- @param self The tooltip.
149 -- @param object An object.
150 local function add_to_object(self
, object
)
151 object
:add_signal("mouse::enter", data
[self
].show
)
152 object
:add_signal("mouse::leave", data
[self
].hide
)
155 --- Remove tooltip from an object.
156 -- @param self The tooltip.
157 -- @param object An object.
158 local function remove_from_object(self
, object
)
159 object
:remove_signal("mouse::enter", data
[self
].show
)
160 object
:remove_signal("mouse::leave", data
[self
].hide
)
164 --- Create a new tooltip and link it to a widget.
165 -- @param args Arguments for tooltip creation may containt:<br/>
166 -- <code>timeout</code>: The timeout value for update_func.<br/>
167 -- <code>timer_function</code>: A function to dynamicaly change the tooltip
169 -- <code>objects</code>: A list of objects linked to the tooltip.<br/>
170 -- @return The created tooltip.
171 -- @see add_to_object
174 local function new(args
)
180 local my_textbox
= widget({
182 name
= "tooltip_textbox",
187 show
= function() show(self
) end,
188 hide
= function() hide(self
) end
192 self
.set_text
= set_text
193 self
.set_timeout
= set_timeout
194 self
.add_to_object
= add_to_object
195 self
.remove_from_object
= remove_from_object
199 -- setup the timer action only if needed
200 if args
.timer_function
then
201 data
[self
].timer
= timer
{ timeout
= args
.timeout
and args
.timeout
or 1 }
202 data
[self
].timer_function
= function()
203 self
:set_text(args
.timer_function())
206 data
[self
].timer
:add_signal("timeout", data
[self
].timer_function
)
209 -- set tooltip properties
210 self
.wibox
.visible
= false
211 -- Who want a non ontop tooltip ?
212 self
.wibox
.ontop
= true
213 self
.wibox
.widgets
= { my_textbox
}
215 -- add some signals on both the tooltip and widget
216 self
.wibox
:add_signal("mouse::enter", data
[self
].hide
)
218 -- Add tooltip to objects
220 for _
, object
in ipairs(args
.objects
) do
221 self
:add_to_object(object
)
228 setmetatable(_M
, { __call
= function(_
, ...) return new(...) end })
230 -- vim: ft=lua:et:sw=4:ts=4:sts=4:enc=utf-8:tw=78