1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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;
}
|