awful.menu: Fix menu hide/show overloading
[awesome.git] / lib / awful / tooltip.lua.in
blobf282804755fbb7cc047c6d16775d6c44c7b92850
1 -------------------------------------------------------------------------
2 -- @author Sébastien Gross <seb•ɱɩɲʋʃ•awesome•ɑƬ•chezwam•ɖɵʈ•org&gt
3 -- @copyright 2009 Sébastien Gross
4 -- @release @AWESOME_VERSION@
5 -------------------------------------------------------------------------
7 local mouse = mouse
8 local widget = widget
9 local wibox = wibox
10 local screen = screen
11 local timer = timer
12 local a_placement = require("awful.placement")
13 local beautiful = require("beautiful")
14 local setmetatable = setmetatable
15 local ipairs = ipairs
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/>
24 -- <code>
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/>
30 -- end,<br/>
31 -- })<br/>
32 -- </code>
33 -- </p>
34 -- <p>How to add the same tooltip to several objects?<br/>
35 -- <code>
36 -- myclock_t:add_to_object(obj1)<br/>
37 -- myclock_t:add_to_object(obj2)<br/>
38 -- </code>
39 -- Now the same tooltip is attached to <code>K</code>, <code>obj1</code>,
40 -- <code>obj2</code>.<br/>
41 -- </p>
42 -- <p>How to remove tooltip from many objects?<br/>
43 -- <code>
44 -- myclock_t:remove_from_object(obj1)<br/>
45 -- myclock_t:remove_from_object(obj2)<br/>
46 -- </code>
47 -- Now the same tooltip is only attached to <code>K</code>.<br/>
48 -- </p>
49 module("awful.tooltip")
51 local data = setmetatable({}, { __mode = 'k' })
53 --- Tooltip object definition.
54 -- @name tooltip
55 -- @field wibox The wibox displaying the tooltip.
56 -- @field visible True if tooltip is visible.
57 -- @class table
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)
73 end
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)
83 place(self)
84 end
85 if not self.wibox.visible then
86 place(self)
87 end
88 end
90 -- Show a tooltip.
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()
103 set_geometry(self)
104 self.wibox.visible = true
105 self.visible = true
108 -- Hide a tooltip.
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()
118 self.visible = false
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
171 -- text.<br/>
172 -- <code>objects</code>: A list of objects linked to the tooltip.<br/>
173 -- @return The created tooltip.
174 -- @see add_to_object
175 -- @see set_timeout
176 -- @see set_text
177 local function new(args)
178 local self = {
179 wibox = wibox({ }),
180 visible = false,
183 local my_textbox = widget({
184 type = "textbox",
185 name = "tooltip_textbox",
186 align="right"})
188 -- private data
189 data[self] = {
190 show = function() show(self) end,
191 hide = function() hide(self) end
194 -- export functions
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
200 set_defaults(self)
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())
207 set_geometry(self)
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
222 if args.objects then
223 for _, object in ipairs(args.objects) do
224 self:add_to_object(object)
228 return self
231 setmetatable(_M, { __call = function(_, ...) return new(...) end })
233 -- vim: ft=lua:et:sw=4:ts=4:sts=4:enc=utf-8:tw=78