Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions localization/en-us.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,9 @@ return {
"Once per Ante",
"Off",
},
k_sc_title = "SHORTCUTS",
k_sc_hint = "Press key or release TAB to close",
b_sc_choose_deck = "Choose Deck/Stake",
loc_ready = "Ready for PvP",
loc_selecting = "Selecting a Blind",
loc_shop = "Shopping",
Expand Down
277 changes: 277 additions & 0 deletions ui/shortcuts_menu.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
-- TAB-hold shortcuts menu
-- Shows a context-aware overlay of quick actions while TAB is held

MP.SHORTCUTS = {
visible = false,
ui = nil,
}

-- Build the list of available shortcuts based on current state
local function get_shortcuts()
local shortcuts = {}
local in_lobby = MP.LOBBY.code ~= nil
local connected = MP.LOBBY.connected
local in_menu = G.STAGE == G.STAGES.MAIN_MENU

if in_menu then
if in_lobby then
table.insert(shortcuts, {
label = localize("b_copy_code"),
key = "C",
action = function()
MP.UTILS.copy_to_clipboard(MP.LOBBY.code)
end,
})
table.insert(shortcuts, {
label = localize("b_view_code"),
key = "V",
action = function()
MP.UI.UTILS.overlay_message(MP.LOBBY.code)
end,
})
if MP.LOBBY.is_host or MP.LOBBY.config.different_decks then
table.insert(shortcuts, {
label = localize("b_sc_choose_deck"),
key = "D",
action = function()
G.FUNCS.lobby_choose_deck({ config = {} })
end,
})
end
table.insert(shortcuts, {
label = localize("b_leave_lobby"),
key = "L",
action = function()
G.FUNCS.lobby_leave()
end,
})
elseif connected then
table.insert(shortcuts, {
label = localize("b_join_lobby_clipboard"),
key = "V",
action = function()
G.FUNCS.join_from_clipboard()
end,
})
table.insert(shortcuts, {
label = localize("b_join_lobby"),
key = "J",
action = function()
G.FUNCS.join_lobby()
end,
})
table.insert(shortcuts, {
label = localize("b_create_lobby"),
key = "C",
action = function()
G.FUNCS.create_lobby()
end,
})
else
table.insert(shortcuts, {
label = localize("b_reconnect"),
key = "R",
action = function()
G.FUNCS.reconnect()
end,
})
end
end

return shortcuts
end

-- Create the UI definition for the shortcuts overlay
local function create_shortcuts_ui(shortcuts)
local rows = {}

-- Header
table.insert(rows, {
n = G.UIT.R,
config = { align = "cm", padding = 0.08 },
nodes = {
{
n = G.UIT.T,
config = {
text = localize("k_sc_title"),
scale = 0.5,
colour = G.C.UI.TEXT_LIGHT,
shadow = true,
},
},
},
})

-- Shortcut rows
for _, sc in ipairs(shortcuts) do
table.insert(rows, {
n = G.UIT.R,
config = {
align = "cm",
padding = 0.04,
r = 0.08,
colour = G.C.L_BLACK,
hover = true,
button = "mp_shortcut_exec",
ref_table = sc,
},
nodes = {
{
n = G.UIT.C,
config = { align = "cm", minw = 1 },
nodes = {
{
n = G.UIT.R,
config = {
align = "cm",
padding = 0.04,
r = 0.05,
colour = G.C.PURPLE,
minw = 0.6,
},
nodes = {
{
n = G.UIT.T,
config = {
text = sc.key,
scale = 0.4,
colour = G.C.UI.TEXT_LIGHT,
shadow = true,
},
},
},
},
},
},
{
n = G.UIT.C,
config = { align = "cl", minw = 3.5 },
nodes = {
{
n = G.UIT.T,
config = {
text = " " .. sc.label,
scale = 0.38,
colour = G.C.UI.TEXT_LIGHT,
},
},
},
},
},
})
end

-- Footer hint
table.insert(rows, {
n = G.UIT.R,
config = { align = "cm", padding = 0.06 },
nodes = {
{
n = G.UIT.T,
config = {
text = localize("k_sc_hint"),
scale = 0.3,
colour = G.C.UI.TEXT_INACTIVE,
},
},
},
})

return {
n = G.UIT.ROOT,
config = {
align = "cl",
colour = { 0, 0, 0, 0.4 },
r = 0.15,
padding = 0.15,
minw = 5,
},
nodes = {
{
n = G.UIT.C,
config = { align = "cl", padding = 0.05 },
nodes = rows,
},
},
}
end

function G.FUNCS.mp_shortcut_exec(e)
if e.config.ref_table and e.config.ref_table.action then
MP.SHORTCUTS.hide()
e.config.ref_table.action()
end
end

function MP.SHORTCUTS.show()
if MP.SHORTCUTS.visible then return end

local shortcuts = get_shortcuts()
if #shortcuts == 0 then return end

MP.SHORTCUTS.visible = true
MP.SHORTCUTS.current_shortcuts = shortcuts

MP.SHORTCUTS.ui = UIBox({
definition = create_shortcuts_ui(shortcuts),
config = {
align = "cm",
offset = { x = -5, y = 0 },
major = G.ROOM_ATTACH,
bond = "Weak",
},
})
end

function MP.SHORTCUTS.hide()
if not MP.SHORTCUTS.visible then return end

MP.SHORTCUTS.visible = false
if MP.SHORTCUTS.ui then
MP.SHORTCUTS.ui:remove()
MP.SHORTCUTS.ui = nil
end
MP.SHORTCUTS.current_shortcuts = nil
end

-- Execute a shortcut by its key letter
function MP.SHORTCUTS.execute_key(key)
if not MP.SHORTCUTS.current_shortcuts then return false end

local upper_key = string.upper(key)
for _, sc in ipairs(MP.SHORTCUTS.current_shortcuts) do
if sc.key == upper_key then
MP.SHORTCUTS.hide()
sc.action()
return true
end
end
return false
end

-- Hook into Controller to detect TAB press and shortcut key presses
local key_press_update_ref = Controller.key_press_update
function Controller:key_press_update(key, dt)
-- Intercept shortcut key presses while menu is visible
if MP.SHORTCUTS.visible and #key == 1 then
if MP.SHORTCUTS.execute_key(key) then
return
end
end

if key == "tab" then
if not G.OVERLAY_MENU then
MP.SHORTCUTS.show()
return
end
end
key_press_update_ref(self, key, dt)
end

local key_release_update_ref = Controller.key_release_update
function Controller:key_release_update(key, dt)
if key == "tab" then
MP.SHORTCUTS.hide()
end
key_release_update_ref(self, key, dt)
end