123 lines
3.6 KiB
Lua
123 lines
3.6 KiB
Lua
---------------------------------------------------------------------------
|
|
-- @author Uli Schlachter
|
|
-- @copyright 2010 Uli Schlachter
|
|
-- @release @AWESOME_VERSION@
|
|
---------------------------------------------------------------------------
|
|
|
|
local object = require("gears.object")
|
|
local pairs = pairs
|
|
local error = error
|
|
local type = type
|
|
local table = table
|
|
|
|
module("wibox.widget.base")
|
|
|
|
--- Set/get a widget's buttons
|
|
function buttons(widget, buttons)
|
|
if buttons then
|
|
widget.widget_buttons = buttons
|
|
end
|
|
|
|
return widget.widget_buttons
|
|
end
|
|
|
|
--- Handle a button event on a widget. This is used internally.
|
|
function handle_button(event, widget, x, y, button, modifiers)
|
|
local function is_any(mod)
|
|
if #mod ~= 1 then
|
|
return false
|
|
end
|
|
if mod[1] ~= "Any" then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function tables_equal(a, b)
|
|
if #a ~= #b then
|
|
return false
|
|
end
|
|
for k, v in pairs(b) do
|
|
if a[k] ~= v then
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
-- Find all matching button objects
|
|
local matches = {}
|
|
for k, v in pairs(widget.widget_buttons) do
|
|
local match = true
|
|
-- Is it the right button?
|
|
if v.button ~= 0 and v.button ~= button then match = false end
|
|
-- Are the correct modifiers pressed?
|
|
if (not is_any(v.modifiers)) and (not tables_equal(v.modifiers, modifiers)) then match = false end
|
|
if match then
|
|
table.insert(matches, v)
|
|
end
|
|
end
|
|
|
|
-- Emit the signals
|
|
for k, v in pairs(matches) do
|
|
v:emit_signal(event)
|
|
end
|
|
end
|
|
|
|
--- Create a new widget. All widgets have to be generated via this function so
|
|
-- that the needed signals are added and mouse input handling is set up.
|
|
-- @param proxy If this is set, the returned widget will be a proxy for this
|
|
-- widget. It will be equivalent to this widget.
|
|
function make_widget(proxy)
|
|
local ret = object()
|
|
|
|
-- This signal is used by layouts to find out when they have to update.
|
|
ret:add_signal("widget::updated")
|
|
-- Mouse input, oh noes!
|
|
ret:add_signal("button::press")
|
|
ret:add_signal("button::release")
|
|
|
|
-- No buttons yet
|
|
ret.widget_buttons = {}
|
|
ret.buttons = buttons
|
|
|
|
-- Make buttons work
|
|
ret:connect_signal("button::press", function(...)
|
|
return handle_button("press", ...)
|
|
end)
|
|
ret:connect_signal("button::release", function(...)
|
|
return handle_button("release", ...)
|
|
end)
|
|
|
|
if proxy then
|
|
ret.size = function(_, ...) return proxy:size(...) end
|
|
ret.draw = function(_, ...) return proxy:draw(...) end
|
|
ret.fit = function(_, ...) return proxy:fit(...) end
|
|
proxy:connect_signal("widget::updated", function()
|
|
ret:emit_signal("widget::updated")
|
|
end)
|
|
end
|
|
|
|
return ret
|
|
end
|
|
|
|
--- Do some sanity checking on widget. This function raises a lua error if
|
|
-- widget is not a valid widget.
|
|
function check_widget(widget)
|
|
if type(widget) ~= "table" then
|
|
error("widget is not a table?!")
|
|
end
|
|
for k, func in pairs({ "draw", "fit", "add_signal", "connect_signal", "disconnect_signal" }) do
|
|
if type(widget[func]) ~= "function" then
|
|
error("widget's " .. func .. "() is not a function?!")
|
|
end
|
|
end
|
|
|
|
local width, height = widget:fit(0, 0)
|
|
if type(width) ~= "number" or type(height) ~= "number" then
|
|
error("widget's fit() didn't return two numbers")
|
|
end
|
|
end
|
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|