2013-05-01 22:25:52 +00:00
|
|
|
local modalbind = {}
|
|
|
|
local wibox = require("wibox")
|
2012-03-15 23:52:06 +00:00
|
|
|
local inited = false
|
|
|
|
local modewidget = {}
|
|
|
|
local modewibox = { screen = -1 }
|
2013-05-01 22:25:52 +00:00
|
|
|
local nesting = 0
|
2012-03-15 23:52:06 +00:00
|
|
|
|
|
|
|
--local functions
|
|
|
|
|
|
|
|
local defaults = {}
|
2013-04-13 15:17:09 +00:00
|
|
|
|
2012-03-15 23:52:06 +00:00
|
|
|
defaults.opacity = 1.0
|
|
|
|
defaults.height = 22
|
|
|
|
defaults.border_width = 1
|
2013-04-13 15:17:09 +00:00
|
|
|
defaults.x_offset = 0
|
|
|
|
defaults.y_offset = 0
|
2012-03-15 23:52:06 +00:00
|
|
|
defaults.show_options = true
|
|
|
|
|
|
|
|
-- Clone the defaults for the used settings
|
|
|
|
local settings = {}
|
|
|
|
for key, value in pairs(defaults) do
|
2013-04-13 15:17:09 +00:00
|
|
|
settings[key] = value
|
|
|
|
end
|
|
|
|
|
|
|
|
local function update_settings()
|
|
|
|
for s, value in ipairs(modewibox) do
|
|
|
|
value.border_width = settings.border_width
|
|
|
|
set_default(s)
|
|
|
|
value.opacity = settings.opacity
|
|
|
|
end
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2013-04-13 15:17:09 +00:00
|
|
|
--- Change the opacity of the modebox.
|
|
|
|
-- @param amount opacity between 0.0 and 1.0, or nil to use default
|
2013-05-01 22:25:52 +00:00
|
|
|
function set_opacity(amount)
|
2013-04-13 15:17:09 +00:00
|
|
|
settings.opacity = amount or defaults.opacity
|
|
|
|
update_settings()
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.set_opacity = set_opacity
|
2012-03-15 23:52:06 +00:00
|
|
|
|
2013-04-13 15:17:09 +00:00
|
|
|
--- Change height of the modebox.
|
|
|
|
-- @param amount height in pixels, or nil to use default
|
2013-05-01 22:25:52 +00:00
|
|
|
function set_height(amount)
|
2013-04-13 15:17:09 +00:00
|
|
|
settings.height = amount or defaults.height
|
|
|
|
update_settings()
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.set_height = set_height
|
2012-03-15 23:52:06 +00:00
|
|
|
|
2013-04-13 15:17:09 +00:00
|
|
|
--- Change border width of the modebox.
|
|
|
|
-- @param amount width in pixels, or nil to use default
|
2013-05-01 22:25:52 +00:00
|
|
|
function set_border_width(amount)
|
2013-04-13 15:17:09 +00:00
|
|
|
settings.border_width = amount or defaults.border_width
|
|
|
|
update_settings()
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.set_border_width = set_border_width
|
2012-03-15 23:52:06 +00:00
|
|
|
|
2013-04-13 15:17:09 +00:00
|
|
|
--- Change horizontal offset of the modebox.
|
|
|
|
-- set location for the box with set_corner(). The box is shifted to the right
|
|
|
|
-- if it is in one of the left corners or to the left otherwise
|
|
|
|
-- @param amount horizontal shift in pixels, or nil to use default
|
2013-05-01 22:25:52 +00:00
|
|
|
function set_x_offset (amount)
|
2013-04-13 15:17:09 +00:00
|
|
|
settings.x_offset = amount or defaults.x_offset
|
|
|
|
update_settings()
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.set_x_offset = set_x_offset
|
2012-03-15 23:52:06 +00:00
|
|
|
|
2013-04-13 15:17:09 +00:00
|
|
|
--- Change vertical offset of the modebox.
|
|
|
|
-- set location for the box with set_corner(). The box is shifted downwards if it
|
|
|
|
-- is in one of the upper corners or upwards otherwise.
|
|
|
|
-- @param amount vertical shift in pixels, or nil to use default
|
2013-05-01 22:25:52 +00:00
|
|
|
function set_y_offset(amount)
|
2013-04-13 15:17:09 +00:00
|
|
|
settings.y_offset = amount or defaults.y_offset
|
|
|
|
update_settings()
|
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.set_y_offset = set_y_offset
|
2013-04-13 15:17:09 +00:00
|
|
|
|
|
|
|
--- Set the corner, where the modebox will be displayed
|
|
|
|
-- If a parameter is not a valid orientation (see below), the function returns
|
|
|
|
-- without doing anything
|
|
|
|
-- @param vertical either top or bottom
|
|
|
|
-- @param horizontal either left or right
|
2013-05-01 22:25:52 +00:00
|
|
|
function set_corner(vertical, horizontal)
|
2013-04-13 15:17:09 +00:00
|
|
|
if (vertical ~= "top" and vertical ~= "bottom") then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if (horizontal ~= "left" and horizontal ~= "right") then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
settings.corner_v = vertical or defaults.corner_v
|
|
|
|
settings.corner_h = horizontal or defaults.corner_h
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.set_corner = set_corner
|
2012-03-15 23:52:06 +00:00
|
|
|
|
2013-05-01 22:25:52 +00:00
|
|
|
function set_show_options(bool)
|
2013-04-13 15:17:09 +00:00
|
|
|
settings.show_options = bool
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.set_show_options = set_show_options
|
2012-03-15 23:52:06 +00:00
|
|
|
|
2015-02-19 10:11:15 +00:00
|
|
|
local function set_default(s, position)
|
2013-04-13 15:17:09 +00:00
|
|
|
minwidth, minheight = modewidget[s]:fit(screen[s].geometry.width,
|
|
|
|
screen[s].geometry.height)
|
|
|
|
modewibox[s].width = minwidth + 1;
|
|
|
|
modewibox[s].height = math.max(settings.height, minheight)
|
2015-02-19 10:11:15 +00:00
|
|
|
if position then
|
|
|
|
modewibox[s].x = getXOffset(s, position)
|
|
|
|
modewibox[s].y = getYOffset(s, position)
|
|
|
|
else
|
|
|
|
modewibox[s].x = settings.x_offset < 0 and
|
|
|
|
screen[s].geometry.x - modewibox[s].width + settings.x_offset or
|
|
|
|
settings.x_offset
|
|
|
|
modewibox[s].y = screen[s].geometry.height - modewibox[s].height
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function getXOffset(s,position)
|
|
|
|
if type(position) == "table" then
|
|
|
|
return position.x
|
|
|
|
elseif position == "topleft" or position == "bottomleft" then
|
|
|
|
return 0
|
|
|
|
elseif position == "topright" or position == "bottomright" then
|
|
|
|
return screen[s].geometry.x - modewibox[s].width
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function getYOffset(s,position)
|
|
|
|
if type(position) == "table" then
|
|
|
|
return position.y
|
|
|
|
elseif position == "topleft" or position == "topright" then
|
|
|
|
return 0
|
|
|
|
elseif position == "bottomleft" or position == "bottomright" then
|
|
|
|
return screen[s].geometry.y - modewibox[s].height
|
|
|
|
end
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
|
|
|
|
2013-04-13 15:17:09 +00:00
|
|
|
local function ensure_init()
|
|
|
|
if inited then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
inited = true
|
|
|
|
for s = 1, screen.count() do
|
|
|
|
modewidget[s] = wibox.widget.textbox()
|
2014-04-25 13:13:31 +00:00
|
|
|
modewidget[s]:set_align("left")
|
2015-02-19 10:11:57 +00:00
|
|
|
if beautiful.fontface then
|
|
|
|
modewidget[s]:set_font(beautiful.fontface .. " " .. (beautiful.fontsize + 4))
|
|
|
|
end
|
2013-04-13 15:17:09 +00:00
|
|
|
|
|
|
|
modewibox[s] = wibox({
|
|
|
|
fg = beautiful.fg_normal,
|
|
|
|
bg = beautiful.bg_normal,
|
|
|
|
border_width = settings.border_width,
|
|
|
|
border_color = beautiful.bg_focus,
|
|
|
|
})
|
|
|
|
|
|
|
|
local modelayout = {}
|
|
|
|
modelayout[s] = wibox.layout.fixed.horizontal()
|
|
|
|
modelayout[s]:add(modewidget[s])
|
|
|
|
modewibox[s]:set_widget(modelayout[s]);
|
|
|
|
set_default(s)
|
|
|
|
modewibox[s].visible = false
|
|
|
|
modewibox[s].screen = s
|
|
|
|
modewibox[s].ontop = true
|
|
|
|
|
|
|
|
-- Widgets for prompt wibox
|
|
|
|
modewibox[s].widgets = {
|
|
|
|
modewidget[s],
|
|
|
|
layout = wibox.layout.fixed.horizontal
|
|
|
|
}
|
|
|
|
end
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
|
|
|
|
2014-04-25 13:13:31 +00:00
|
|
|
local function show_box(s, map, name)
|
2012-03-15 23:52:06 +00:00
|
|
|
ensure_init()
|
|
|
|
modewibox.screen = s
|
2014-04-25 13:13:31 +00:00
|
|
|
local label = "<b>" .. name .. "</b>"
|
2012-03-15 23:52:06 +00:00
|
|
|
if settings.show_options then
|
2014-04-25 13:13:31 +00:00
|
|
|
for key, mapping in pairs(map) do
|
|
|
|
label = label .. "\n<b>" .. key .. "</b>"
|
|
|
|
if type(mapping) == "table" then
|
|
|
|
label = label .. "\t" .. (mapping.desc or "???")
|
|
|
|
end
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
|
|
|
end
|
2014-04-25 13:13:31 +00:00
|
|
|
modewidget[s]:set_markup(label)
|
2013-04-13 15:17:09 +00:00
|
|
|
modewibox[s].visible = true
|
|
|
|
set_default(s)
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
|
|
|
|
2013-04-13 15:17:09 +00:00
|
|
|
local function hide_box()
|
2012-03-15 23:52:06 +00:00
|
|
|
local s = modewibox.screen
|
2013-04-13 15:17:09 +00:00
|
|
|
if s ~= -1 then modewibox[s].visible = false end
|
|
|
|
end
|
|
|
|
|
2014-04-25 13:13:31 +00:00
|
|
|
function grab(keymap, name, stay_in_mode)
|
|
|
|
if name then
|
|
|
|
show_box(mouse.screen, keymap, name)
|
2013-05-01 22:25:52 +00:00
|
|
|
nesting = nesting + 1
|
|
|
|
end
|
2013-04-13 15:17:09 +00:00
|
|
|
|
|
|
|
keygrabber.run(function(mod, key, event)
|
|
|
|
if key == "Escape" then
|
|
|
|
keygrabber.stop()
|
2013-05-01 22:25:52 +00:00
|
|
|
nesting = 0
|
2013-04-13 15:17:09 +00:00
|
|
|
hide_box();
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
if event == "release" then return true end
|
|
|
|
|
|
|
|
if keymap[key] then
|
|
|
|
keygrabber.stop()
|
2014-04-25 13:13:31 +00:00
|
|
|
if type(keymap[key]) == "table" then
|
|
|
|
keymap[key].func()
|
|
|
|
else
|
|
|
|
keymap[key]()
|
|
|
|
end
|
2013-04-13 15:17:09 +00:00
|
|
|
if stay_in_mode then
|
2014-05-16 16:17:10 +00:00
|
|
|
grab(keymap, name, true)
|
2013-04-13 15:17:09 +00:00
|
|
|
else
|
2013-05-01 22:25:52 +00:00
|
|
|
nesting = nesting - 1
|
|
|
|
if nesting < 1 then hide_box() end
|
2013-04-13 15:17:09 +00:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end)
|
2012-03-15 23:52:06 +00:00
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.grab = grab
|
|
|
|
|
2014-04-25 13:13:31 +00:00
|
|
|
function grabf(keymap, name, stay_in_mode)
|
|
|
|
return function() grab(keymap, name, stay_in_mode) end
|
2013-04-13 15:17:09 +00:00
|
|
|
end
|
2013-05-01 22:25:52 +00:00
|
|
|
modalbind.grabf = grabf
|
2013-04-13 15:17:09 +00:00
|
|
|
|
2013-05-01 22:25:52 +00:00
|
|
|
function modebox() return modewibox[1] end
|
|
|
|
modalbind.modebox = modebox
|
2012-03-15 23:52:06 +00:00
|
|
|
|
2013-05-01 22:25:52 +00:00
|
|
|
return modalbind
|