/* * Copyright (C) 2005-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 "GUIDialogPeripheralSettings.h" #include "FileItem.h" #include "ServiceBroker.h" #include "addons/Skin.h" #include "dialogs/GUIDialogYesNo.h" #include "games/controllers/Controller.h" #include "games/controllers/ControllerManager.h" #include "guilib/GUIMessage.h" #include "peripherals/Peripherals.h" #include "settings/SettingAddon.h" #include "settings/lib/Setting.h" #include "settings/lib/SettingSection.h" #include "utils/Variant.h" #include "utils/log.h" #include #include using namespace KODI; using namespace PERIPHERALS; // Settings for peripherals constexpr std::string_view SETTING_APPEARANCE = "appearance"; CGUIDialogPeripheralSettings::CGUIDialogPeripheralSettings() : CGUIDialogSettingsManualBase(WINDOW_DIALOG_PERIPHERAL_SETTINGS, "DialogSettings.xml"), m_item(NULL) { } CGUIDialogPeripheralSettings::~CGUIDialogPeripheralSettings() { if (m_item != NULL) delete m_item; m_settingsMap.clear(); } bool CGUIDialogPeripheralSettings::OnMessage(CGUIMessage& message) { if (message.GetMessage() == GUI_MSG_CLICKED && message.GetSenderId() == CONTROL_SETTINGS_CUSTOM_BUTTON) { OnResetSettings(); return true; } return CGUIDialogSettingsManualBase::OnMessage(message); } void CGUIDialogPeripheralSettings::RegisterPeripheralManager(CPeripherals& manager) { m_manager = &manager; } void CGUIDialogPeripheralSettings::UnregisterPeripheralManager() { m_manager = nullptr; } void CGUIDialogPeripheralSettings::SetFileItem(const CFileItem* item) { if (item == NULL) return; if (m_item != NULL) delete m_item; m_item = new CFileItem(*item); } void CGUIDialogPeripheralSettings::OnSettingChanged(const std::shared_ptr& setting) { if (setting == NULL) return; CGUIDialogSettingsManualBase::OnSettingChanged(setting); const std::string& settingId = setting->GetId(); // we need to copy the new value of the setting from the copy to the // original setting std::map>::iterator itSetting = m_settingsMap.find(settingId); if (itSetting == m_settingsMap.end()) return; itSetting->second->FromString(setting->ToString()); // Get peripheral associated with this setting PeripheralPtr peripheral; if (m_item != nullptr) peripheral = CServiceBroker::GetPeripherals().GetByPath(m_item->GetPath()); if (!peripheral) return; if (settingId == SETTING_APPEARANCE) { // Get the controller profile of the new appearance GAME::ControllerPtr controller; if (setting->GetType() == SettingType::String) { std::shared_ptr settingString = std::static_pointer_cast(setting); const std::string& addonId = settingString->GetValue(); if (m_manager != nullptr) controller = m_manager->GetControllerProfiles().GetController(addonId); } if (controller) peripheral->SetControllerProfile(controller); } } bool CGUIDialogPeripheralSettings::Save() { if (m_item == NULL || m_initialising) return true; PeripheralPtr peripheral = CServiceBroker::GetPeripherals().GetByPath(m_item->GetPath()); if (!peripheral) return true; peripheral->PersistSettings(); return true; } void CGUIDialogPeripheralSettings::OnResetSettings() { if (m_item == NULL) return; PeripheralPtr peripheral = CServiceBroker::GetPeripherals().GetByPath(m_item->GetPath()); if (!peripheral) return; if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{10041}, CVariant{10042})) return; // reset the settings in the peripheral peripheral->ResetDefaultSettings(); // re-create all settings and their controls SetupView(); } void CGUIDialogPeripheralSettings::SetupView() { CGUIDialogSettingsManualBase::SetupView(); SetHeading(m_item->GetLabel()); SET_CONTROL_LABEL(CONTROL_SETTINGS_OKAY_BUTTON, 186); SET_CONTROL_LABEL(CONTROL_SETTINGS_CANCEL_BUTTON, 222); SET_CONTROL_LABEL(CONTROL_SETTINGS_CUSTOM_BUTTON, 409); } void CGUIDialogPeripheralSettings::InitializeSettings() { if (m_item == NULL) { m_initialising = false; return; } m_initialising = true; bool usePopup = g_SkinInfo->HasSkinFile("DialogSlider.xml"); PeripheralPtr peripheral = CServiceBroker::GetPeripherals().GetByPath(m_item->GetPath()); if (!peripheral) { CLog::Log(LOGDEBUG, "{} - no peripheral", __FUNCTION__); m_initialising = false; return; } m_settingsMap.clear(); CGUIDialogSettingsManualBase::InitializeSettings(); const std::shared_ptr category = AddCategory("peripheralsettings", -1); if (category == NULL) { CLog::Log(LOGERROR, "CGUIDialogPeripheralSettings: unable to setup settings"); return; } const std::shared_ptr group = AddGroup(category); if (group == NULL) { CLog::Log(LOGERROR, "CGUIDialogPeripheralSettings: unable to setup settings"); return; } std::vector settings = peripheral->GetSettings(); for (auto& setting : settings) { if (setting == NULL) continue; if (!setting->IsVisible()) { CLog::Log(LOGDEBUG, "{} - invisible", __FUNCTION__); continue; } // we need to create a copy of the setting because the CSetting instances // are destroyed when leaving the dialog SettingPtr settingCopy; switch (setting->GetType()) { case SettingType::Boolean: { std::shared_ptr settingBool = std::make_shared( setting->GetId(), *std::static_pointer_cast(setting)); settingBool->SetControl(GetCheckmarkControl()); settingCopy = std::static_pointer_cast(settingBool); break; } case SettingType::Integer: { std::shared_ptr settingInt = std::make_shared( setting->GetId(), *std::static_pointer_cast(setting)); if (settingInt->GetTranslatableOptions().empty()) settingInt->SetControl(GetSliderControl("integer", false, -1, usePopup, -1, "{:d}")); else settingInt->SetControl(GetSpinnerControl("string")); settingCopy = std::static_pointer_cast(settingInt); break; } case SettingType::Number: { std::shared_ptr settingNumber = std::make_shared( setting->GetId(), *std::static_pointer_cast(setting)); settingNumber->SetControl(GetSliderControl("number", false, -1, usePopup, -1, "{:2.2f}")); settingCopy = std::static_pointer_cast(settingNumber); break; } case SettingType::String: { if (auto settingAsAddon = std::dynamic_pointer_cast(setting)) { std::shared_ptr settingAddon = std::make_shared(setting->GetId(), *settingAsAddon); // Control properties const std::string format = "addon"; const bool delayed = false; const int heading = -1; const bool hideValue = false; const bool showInstalledAddons = true; const bool showInstallableAddons = true; const bool showMoreAddons = false; settingAddon->SetControl(GetButtonControl(format, delayed, heading, hideValue, showInstalledAddons, showInstallableAddons, showMoreAddons)); GAME::ControllerPtr controller = peripheral->ControllerProfile(); if (controller) settingAddon->SetValue(controller->ID()); settingCopy = std::static_pointer_cast(settingAddon); } else { std::shared_ptr settingString = std::make_shared( setting->GetId(), *std::static_pointer_cast(setting)); settingString->SetControl(GetEditControl("string")); settingCopy = std::static_pointer_cast(settingString); } break; } default: //! @todo add more types if needed CLog::Log(LOGDEBUG, "{} - unknown type", __FUNCTION__); break; } if (settingCopy != NULL && settingCopy->GetControl() != NULL) { settingCopy->SetLevel(SettingLevel::Basic); group->AddSetting(settingCopy); m_settingsMap.insert(std::make_pair(setting->GetId(), setting)); } } m_initialising = false; }