diff --git a/cont/LuaUI/callins.lua b/cont/LuaUI/callins.lua index 944da0111d..e46eea367a 100644 --- a/cont/LuaUI/callins.lua +++ b/cont/LuaUI/callins.lua @@ -15,6 +15,7 @@ CallInsList = { "Shutdown", "LayoutButtons", "ConfigureLayout", + "ActiveCommandSet", "CommandNotify", "KeyMapChanged", diff --git a/cont/LuaUI/main.lua b/cont/LuaUI/main.lua index dc4c5e2243..04df76ddc4 100644 --- a/cont/LuaUI/main.lua +++ b/cont/LuaUI/main.lua @@ -97,6 +97,10 @@ function ConfigureLayout(command) return widgetHandler:ConfigureLayout(command) end +function ActiveCommandSet(id, cmdType) + return widgetHandler:ActiveCommandSet(id, cmdType) +end + function CommandNotify(id, params, options) return widgetHandler:CommandNotify(id, params, options) end diff --git a/cont/LuaUI/widgets.lua b/cont/LuaUI/widgets.lua index 99604a9a62..9cb090bb0c 100644 --- a/cont/LuaUI/widgets.lua +++ b/cont/LuaUI/widgets.lua @@ -184,6 +184,7 @@ local callInLists = { 'Shutdown', 'Update', 'TextCommand', + 'ActiveCommandSet', 'CommandNotify', 'AddConsoleLine', 'ViewResize', @@ -1182,6 +1183,13 @@ function widgetHandler:ConfigureLayout(command) end +function widgetHandler:ActiveCommandSet(id, cmdType) + for _,w in ipairs(self.ActiveCommandSetList) do + w:ActiveCommandSet(id, cmdType) + end +end + + function widgetHandler:CommandNotify(id, params, options) for _,w in ipairs(self.CommandNotifyList) do if (w:CommandNotify(id, params, options)) then diff --git a/cont/base/springcontent/LuaGadgets/callins.lua b/cont/base/springcontent/LuaGadgets/callins.lua index ebd2093ff3..fd5c100925 100644 --- a/cont/base/springcontent/LuaGadgets/callins.lua +++ b/cont/base/springcontent/LuaGadgets/callins.lua @@ -176,6 +176,7 @@ CALLIN_LIST = { "RecvSkirmishAIMessage", "DefaultCommand", + "ActiveCommandSet", "CommandNotify", "ViewResize", -- FIXME ? diff --git a/cont/base/springcontent/LuaGadgets/gadgets.lua b/cont/base/springcontent/LuaGadgets/gadgets.lua index 3c59411c31..789a97a948 100644 --- a/cont/base/springcontent/LuaGadgets/gadgets.lua +++ b/cont/base/springcontent/LuaGadgets/gadgets.lua @@ -1844,6 +1844,12 @@ function gadgetHandler:DefaultCommand(type, id, cmd) end end +function gadgetHandler:ActiveCommandSet(id, cmdType) + for _,g in r_ipairs(self.ActiveCommandSetList) do + g:ActiveCommandSet(id, cmdType) + end +end + function gadgetHandler:CommandNotify(id, params, options) for _,g in r_ipairs(self.CommandNotifyList) do if (g:CommandNotify(id, params, options)) then diff --git a/rts/Game/UI/GuiHandler.cpp b/rts/Game/UI/GuiHandler.cpp index acf36c3a86..8901d1b609 100644 --- a/rts/Game/UI/GuiHandler.cpp +++ b/rts/Game/UI/GuiHandler.cpp @@ -542,6 +542,7 @@ void CGuiHandler::RevertToCmdDesc(const SCommandDescription& cmdDesc, bool defaultCommand, bool samePage) { RECOIL_DETAILED_TRACY_ZONE; + int newInCommand = inCommand; for (size_t a = 0; a < commands.size(); ++a) { if (commands[a].id != cmdDesc.id) continue; @@ -551,7 +552,7 @@ void CGuiHandler::RevertToCmdDesc(const SCommandDescription& cmdDesc, return; } - inCommand = a; + newInCommand = a; if (commands[a].type == CMDTYPE_ICON_BUILDING) { const UnitDef* ud = unitDefHandler->GetUnitDefByID(-commands[a].id); @@ -564,13 +565,14 @@ void CGuiHandler::RevertToCmdDesc(const SCommandDescription& cmdDesc, continue; for (int ii = 0; ii < iconsCount; ii++) { - if (inCommand != icons[ii].commandsID) + if (newInCommand != icons[ii].commandsID) continue; activePage = std::min(maxPage, (ii / iconsPerPage)); selectedUnitsHandler.SetCommandPage(activePage); } } + SetActiveCommandIndex(newInCommand); } @@ -598,7 +600,7 @@ void CGuiHandler::LayoutIcons(bool useSelectionPage) useSelectionPage = useSelectionPage && !samePage; // reset some of our state - inCommand = -1; + SetActiveCommandIndex(-1); defaultCmdMemory = -1; forceLayoutUpdate = false; @@ -1042,7 +1044,7 @@ void CGuiHandler::Update() { if (!invertQueueKey && (needShift && !KeyInput::GetKeyModState(KMOD_SHIFT))) { SetShowingMetal(false); - inCommand = -1; + SetActiveCommandIndex(-1); needShift = false; } } @@ -1215,7 +1217,7 @@ bool CGuiHandler::MousePress(int x, int y, int button) } } if (button == SDL_BUTTON_RIGHT) - inCommand = defaultCmdMemory = -1; + SetActiveCommandIndex(defaultCmdMemory = -1); return true; } else if (minimap && minimap->IsAbove(x, y)) { @@ -1226,7 +1228,7 @@ bool CGuiHandler::MousePress(int x, int y, int button) if (invertQueueKey && (button == SDL_BUTTON_RIGHT) && !mouse->buttons[SDL_BUTTON_LEFT].pressed) { // for rocker gestures SetShowingMetal(false); - inCommand = -1; + SetActiveCommandIndex(-1); needShift = false; return false; } @@ -1263,7 +1265,7 @@ void CGuiHandler::MouseRelease(int x, int y, int button, const float3& cameraPos if (!invertQueueKey && needShift && !KeyInput::GetKeyModState(KMOD_SHIFT)) { SetShowingMetal(false); - inCommand = -1; + SetActiveCommandIndex(-1); needShift = false; } @@ -1282,7 +1284,7 @@ void CGuiHandler::MouseRelease(int x, int y, int button, const float3& cameraPos if ((button == SDL_BUTTON_RIGHT) && (iconCmd == -1)) { // right click -> set the default cmd - inCommand = defaultCmdMemory; + SetActiveCommandIndex(defaultCmdMemory); defaultCmdMemory = -1; } @@ -1320,11 +1322,11 @@ bool CGuiHandler::SetActiveCommand(int cmdIndex, bool rightMouseButton) if (cmdIndex < 0) { // cancel the current command - inCommand = -1; defaultCmdMemory = -1; needShift = false; activeMousePress = false; SetShowingMetal(false); + SetActiveCommandIndex(-1); return true; } @@ -1370,14 +1372,14 @@ bool CGuiHandler::SetActiveCommand(int cmdIndex, bool rightMouseButton) case CMDTYPE_ICON_UNIT_OR_AREA: case CMDTYPE_ICON_UNIT_OR_RECTANGLE: case CMDTYPE_ICON_UNIT_FEATURE_OR_AREA: { - inCommand = cmdIndex; + SetActiveCommandIndex(cmdIndex); SetShowingMetal(false); activeMousePress = false; break; } case CMDTYPE_ICON_BUILDING: { const UnitDef* ud = unitDefHandler->GetUnitDefByID(-cd.id); - inCommand = cmdIndex; + SetActiveCommandIndex(cmdIndex); SetShowingMetal(ud->extractsMetal > 0); activeMousePress = false; break; @@ -1448,6 +1450,17 @@ bool CGuiHandler::SetActiveCommand(int cmdIndex, int button, return retval; } +void CGuiHandler::SetActiveCommandIndex(int newIndex) +{ + if (inCommand != newIndex) { + inCommand = newIndex; + if (inCommand < commands.size()) + eventHandler.ActiveCommandSet(&commands[inCommand]); + else + eventHandler.ActiveCommandSet(nullptr); + + } +} int CGuiHandler::IconAtPos(int x, int y) // GetToolTip --> IconAtPos { @@ -1841,13 +1854,13 @@ bool CGuiHandler::KeyPressed(int keyCode, int scanCode, bool isRepeat) RECOIL_DETAILED_TRACY_ZONE; if (keyCode == SDLK_ESCAPE && activeMousePress) { activeMousePress = false; - inCommand = -1; SetShowingMetal(false); + SetActiveCommandIndex(-1); return true; } if (keyCode == SDLK_ESCAPE && inCommand >= 0) { - inCommand=-1; SetShowingMetal(false); + SetActiveCommandIndex(-1); return true; } @@ -1892,6 +1905,8 @@ bool CGuiHandler::SetActiveCommand(const Action& action, return true; } + int newInCommand = inCommand; + // See if we have a positional icon command int iconCmd = -1; if (!action.extra.empty() && (action.command == "iconpos")) { @@ -2009,7 +2024,7 @@ bool CGuiHandler::SetActiveCommand(const Action& action, SetShowingMetal(false); actionOffset = actionIndex; lastKeySet = ks; - inCommand = a; + newInCommand = a; break; } case CMDTYPE_ICON_BUILDING: { @@ -2017,7 +2032,7 @@ bool CGuiHandler::SetActiveCommand(const Action& action, SetShowingMetal(ud->extractsMetal > 0); actionOffset = actionIndex; lastKeySet = ks; - inCommand = a; + newInCommand = a; break; } case CMDTYPE_NEXT: { @@ -2041,9 +2056,10 @@ bool CGuiHandler::SetActiveCommand(const Action& action, default:{ lastKeySet.Reset(); SetShowingMetal(false); - inCommand = a; + newInCommand = a; } } + SetActiveCommandIndex(newInCommand); return true; // we used the command } @@ -2063,7 +2079,7 @@ void CGuiHandler::FinishCommand(int button) needShift = true; } else { SetShowingMetal(false); - inCommand = -1; + SetActiveCommandIndex(-1); } } @@ -2185,7 +2201,7 @@ Command CGuiHandler::GetCommand(int mouseX, int mouseY, int buttonHint, bool pre if (size_t(tempInCommand) >= commands.size()) { if (!preview) - inCommand = -1; + SetActiveCommandIndex(-1); return Command(CMD_STOP); } diff --git a/rts/Game/UI/GuiHandler.h b/rts/Game/UI/GuiHandler.h index cc9666a982..4b83aac84c 100644 --- a/rts/Game/UI/GuiHandler.h +++ b/rts/Game/UI/GuiHandler.h @@ -117,6 +117,7 @@ class CGuiHandler : public CInputReceiver { void ConvertCommands(std::vector& cmds); int FindInCommandPage(); + void SetActiveCommandIndex(int newIndex); void RevertToCmdDesc(const SCommandDescription& cmdDesc, bool defaultCommand, bool samePage); unsigned char CreateOptions(bool rightMouseButton); diff --git a/rts/Lua/LuaHandle.cpp b/rts/Lua/LuaHandle.cpp index f4e9c39ba8..1f6d0fad7f 100644 --- a/rts/Lua/LuaHandle.cpp +++ b/rts/Lua/LuaHandle.cpp @@ -3336,6 +3336,33 @@ string CLuaHandle::GetTooltip(int x, int y) * @bool internal */ +/*** Called when a command is issued. + * + * @function ActiveCommandSet + * @int cmdID|nil + * @tparam table|nil cmdParams + * @tparam cmdOpts|nil options + */ +void CLuaHandle::ActiveCommandSet(const SCommandDescription* cmdDesc) +{ + RECOIL_DETAILED_TRACY_ZONE; + LUA_CALL_IN_CHECK(L, false); + luaL_checkstack(L, 3, __func__); + static const LuaHashString cmdStr(__func__); + if (!cmdStr.GetGlobalFunc(L)) + return; + + if (cmdDesc) { + lua_pushnumber(L, cmdDesc->id); + lua_pushnumber(L, cmdDesc->type); + + // call the function + RunCallIn(L, cmdStr, 2, 0); + } else { + RunCallIn(L, cmdStr, 0, 0); + } +} + /*** Called when a command is issued. * * @function CommandNotify diff --git a/rts/Lua/LuaHandle.h b/rts/Lua/LuaHandle.h index a1988ee322..97d3276712 100644 --- a/rts/Lua/LuaHandle.h +++ b/rts/Lua/LuaHandle.h @@ -210,6 +210,8 @@ class CLuaHandle : public CEventClient bool DefaultCommand(const CUnit* unit, const CFeature* feature, int& cmd) override; + void ActiveCommandSet(const SCommandDescription* cmdDesc) override; + bool CommandNotify(const Command& cmd) override; bool AddConsoleLine(const std::string& msg, const std::string& section, int level) override; diff --git a/rts/System/EventClient.cpp b/rts/System/EventClient.cpp index 9c87ff087b..2ce462d536 100644 --- a/rts/System/EventClient.cpp +++ b/rts/System/EventClient.cpp @@ -80,6 +80,7 @@ void CEventClient::DownloadProgress(int ID, long downloaded, long total) {} bool CEventClient::IsAbove(int x, int y) { return false; } std::string CEventClient::GetTooltip(int x, int y) { return ""; } +void CEventClient::ActiveCommandSet(const SCommandDescription* cmdDesc) {} bool CEventClient::CommandNotify(const Command& cmd) { return false; } bool CEventClient::AddConsoleLine(const std::string& msg, const std::string& section, int level) { return false; } diff --git a/rts/System/EventClient.h b/rts/System/EventClient.h index eb6d540e88..ae826d3bd8 100644 --- a/rts/System/EventClient.h +++ b/rts/System/EventClient.h @@ -26,6 +26,7 @@ class CWeapon; class CFeature; class CProjectile; struct Command; +struct SCommandDescription; class IArchive; struct SRectangle; struct UnitDef; @@ -301,6 +302,7 @@ class CEventClient virtual bool DefaultCommand(const CUnit* unit, const CFeature* feature, int& cmd); + virtual void ActiveCommandSet(const SCommandDescription* cmdDesc); virtual bool CommandNotify(const Command& cmd); virtual bool AddConsoleLine(const std::string& msg, const std::string& section, int level); diff --git a/rts/System/EventHandler.cpp b/rts/System/EventHandler.cpp index 62cdac82b3..60bc6c04eb 100644 --- a/rts/System/EventHandler.cpp +++ b/rts/System/EventHandler.cpp @@ -762,13 +762,18 @@ template std::string ControlReverseIterat return {}; } +void CEventHandler::ActiveCommandSet(const SCommandDescription* cmdDesc) +{ + ZoneScoped; + ITERATE_EVENTCLIENTLIST(ActiveCommandSet, cmdDesc); +} + bool CEventHandler::CommandNotify(const Command& cmd) { ZoneScoped; return ControlReverseIterateDefTrue(listCommandNotify, &CEventClient::CommandNotify, cmd); } - bool CEventHandler::KeyMapChanged() { ZoneScoped; diff --git a/rts/System/EventHandler.h b/rts/System/EventHandler.h index 6a641f9a1f..ecb774c820 100644 --- a/rts/System/EventHandler.h +++ b/rts/System/EventHandler.h @@ -234,6 +234,7 @@ class CEventHandler void DefaultCommand(const CUnit* unit, const CFeature* feature, int& cmd); + void ActiveCommandSet(const SCommandDescription *cmdDesc); bool CommandNotify(const Command& cmd); bool AddConsoleLine(const std::string& msg, const std::string& section, int level); diff --git a/rts/System/Events.def b/rts/System/Events.def index 28536101bf..8eac21642e 100644 --- a/rts/System/Events.def +++ b/rts/System/Events.def @@ -117,6 +117,7 @@ SETUP_EVENT(LastMessagePosition, MANAGED_BIT | UNSYNCED_BIT) SETUP_EVENT(DefaultCommand, MANAGED_BIT | UNSYNCED_BIT | CONTROL_BIT) + SETUP_EVENT(ActiveCommandSet, MANAGED_BIT | UNSYNCED_BIT) SETUP_EVENT(CommandNotify, MANAGED_BIT | UNSYNCED_BIT | CONTROL_BIT) SETUP_EVENT(AddConsoleLine, MANAGED_BIT | UNSYNCED_BIT) SETUP_EVENT(GroupChanged, MANAGED_BIT | UNSYNCED_BIT)