1 -------------------------------------------------------------------------
2 -- @author Sébastien Gross <seb•ɱɩɲʋʃ•awesome•ɑƬ•chezwam•ɖɵʈ•org>
3 -- @copyright 2009 Sébastien Gross
4 -- @release @AWESOME_VERSION@
5 -------------------------------------------------------------------------
10 local wibox
= require("wibox")
11 local a_placement
= require("awful.placement")
12 local beautiful
= require("beautiful")
13 local textbox
= require("wibox.widget.textbox")
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>connect_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 = { myclock },<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>myclock</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>myclock</code>.<br/>
50 local tooltip
= { mt
= {} }
52 local data
= setmetatable({}, { __mode
= 'k' })
54 --- Tooltip object definition.
56 -- @field wibox The wibox displaying the tooltip.
57 -- @field visible True if tooltip is visible.
60 -- Tooltip private data.
61 -- @name awful.tooltip.data
62 -- @field fg tooltip foreground color.
63 -- @field font Tooltip font.
64 -- @field hide The hide() function.
65 -- @field show The show() function.
66 -- @field timer The text update timer.
67 -- @field timer_function The text update timer function.
69 -- Place to tooltip on th screen.
70 -- @param self A tooltip object.
71 local function place(self
)
72 a_placement
.under_mouse(self
.wibox
)
73 a_placement
.no_offscreen(self
.wibox
)
76 -- Place the tooltip under the mouse.
77 -- @param self A tooltip object.
78 local function set_geometry(self
)
79 local my_geo
= self
.wibox
:geometry()
80 -- calculate width / height
81 local n_w
, n_h
= self
.widget
:fit(-1, -1)
82 if my_geo
.width
~= n_w
or my_geo
.height
~= n_h
then
83 self
.wibox
:geometry({ width
= n_w
, height
= n_h
})
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 data
[self
].timer_function()
95 data
[self
].timer
:start()
100 self
.wibox
.visible
= true
105 -- @param self The tooltip to hide.
106 local function hide(self
)
107 -- do nothing if the tooltip is already hidden
108 if not self
.visible
then return end
109 if data
[self
].timer
then
110 if data
[self
].timer
.started
then
111 data
[self
].timer
:stop()
115 self
.wibox
.visible
= false
118 --- Change displayed text.
119 -- @param self The tooltip object.
120 -- @param text New tooltip text.
121 local function set_text(self
, text
)
122 self
.widget
:set_font(data
[self
].font
)
123 self
.widget
:set_markup('<span color="' .. data
[self
].fg
124 .. '">' .. text
.. "</span>")
128 --- Change the tooltip's update interval.
129 -- @param self A tooltip object.
130 -- @param timeout The timeout value.
131 local function set_timeout(self
, timeout
)
132 if data
[self
].timer
then
133 data
[self
].timer
.timeout
= timeout
137 -- Load Default values.
138 -- @param self A tooltip object.
139 local function set_defaults(self
)
140 self
.wibox
.border_width
= beautiful
.tooltip_border_width
or beautiful
.border_width
or 1
141 self
.wibox
.border_color
= beautiful
.tooltip_border_color
or beautiful
.border_normal
or "#ffcb60"
142 self
.wibox
.opacity
= beautiful
.tooltip_opacity
or 1
143 self
.wibox
:set_bg(beautiful
.tooltip_bg_color
or beautiful
.bg_focus
or "#ffcb60")
144 data
[self
].fg
= beautiful
.tooltip_fg_color
or beautiful
.fg_focus
or "#000000"
145 data
[self
].font
= beautiful
.tooltip_font
or beautiful
.font
or "terminus 6"
148 --- Add tooltip to an object.
149 -- @param self The tooltip.
150 -- @param object An object.
151 local function add_to_object(self
, object
)
152 object
:connect_signal("mouse::enter", data
[self
].show
)
153 object
:connect_signal("mouse::leave", data
[self
].hide
)
156 --- Remove tooltip from an object.
157 -- @param self The tooltip.
158 -- @param object An object.
159 local function remove_from_object(self
, object
)
160 object
:disconnect_signal("mouse::enter", data
[self
].show
)
161 object
:disconnect_signal("mouse::leave", data
[self
].hide
)
165 --- Create a new tooltip and link it to a widget.
166 -- @param args Arguments for tooltip creation may containt:<br/>
167 -- <code>timeout</code>: The timeout value for update_func.<br/>
168 -- <code>timer_function</code>: A function to dynamically change the tooltip
170 -- <code>objects</code>: A list of objects linked to the tooltip.<br/>
171 -- @return The created tooltip.
172 -- @see add_to_object
175 local function new(args
)
181 local my_textbox
= textbox()
185 show
= function() show(self
) end,
186 hide
= function() hide(self
) end
190 self
.set_text
= set_text
191 self
.set_timeout
= set_timeout
192 self
.add_to_object
= add_to_object
193 self
.remove_from_object
= remove_from_object
197 -- setup the timer action only if needed
198 if args
.timer_function
then
199 data
[self
].timer
= timer
{ timeout
= args
.timeout
and args
.timeout
or 1 }
200 data
[self
].timer_function
= function()
201 self
:set_text(args
.timer_function())
203 data
[self
].timer
:connect_signal("timeout", data
[self
].timer_function
)
206 -- set tooltip properties
207 self
.wibox
.visible
= false
208 -- Who wants a non ontop tooltip ?
209 self
.wibox
.ontop
= true
210 self
.wibox
:set_widget(my_textbox
)
211 self
.widget
= my_textbox
213 -- add some signals on both the tooltip and widget
214 self
.wibox
:connect_signal("mouse::enter", data
[self
].hide
)
216 -- Add tooltip to objects
218 for _
, object
in ipairs(args
.objects
) do
219 self
:add_to_object(object
)
226 function tooltip
.mt
:__call(...)
230 return setmetatable(tooltip
, tooltip
.mt
)
232 -- vim: ft=lua:et:sw=4:ts=4:sts=4:enc=utf-8:tw=78