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 background
= require("wibox.widget.background")
15 local setmetatable
= setmetatable
18 --- Tooltip module for awesome objects.
19 -- A tooltip is a small hint displayed when the mouse cursor
20 -- hovers a specific item.
21 -- In awesome, a tooltip can be linked with almost any
22 -- object having a <code>connect_signal()</code> method and receiving
23 -- <code>mouse::enter</code> and <code>mouse::leave</code> signals.
24 -- <p>How to create a tooltip?<br/>
26 -- myclock = awful.widget.textclock({}, "%T", 1)<br/>
27 -- myclock_t = awful.tooltip({<br/>
28 -- objects = { myclock },<br/>
29 -- timer_function = function()<br/>
30 -- return os.date("Today is %A %B %d %Y\nThe time is %T")<br/>
35 -- <p>How to add the same tooltip to several objects?<br/>
37 -- myclock_t:add_to_object(obj1)<br/>
38 -- myclock_t:add_to_object(obj2)<br/>
40 -- Now the same tooltip is attached to <code>myclock</code>, <code>obj1</code>,
41 -- <code>obj2</code>.<br/>
43 -- <p>How to remove tooltip from many objects?<br/>
45 -- myclock_t:remove_from_object(obj1)<br/>
46 -- myclock_t:remove_from_object(obj2)<br/>
48 -- Now the same tooltip is only attached to <code>myclock</code>.<br/>
51 local tooltip
= { mt
= {} }
53 local data
= setmetatable({}, { __mode
= 'k' })
55 --- Tooltip object definition.
57 -- @field wibox The wibox displaying the tooltip.
58 -- @field visible True if tooltip is visible.
61 -- Tooltip private data.
62 -- @name awful.tooltip.data
63 -- @field fg tooltip foreground color.
64 -- @field font Tooltip font.
65 -- @field hide The hide() function.
66 -- @field show The show() function.
67 -- @field timer The text update timer.
68 -- @field timer_function The text update timer function.
70 -- Place to tooltip on th screen.
71 -- @param self A tooltip object.
72 local function place(self
)
73 a_placement
.under_mouse(self
.wibox
)
74 a_placement
.no_offscreen(self
.wibox
)
77 -- Place the tooltip under the mouse.
78 -- @param self A tooltip object.
79 local function set_geometry(self
)
80 local my_geo
= self
.wibox
:geometry()
81 -- calculate width / height
82 local n_w
, n_h
= self
.textbox
:fit(-1, -1)
83 if my_geo
.width
~= n_w
or my_geo
.height
~= n_h
then
84 self
.wibox
:geometry({ width
= n_w
, height
= n_h
})
89 -- @param self The tooltip to show.
90 local function show(self
)
91 -- do nothing if the tooltip is already shown
92 if self
.visible
then return end
93 if data
[self
].timer
then
94 if not data
[self
].timer
.started
then
95 data
[self
].timer_function()
96 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
.textbox
:set_text(text
)
127 --- Change displayed text.
128 -- @param self The tooltip object.
129 -- @param text New tooltip text, including pango markup.
130 local function set_markup(self
, text
)
131 self
.textbox
:set_markup(text
)
135 --- Change the tooltip's update interval.
136 -- @param self A tooltip object.
137 -- @param timeout The timeout value.
138 local function set_timeout(self
, timeout
)
139 if data
[self
].timer
then
140 data
[self
].timer
.timeout
= timeout
144 --- Add tooltip to an object.
145 -- @param self The tooltip.
146 -- @param object An object.
147 local function add_to_object(self
, object
)
148 object
:connect_signal("mouse::enter", data
[self
].show
)
149 object
:connect_signal("mouse::leave", data
[self
].hide
)
152 --- Remove tooltip from an object.
153 -- @param self The tooltip.
154 -- @param object An object.
155 local function remove_from_object(self
, object
)
156 object
:disconnect_signal("mouse::enter", data
[self
].show
)
157 object
:disconnect_signal("mouse::leave", data
[self
].hide
)
161 --- Create a new tooltip and link it to a widget.
162 -- @param args Arguments for tooltip creation may containt:<br/>
163 -- <code>timeout</code>: The timeout value for update_func.<br/>
164 -- <code>timer_function</code>: A function to dynamically change the tooltip
166 -- <code>objects</code>: A list of objects linked to the tooltip.<br/>
167 -- @return The created tooltip.
168 -- @see add_to_object
172 local function new(args
)
180 show
= function() show(self
) end,
181 hide
= function() hide(self
) end
185 self
.set_text
= set_text
186 self
.set_markup
= set_markup
187 self
.set_timeout
= set_timeout
188 self
.add_to_object
= add_to_object
189 self
.remove_from_object
= remove_from_object
191 -- setup the timer action only if needed
192 if args
.timer_function
then
193 data
[self
].timer
= timer
{ timeout
= args
.timeout
and args
.timeout
or 1 }
194 data
[self
].timer_function
= function()
195 self
:set_markup(args
.timer_function())
197 data
[self
].timer
:connect_signal("timeout", data
[self
].timer_function
)
200 -- Set default properties
201 self
.wibox
.border_width
= beautiful
.tooltip_border_width
or beautiful
.border_width
or 1
202 self
.wibox
.border_color
= beautiful
.tooltip_border_color
or beautiful
.border_normal
or "#ffcb60"
203 self
.wibox
.opacity
= beautiful
.tooltip_opacity
or 1
204 self
.wibox
:set_bg(beautiful
.tooltip_bg_color
or beautiful
.bg_focus
or "#ffcb60")
205 local fg
= beautiful
.tooltip_fg_color
or beautiful
.fg_focus
or "#000000"
206 local font
= beautiful
.tooltip_font
or beautiful
.font
or "terminus 6"
208 -- set tooltip properties
209 self
.wibox
.visible
= false
210 -- Who wants a non ontop tooltip ?
211 self
.wibox
.ontop
= true
212 self
.textbox
= textbox()
213 self
.textbox
:set_font(font
)
214 self
.background
= background(self
.textbox
)
215 self
.background
:set_fg(fg
)
216 self
.wibox
:set_widget(self
.background
)
218 -- add some signals on both the tooltip and widget
219 self
.wibox
:connect_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 function tooltip
.mt
:__call(...)
235 return setmetatable(tooltip
, tooltip
.mt
)
237 -- vim: ft=lua:et:sw=4:ts=4:sts=4:enc=utf-8:tw=78