tooltip: Add position mode

This commit is contained in:
Emmanuel Lepage Vallee 2016-07-20 20:15:13 -04:00
parent 141b191921
commit bc3cbc44c9
1 changed files with 111 additions and 9 deletions

View File

@ -177,6 +177,35 @@ local function apply_shape(self)
wb:set_bgimage(img) wb:set_bgimage(img)
end end
local function apply_mouse_mode(self)
local w = self:get_wibox()
local align = self._private.align
local real_placement = align_convert[align]
a_placement[real_placement](w, {
parent = capi.mouse,
offset = offset[align]
})
end
local function apply_outside_mode(self)
local w = self:get_wibox()
local _, position = a_placement.next_to(w, {
geometry = self._private.widget_geometry,
preferred_positions = self.preferred_positions,
honor_workarea = true,
})
if position ~= self.current_position then
-- Re-apply the shape.
apply_shape(self)
end
self.current_position = position
end
-- Place the tooltip under the mouse.
-- --
-- @tparam tooltip self A tooltip object. -- @tparam tooltip self A tooltip object.
local function set_geometry(self) local function set_geometry(self)
@ -192,14 +221,13 @@ local function set_geometry(self)
apply_shape(self) apply_shape(self)
end end
local align = self._private.align local mode = self.mode
local real_placement = align_convert[align] if mode == "outside" and self._private.widget_geometry then
apply_outside_mode(self)
a_placement[real_placement](w, { else
parent = capi.mouse, apply_mouse_mode(self)
offset = offset[align] end
})
a_placement.no_offscreen(w) a_placement.no_offscreen(w)
end end
@ -331,6 +359,53 @@ function tooltip:set_shape(s, ...)
apply_shape(self) apply_shape(self)
end end
--- Set the tooltip positioning mode.
-- This affects how the tooltip is placed. By default, the tooltip is `align`ed
-- close to the mouse cursor. It is also possible to place the tooltip relative
-- to the widget geometry.
--
-- Valid modes are:
--
-- * "mouse": Next to the mouse cursor
-- * "outside": Outside of the widget
--
-- @property mode
-- @param string
function tooltip:set_mode(mode)
self._private.mode = mode
set_geometry(self)
self:emit_signal("property::mode")
end
function tooltip:get_mode()
return self._private.mode or "mouse"
end
--- The preferred positions when in `outside` mode.
--
-- If the tooltip fits on multiple sides of the drawable, then this defines the
-- priority
--
-- The default is:
--
-- {"top", "right", "left", "bottom"}
--
-- @property preferred_positions
-- @tparam table preferred_positions The position, ordered by priorities
function tooltip:get_preferred_positions()
return self._private.preferred_positions or
{"top", "right", "left", "bottom"}
end
function tooltip:set_preferred_positions(value)
self._private.preferred_positions = value
set_geometry(self)
end
--- Change displayed text. --- Change displayed text.
-- --
-- @property text -- @property text
@ -378,6 +453,8 @@ end
-- `mouse::leave` signals. -- `mouse::leave` signals.
-- @function add_to_object -- @function add_to_object
function tooltip:add_to_object(obj) function tooltip:add_to_object(obj)
if not obj then return end
obj:connect_signal("mouse::enter", self.show) obj:connect_signal("mouse::enter", self.show)
obj:connect_signal("mouse::leave", self.hide) obj:connect_signal("mouse::leave", self.hide)
end end
@ -393,6 +470,15 @@ function tooltip:remove_from_object(obj)
obj:disconnect_signal("mouse::leave", self.hide) obj:disconnect_signal("mouse::leave", self.hide)
end end
-- Tooltip can be applied to both widgets, wibox and client, their geometry
-- works differently.
local function get_parent_geometry(arg1, arg2)
if type(arg2) == "table" and arg2.width then
return arg2
elseif type(arg1) == "table" and arg1.width then
return arg1
end
end
--- Create a new tooltip and link it to a widget. --- Create a new tooltip and link it to a widget.
-- Tooltips emit `property::visible` when their visibility changes. -- Tooltips emit `property::visible` when their visibility changes.
@ -436,7 +522,15 @@ function tooltip.new(args)
delay_timeout:stop() delay_timeout:stop()
end) end)
function self.show() function self.show(other, geo)
-- Auto detect clients and wiboxes
if other.drawable or other.pid then
geo = other:geometry()
end
-- Cache the geometry in case it is needed later
self._private.widget_geometry = get_parent_geometry(other, geo)
if not delay_timeout.started then if not delay_timeout.started then
delay_timeout:start() delay_timeout:start()
end end
@ -448,7 +542,15 @@ function tooltip.new(args)
hide(self) hide(self)
end end
else else
function self.show() function self.show(other, geo)
-- Auto detect clients and wiboxes
if other.drawable or other.pid then
geo = other:geometry()
end
-- Cache the geometry in case it is needed later
self._private.widget_geometry = get_parent_geometry(other, geo)
show(self) show(self)
end end
function self.hide() function self.hide()