summaryrefslogtreecommitdiffstats
path: root/xbmc/input/CustomControllerTranslator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/input/CustomControllerTranslator.cpp')
-rw-r--r--xbmc/input/CustomControllerTranslator.cpp117
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;
+}