diff options
Diffstat (limited to 'xbmc/games/controllers/ControllerLayout.cpp')
-rw-r--r-- | xbmc/games/controllers/ControllerLayout.cpp | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/xbmc/games/controllers/ControllerLayout.cpp b/xbmc/games/controllers/ControllerLayout.cpp new file mode 100644 index 0000000..85816c1 --- /dev/null +++ b/xbmc/games/controllers/ControllerLayout.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2015-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 "ControllerLayout.h" + +#include "Controller.h" +#include "ControllerDefinitions.h" +#include "ControllerTranslator.h" +#include "games/controllers/input/PhysicalTopology.h" +#include "guilib/LocalizeStrings.h" +#include "utils/URIUtils.h" +#include "utils/XMLUtils.h" +#include "utils/log.h" + +#include <sstream> + +using namespace KODI; +using namespace GAME; + +CControllerLayout::CControllerLayout() : m_topology(new CPhysicalTopology) +{ +} + +CControllerLayout::CControllerLayout(const CControllerLayout& other) + : m_controller(other.m_controller), + m_labelId(other.m_labelId), + m_icon(other.m_icon), + m_strImage(other.m_strImage), + m_topology(new CPhysicalTopology(*other.m_topology)) +{ +} + +CControllerLayout::~CControllerLayout() = default; + +void CControllerLayout::Reset(void) +{ + m_controller = nullptr; + m_labelId = -1; + m_icon.clear(); + m_strImage.clear(); + m_topology->Reset(); +} + +bool CControllerLayout::IsValid(bool bLog) const +{ + if (m_labelId < 0) + { + if (bLog) + CLog::Log(LOGERROR, "<{}> tag has no \"{}\" attribute", LAYOUT_XML_ROOT, + LAYOUT_XML_ATTR_LAYOUT_LABEL); + return false; + } + + if (m_strImage.empty()) + { + if (bLog) + CLog::Log(LOGDEBUG, "<{}> tag has no \"{}\" attribute", LAYOUT_XML_ROOT, + LAYOUT_XML_ATTR_LAYOUT_IMAGE); + return false; + } + + return true; +} + +std::string CControllerLayout::Label(void) const +{ + std::string label; + + if (m_labelId >= 0 && m_controller != nullptr) + label = g_localizeStrings.GetAddonString(m_controller->ID(), m_labelId); + + return label; +} + +std::string CControllerLayout::ImagePath(void) const +{ + std::string path; + + if (!m_strImage.empty() && m_controller != nullptr) + return URIUtils::AddFileToFolder(URIUtils::GetDirectory(m_controller->LibPath()), m_strImage); + + return path; +} + +void CControllerLayout::Deserialize(const TiXmlElement* pElement, + const CController* controller, + std::vector<CPhysicalFeature>& features) +{ + if (pElement == nullptr || controller == nullptr) + return; + + // Controller (used for string lookup and path translation) + m_controller = controller; + + // Label + std::string strLabel = XMLUtils::GetAttribute(pElement, LAYOUT_XML_ATTR_LAYOUT_LABEL); + if (!strLabel.empty()) + std::istringstream(strLabel) >> m_labelId; + + // Icon + std::string icon = XMLUtils::GetAttribute(pElement, LAYOUT_XML_ATTR_LAYOUT_ICON); + if (!icon.empty()) + m_icon = icon; + + // Fallback icon, use add-on icon + if (m_icon.empty()) + m_icon = controller->Icon(); + + // Image + std::string image = XMLUtils::GetAttribute(pElement, LAYOUT_XML_ATTR_LAYOUT_IMAGE); + if (!image.empty()) + m_strImage = image; + + for (const TiXmlElement* pChild = pElement->FirstChildElement(); pChild != nullptr; + pChild = pChild->NextSiblingElement()) + { + if (pChild->ValueStr() == LAYOUT_XML_ELM_CATEGORY) + { + // Category + std::string strCategory = XMLUtils::GetAttribute(pChild, LAYOUT_XML_ATTR_CATEGORY_NAME); + JOYSTICK::FEATURE_CATEGORY category = + CControllerTranslator::TranslateFeatureCategory(strCategory); + + // Category label + int categoryLabelId = -1; + + std::string strCategoryLabelId = + XMLUtils::GetAttribute(pChild, LAYOUT_XML_ATTR_CATEGORY_LABEL); + if (!strCategoryLabelId.empty()) + std::istringstream(strCategoryLabelId) >> categoryLabelId; + + // Features + for (const TiXmlElement* pFeature = pChild->FirstChildElement(); pFeature != nullptr; + pFeature = pFeature->NextSiblingElement()) + { + CPhysicalFeature feature; + + if (feature.Deserialize(pFeature, controller, category, categoryLabelId)) + features.push_back(feature); + } + } + else if (pChild->ValueStr() == LAYOUT_XML_ELM_TOPOLOGY) + { + // Topology + CPhysicalTopology topology; + if (topology.Deserialize(pChild)) + *m_topology = std::move(topology); + } + else + { + CLog::Log(LOGDEBUG, "Ignoring <{}> tag", pChild->ValueStr()); + } + } +} |