mirror of https://github.com/einverne/dotfiles.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
6.6 KiB
189 lines
6.6 KiB
--- === ModalMgr === |
|
--- |
|
--- Modal keybindings environment management. Just an wrapper of `hs.hotkey.modal`. |
|
--- |
|
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/ModalMgr.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/ModalMgr.spoon.zip) |
|
|
|
local obj = {} |
|
obj.__index = obj |
|
|
|
-- Metadata |
|
obj.name = "ModalMgr" |
|
obj.version = "1.0" |
|
obj.author = "ashfinal <[email protected]>" |
|
obj.homepage = "https://github.com/Hammerspoon/Spoons" |
|
obj.license = "MIT - https://opensource.org/licenses/MIT" |
|
|
|
obj.modal_tray = nil |
|
obj.which_key = nil |
|
obj.modal_list = {} |
|
obj.active_list = {} |
|
obj.supervisor = nil |
|
|
|
function obj:init() |
|
hsupervisor_keys = hsupervisor_keys or {{"cmd", "shift", "ctrl"}, "Q"} |
|
obj.supervisor = hs.hotkey.modal.new(hsupervisor_keys[1], hsupervisor_keys[2], 'Initialize Modal Environment') |
|
obj.supervisor:bind(hsupervisor_keys[1], hsupervisor_keys[2], "Reset Modal Environment", function() obj.supervisor:exit() end) |
|
hshelp_keys = hshelp_keys or {{"alt", "shift"}, "/"} |
|
obj.supervisor:bind(hshelp_keys[1], hshelp_keys[2], "Toggle Help Panel", function() obj:toggleCheatsheet({all=obj.supervisor}) end) |
|
obj.modal_tray = hs.canvas.new({x = 0, y = 0, w = 0, h = 0}) |
|
obj.modal_tray:level(hs.canvas.windowLevels.tornOffMenu) |
|
obj.modal_tray[1] = { |
|
type = "circle", |
|
action = "fill", |
|
fillColor = {hex = "#FFFFFF", alpha = 0.7}, |
|
} |
|
obj.which_key = hs.canvas.new({x = 0, y = 0, w = 0, h = 0}) |
|
obj.which_key:level(hs.canvas.windowLevels.tornOffMenu) |
|
obj.which_key[1] = { |
|
type = "rectangle", |
|
action = "fill", |
|
fillColor = {hex = "#EEEEEE", alpha = 0.95}, |
|
roundedRectRadii = {xRadius = 10, yRadius = 10}, |
|
} |
|
end |
|
|
|
--- ModalMgr:new(id) |
|
--- Method |
|
--- Create a new modal keybindings environment |
|
--- |
|
--- Parameters: |
|
--- * id - A string specifying ID of new modal keybindings |
|
|
|
function obj:new(id) |
|
obj.modal_list[id] = hs.hotkey.modal.new() |
|
end |
|
|
|
--- ModalMgr:toggleCheatsheet([idList], [force]) |
|
--- Method |
|
--- Toggle the cheatsheet display of current modal environments's keybindings. |
|
--- |
|
--- Parameters: |
|
--- * iterList - An table specifying IDs of modal environments or active_list. Optional, defaults to all active environments. |
|
--- * force - A optional boolean value to force show cheatsheet, defaults to `nil` (automatically). |
|
|
|
function obj:toggleCheatsheet(iterList, force) |
|
if obj.which_key:isShowing() and not force then |
|
obj.which_key:hide() |
|
else |
|
local cscreen = hs.screen.mainScreen() |
|
local cres = cscreen:fullFrame() |
|
obj.which_key:frame({ |
|
x = cres.x + cres.w / 5, |
|
y = cres.y + cres.h / 5, |
|
w = cres.w / 5 * 3, |
|
h = cres.h / 5 * 3 |
|
}) |
|
local keys_pool = {} |
|
local tmplist = iterList or obj.active_list |
|
for i, v in pairs(tmplist) do |
|
if type(v) == "string" then |
|
-- It appears to be idList |
|
for _, m in ipairs(obj.modal_list[v].keys) do |
|
table.insert(keys_pool, m.msg) |
|
end |
|
elseif type(i) == "string" then |
|
-- It appears to be active_list |
|
for _, m in pairs(v.keys) do |
|
table.insert(keys_pool, m.msg) |
|
end |
|
end |
|
end |
|
for idx, val in ipairs(keys_pool) do |
|
if idx % 2 == 1 then |
|
obj.which_key[idx + 1] = { |
|
type = "text", |
|
text = keys_pool[idx], |
|
textFont = "Courier-Bold", |
|
textSize = 16, |
|
textColor = {hex = "#2390FF", alpha = 1}, |
|
textAlignment = "left", |
|
frame = { |
|
x = tostring(40 / (cres.w / 5 * 3)), |
|
y = tostring((30 + (idx - math.ceil(idx / 2)) * math.ceil((cres.h / 5 * 3 - 60) / #keys_pool) * 2) / (cres.h / 5 * 3)), |
|
w = tostring((1 - 80 / (cres.w / 5 * 3)) / 2), |
|
h = tostring(math.ceil((cres.h / 5 * 3 - 60) / #keys_pool) * 2 / (cres.h / 5 * 3)) |
|
} |
|
} |
|
else |
|
obj.which_key[idx + 1] = { |
|
type = "text", |
|
text = keys_pool[idx], |
|
textFont = "Courier-Bold", |
|
textSize = 16, |
|
textColor = {hex = "#2390FF"}, |
|
textAlignment = "right", |
|
frame = { |
|
x = "50%", |
|
y = tostring((30 + (idx - math.ceil(idx / 2) - 1) * math.ceil((cres.h / 5 * 3 - 60) / #keys_pool) * 2) / (cres.h / 5 * 3)), |
|
w = tostring((1 - 80 / (cres.w / 5 * 3)) / 2), |
|
h = tostring(math.ceil((cres.h / 5 * 3 - 60) / #keys_pool) * 2 / (cres.h / 5 * 3)) |
|
} |
|
} |
|
end |
|
end |
|
obj.which_key:show() |
|
end |
|
end |
|
|
|
--- ModalMgr:activate(idList, [trayColor], [showKeys]) |
|
--- Method |
|
--- Activate all modal environment in `idList`. |
|
--- |
|
--- Parameters: |
|
--- * idList - An table specifying IDs of modal environments |
|
--- * trayColor - An optional string (e.g. #000000) specifying the color of modalTray, defaults to `nil`. |
|
--- * showKeys - A optional boolean value to show all available keybindings, defaults to `nil`. |
|
|
|
function obj:activate(idList, trayColor, showKeys) |
|
for _, val in ipairs(idList) do |
|
obj.modal_list[val]:enter() |
|
obj.active_list[val] = obj.modal_list[val] |
|
end |
|
if trayColor then |
|
local cscreen = hs.screen.mainScreen() |
|
local cres = cscreen:fullFrame() |
|
local lcres = cscreen:absoluteToLocal(cres) |
|
obj.modal_tray:frame(cscreen:localToAbsolute{ |
|
x = cres.w - 40, |
|
y = cres.h - 40, |
|
w = 20, |
|
h = 20 |
|
}) |
|
obj.modal_tray[1].fillColor = {hex = trayColor, alpha = 0.7} |
|
obj.modal_tray:show() |
|
end |
|
if showKeys then |
|
obj:toggleCheatsheet(idList, true) |
|
end |
|
end |
|
|
|
--- ModalMgr:deactivate(idList) |
|
--- Method |
|
--- Deactivate modal environments in `idList`. |
|
--- |
|
--- Parameters: |
|
--- * idList - An table specifying IDs of modal environments |
|
|
|
function obj:deactivate(idList) |
|
for _, val in ipairs(idList) do |
|
obj.modal_list[val]:exit() |
|
obj.active_list[val] = nil |
|
end |
|
obj.modal_tray:hide() |
|
for i = 2, #obj.which_key do |
|
obj.which_key:removeElement(2) |
|
end |
|
obj.which_key:hide() |
|
end |
|
|
|
--- ModalMgr:deactivateAll() |
|
--- Method |
|
--- Deactivate all active modal environments. |
|
--- |
|
|
|
function obj:deactivateAll() |
|
obj:deactivate(obj.active_list) |
|
end |
|
|
|
return obj
|
|
|