awful: Add a mouse finder capability
[awesome.git] / lib / awful / mouse / finder.lua.in
blobc72b45bd3e72fa268904d5cad20ab478d02b52a8
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 wibox = wibox
9 local screen = screen
10 local timer = timer
11 local a_placement = require("awful.placement")
12 local a_wibox = require("awful.wibox")
13 local beautiful = require("beautiful")
14 local setmetatable = setmetatable
16 --- Find the mouse pointer on the screen.
17 -- Mouse finder highlights the mouse cursor on the screen
18 -- <p>To enable this feature, a <code>awful.mouse.finder</code> object needs to
19 -- be bound to a key:<br/>
20 -- <code>mymousefinder = awful.mouse.finder()</code><br/>
21 -- Then bind the <code>find</code> function a key binding.
22 -- <p>Some configuration variable can be set in the theme:<br/>
23 -- The mouse_finder display duration<br/>
24 -- <code>theme.mouse_finder_timeout = 3</code><br/>
25 -- The animation speed<br/>
26 -- <code>theme.mouse_finder_animate_timeout = 0.05</code><br/>
27 -- The mouse_finder radius<br/>
28 -- <code>theme.mouse_finder_radius = 20</code><br/>
29 -- The growth factor<br/>
30 -- <code>theme.mouse_finder_factor = 2</code><br/>
31 -- The mouse_finder color<br/>
32 -- <code>theme.mouse_finder_color = "#ff0000"</code><br/>
33 -- </p>
34 module("awful.mouse.finder")
36 -- Mouse finder private data.
37 -- @name data
38 -- @field color Background color.
39 -- @field hide The hide() function.
40 -- @field show The show() function.
41 -- @field timer Timer to hide the mouse finder.
42 -- @field animate_timer Timer to animate the mouse finder.
43 -- @field wibox The mouse finder wibox show on the screen.
44 local data = setmetatable({}, { __mode = 'k' })
46 -- Place a mouse finder on the screen.
47 -- @param self A mouse finder object.
48 local function place(self)
49 a_placement.under_mouse(data[self].wibox)
50 a_placement.no_offscreen(data[self].wibox)
51 end
53 -- Animate a mouse finder.
54 -- @param self A mouse finder object.
55 local function animate(self)
56 local r = data[self].wibox:geometry().width
57 -- Check if the object should be grown or shrinked
58 -- the minimum radius is -data[self].factor because:
59 -- 1. factor is alway negative when shrinking
60 -- 2. geometry() does not hande negative values
61 if data[self].factor > 0 and r >= data[self].radius
62 or data[self].factor < 0 and r <= -data[self].factor then
63 data[self].factor = -data[self].factor
64 end
65 data[self].wibox:geometry({width = r + data[self].factor,
66 height = r + data[self].factor })
67 -- need -1 to the radius to draw a full circle
68 a_wibox.rounded_corners(data[self].wibox, (r + data[self].factor)/2 -1)
69 -- make sure the mouse finder follows the pointer. Uh!
70 place(self)
71 end
74 -- Show a mouse finder.
75 -- @param self The mouse finder to show.
76 local function show(self)
77 -- do nothing if the mouse finder is already shown
78 if data[self].wibox.visible then return end
79 if not data[self].timer.started then
80 -- make sure the mouse finder is on the same screen as the mouse
81 data[self].wibox.screen = mouse.screen
82 data[self].wibox:geometry({width = data[self].radius, height = data[self].radius })
83 a_wibox.rounded_corners(data[self].wibox, data[self].radius/2 -1)
84 data[self].timer:start()
85 data[self].animate_timer:start()
86 end
87 place(self)
88 data[self].wibox.visible = true
89 end
91 -- Hide a mouse finder.
92 -- @param self The mouse finder to hide.
93 local function hide(self)
94 -- do nothing if the mouse finder is already hidden
95 if not data[self].wibox.visible then return end
96 if data[self].timer.started then
97 data[self].timer:stop()
98 data[self].animate_timer:stop()
99 end
100 data[self].wibox.visible = false
103 -- Load Default values.
104 -- @param self A mouse finder object.
105 local function set_defaults(self)
106 data[self].wibox.border_width = 0
107 data[self].wibox.opacity = beautiful.mouse_finder_opacity or 1
108 data[self].wibox.bg = beautiful.mouse_finder_color or beautiful.bg_focus or "#ff0000"
109 data[self].timeout = beautiful.mouse_finder_timeout or 3
110 data[self].animate_timeout = beautiful.mouse_finder_animate_timeout or 0.05
111 data[self].radius = beautiful.mouse_finder_radius or 20
112 data[self].factor = beautiful.mouse_finder_factor or 2
115 --- Find the mouse on the screen
116 -- @param self A mouse finder object.
117 function find(self)
118 show(self)
121 --- Create a new mouse finder.
122 local function new()
123 local self = { }
124 -- private data
125 data[self] = {
126 wibox = wibox({ }),
127 show = function() show(self) end,
128 hide = function() hide(self) end,
129 animate = function() animate(self) end,
132 -- export functions
133 self.find = find
135 set_defaults(self)
137 -- setup the timer action only if needed
138 data[self].timer = timer { timeout = data[self].timeout }
139 data[self].animate_timer = timer { timeout = data[self].animate_timeout }
140 data[self].timer:add_signal("timeout", data[self].hide)
141 data[self].animate_timer:add_signal("timeout", data[self].animate)
142 data[self].wibox.ontop = true
143 data[self].wibox.visible = false
145 return self
148 setmetatable(_M, { __call = function(_, ...) return new(...) end })
150 -- vim: ft=lua:et:sw=4:ts=4:sts=4:enc=utf-8:tw=78