-
-
Save badosu/13b68ffe460aff233ce735e0817dd58b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local widget = widget ---@type Widget | |
| -- mouse_trigger (left|right|mmb) [halt_key] | <action> | |
| -- where halt_key (optional, default false) halts the key press chain on trigger | |
| -- best used with chain_actions widget for halting engine actions, e.g.: | |
| -- bind Any+ctrl mouse_trigger left | chain force select ... | |
| function widget:GetInfo() | |
| return { | |
| name = "Mouse Trigger Actions", | |
| desc = "Allows lua actions to be called from mouse triggers", | |
| author = "whoever_made_this_work,badosu", | |
| date = "October 2025", | |
| license = "GNU GPL, v2 or later", | |
| -- decision on layer: | |
| -- - 0 or lower for overriding game mousepress | |
| -- - highest to allow game to process the mousepress before action | |
| layer = 9999, | |
| enabled = true, | |
| handler = true, | |
| } | |
| end | |
| local activeModifiers = { | |
| [1] = {}, | |
| [2] = {}, | |
| [3] = {}, | |
| } | |
| -- not sure btw, mapping from argument name to button in MousePress | |
| local mouseButtonNameIndex = { | |
| left = 1, | |
| mmb = 2, | |
| right = 3, | |
| } | |
| -- FIXME: This does not handle multiple releases well, e.g.: | |
| -- bind any+1 mouse_trigger left | say hi | |
| -- press(1) -> active | |
| -- press(ctrl) -> active | |
| -- release(ctrl) -> inactive | |
| -- Should be active since 1 is still pressed | |
| -- Should be ok for most applications | |
| -- NOTE: Define: | |
| --array_bisect(array, index) | |
| --array_contains(array, entry) | |
| --array_add_unique(array, key, value) | |
| --array_remove_unique(array, key) | |
| --array_get_unique(array, key) | |
| --e.g.: | |
| --array_bisect({1, 2, 3, 4}, 2) -> {1}, {2, 3, 4} | |
| --array_contains({"halt"}, "halt") -> true | |
| --array_contains({"halt"}, "asd") -> false | |
| --local entries = {} | |
| --array_add_unique(entries, "1", 1) -> entries == {{"1", 1}} | |
| --array_add_unique(entries, "1", 1) -> entries == {{"1", 1}} | |
| --array_get_unique("1") -> 1 | |
| --array_remove_unique(entries, "1") -> entries == {} | |
| local function mouseModifierHandler(_, extra, _, _, _, isRelease) | |
| -- parses "left | asd bla | bla" | |
| -- actionExtra = "left" | |
| -- rest = "asd bla | bla" | |
| local actionExtra, rest = string.match(extra, "^(%S+)%s*|%s*(.+)") | |
| if rest == nil then | |
| Spring.Echo("<Trigger Actions> Error: invalid argument", extra) | |
| return false | |
| end | |
| local trigger, actionOpts = array_bisect(string.split(actionExtra, " "), 2) | |
| trigger = mouseButtonNameIndex[trigger[1]] | |
| if not activeModifiers[trigger] then | |
| Spring.Echo("<Trigger Actions> Error: invalid mouse argument", actionExtra) | |
| return false | |
| end | |
| if isRelease then | |
| array_remove_unique(activeModifiers[trigger], rest) | |
| return | |
| end | |
| local haltKey = array_contains(actionOpts, "halt_key") | |
| -- asd zxc blabla // xxx | |
| -- cmd = asd | |
| -- extra = blabla | |
| local cmd, cmdExtra = string.match(rest, "^(%w+)[%s]*(.*)(//.*)") | |
| local keyAction = { | |
| command = cmd, | |
| extra = cmdExtra, | |
| } | |
| -- Ensure uniqueness of entries, keypresses can retrigger same entry | |
| -- e.g. alt+1 triggers bind Any+1 two times on press(1), press(alt) | |
| array_add_unique(activeModifiers[trigger], rest, keyAction) | |
| -- we halt when halt_key is passed (i.e. we dont allow other actions to process) | |
| return haltKey | |
| end | |
| -- function widget:MousePress(x, y, button) | |
| function widget:MousePress(_, _, button) | |
| local modifiers = activeModifiers[button] | |
| if not next(modifiers) then | |
| return | |
| end | |
| local actions = {} | |
| for _, action in ipairs(modifiers) do | |
| table.insert(actions, action) | |
| end | |
| widgetHandler.actionHandler:KeyAction(true, nil, nil, nil, _, { actions }) | |
| end | |
| function widget:Initialize() | |
| widgetHandler.actionHandler:AddAction(self, "mouse_trigger", mouseModifierHandler, nil, "pr") | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment