diff options
Diffstat (limited to 'xbmc/input/CustomControllerTranslator.cpp')
-rw-r--r-- | xbmc/input/CustomControllerTranslator.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/xbmc/input/CustomControllerTranslator.cpp b/xbmc/input/CustomControllerTranslator.cpp new file mode 100644 index 0000000..9d25a6e --- /dev/null +++ b/xbmc/input/CustomControllerTranslator.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2017-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "CustomControllerTranslator.h" + +#include "WindowTranslator.h" //! @todo +#include "input/actions/ActionIDs.h" +#include "input/actions/ActionTranslator.h" +#include "utils/XBMCTinyXML.h" +#include "utils/log.h" + +void CCustomControllerTranslator::MapActions(int windowID, const TiXmlNode* pCustomController) +{ + CustomControllerButtonMap buttonMap; + std::string controllerName; + + const TiXmlElement* pController = pCustomController->ToElement(); + if (pController != nullptr) + { + // Transform loose name to new family, including altnames + const char* name = pController->Attribute("name"); + if (name != nullptr) + controllerName = name; + } + + if (controllerName.empty()) + { + CLog::Log(LOGERROR, "Missing attribute \"name\" for tag \"customcontroller\""); + return; + } + + // Parse map + const TiXmlElement* pButton = pCustomController->FirstChildElement(); + int id = 0; + while (pButton != nullptr) + { + std::string action; + if (!pButton->NoChildren()) + action = pButton->FirstChild()->ValueStr(); + + if ((pButton->QueryIntAttribute("id", &id) == TIXML_SUCCESS) && id >= 0) + { + buttonMap[id] = action; + } + else + CLog::Log(LOGERROR, "Error reading customController map element, Invalid id: {}", id); + + pButton = pButton->NextSiblingElement(); + } + + // Add/overwrite button with mapped actions + for (auto button : buttonMap) + m_customControllersMap[controllerName][windowID][button.first] = std::move(button.second); +} + +void CCustomControllerTranslator::Clear() +{ + m_customControllersMap.clear(); +} + +bool CCustomControllerTranslator::TranslateCustomControllerString(int windowId, + const std::string& controllerName, + int buttonId, + int& action, + std::string& strAction) +{ + unsigned int actionId = ACTION_NONE; + + // handle virtual windows + windowId = CWindowTranslator::GetVirtualWindow(windowId); + + // Try to get the action from the current window + if (!TranslateString(windowId, controllerName, buttonId, actionId, strAction)) + { + // if it's invalid, try to get it from fallback windows or the global map (windowId == -1) + while (actionId == ACTION_NONE && windowId > -1) + { + windowId = CWindowTranslator::GetFallbackWindow(windowId); + TranslateString(windowId, controllerName, buttonId, actionId, strAction); + } + } + + action = actionId; + return actionId != ACTION_NONE; +} + +bool CCustomControllerTranslator::TranslateString(int windowId, + const std::string& controllerName, + int buttonId, + unsigned int& actionId, + std::string& strAction) +{ + // Resolve the correct custom controller + auto it = m_customControllersMap.find(controllerName); + if (it == m_customControllersMap.end()) + return false; + + const CustomControllerWindowMap& windowMap = it->second; + auto it2 = windowMap.find(windowId); + if (it2 != windowMap.end()) + { + const CustomControllerButtonMap& buttonMap = it2->second; + auto it3 = buttonMap.find(buttonId); + if (it3 != buttonMap.end()) + { + strAction = it3->second; + CActionTranslator::TranslateString(strAction, actionId); + } + } + + return actionId != ACTION_NONE; +} |