diff options
Diffstat (limited to 'xbmc/peripherals/dialogs')
-rw-r--r-- | xbmc/peripherals/dialogs/CMakeLists.txt | 7 | ||||
-rw-r--r-- | xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp | 308 | ||||
-rw-r--r-- | xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h | 52 | ||||
-rw-r--r-- | xbmc/peripherals/dialogs/GUIDialogPeripherals.cpp | 186 | ||||
-rw-r--r-- | xbmc/peripherals/dialogs/GUIDialogPeripherals.h | 51 |
5 files changed, 604 insertions, 0 deletions
diff --git a/xbmc/peripherals/dialogs/CMakeLists.txt b/xbmc/peripherals/dialogs/CMakeLists.txt new file mode 100644 index 0000000..28aca66 --- /dev/null +++ b/xbmc/peripherals/dialogs/CMakeLists.txt @@ -0,0 +1,7 @@ +set(SOURCES GUIDialogPeripherals.cpp + GUIDialogPeripheralSettings.cpp) + +set(HEADERS GUIDialogPeripherals.h + GUIDialogPeripheralSettings.h) + +core_add_library(peripherals_dialogs) diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp new file mode 100644 index 0000000..73816df --- /dev/null +++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.cpp @@ -0,0 +1,308 @@ +/* + * 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 <string_view> +#include <utility> + +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<const CSetting>& 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<std::string, std::shared_ptr<CSetting>>::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<const CSettingString> settingString = + std::static_pointer_cast<const CSettingString>(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<CSettingCategory> category = AddCategory("peripheralsettings", -1); + if (category == NULL) + { + CLog::Log(LOGERROR, "CGUIDialogPeripheralSettings: unable to setup settings"); + return; + } + + const std::shared_ptr<CSettingGroup> group = AddGroup(category); + if (group == NULL) + { + CLog::Log(LOGERROR, "CGUIDialogPeripheralSettings: unable to setup settings"); + return; + } + + std::vector<SettingPtr> 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<CSettingBool> settingBool = std::make_shared<CSettingBool>( + setting->GetId(), *std::static_pointer_cast<CSettingBool>(setting)); + settingBool->SetControl(GetCheckmarkControl()); + + settingCopy = std::static_pointer_cast<CSetting>(settingBool); + break; + } + + case SettingType::Integer: + { + std::shared_ptr<CSettingInt> settingInt = std::make_shared<CSettingInt>( + setting->GetId(), *std::static_pointer_cast<CSettingInt>(setting)); + if (settingInt->GetTranslatableOptions().empty()) + settingInt->SetControl(GetSliderControl("integer", false, -1, usePopup, -1, "{:d}")); + else + settingInt->SetControl(GetSpinnerControl("string")); + + settingCopy = std::static_pointer_cast<CSetting>(settingInt); + break; + } + + case SettingType::Number: + { + std::shared_ptr<CSettingNumber> settingNumber = std::make_shared<CSettingNumber>( + setting->GetId(), *std::static_pointer_cast<CSettingNumber>(setting)); + settingNumber->SetControl(GetSliderControl("number", false, -1, usePopup, -1, "{:2.2f}")); + + settingCopy = std::static_pointer_cast<CSetting>(settingNumber); + break; + } + + case SettingType::String: + { + if (auto settingAsAddon = std::dynamic_pointer_cast<const CSettingAddon>(setting)) + { + std::shared_ptr<CSettingAddon> settingAddon = + std::make_shared<CSettingAddon>(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<CSetting>(settingAddon); + } + else + { + std::shared_ptr<CSettingString> settingString = std::make_shared<CSettingString>( + setting->GetId(), *std::static_pointer_cast<CSettingString>(setting)); + settingString->SetControl(GetEditControl("string")); + + settingCopy = std::static_pointer_cast<CSetting>(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; +} diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h new file mode 100644 index 0000000..33ad2ee --- /dev/null +++ b/xbmc/peripherals/dialogs/GUIDialogPeripheralSettings.h @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#pragma once + +#include "settings/dialogs/GUIDialogSettingsManualBase.h" + +class CFileItem; + +namespace PERIPHERALS +{ +class CPeripherals; + +class CGUIDialogPeripheralSettings : public CGUIDialogSettingsManualBase +{ +public: + CGUIDialogPeripheralSettings(); + ~CGUIDialogPeripheralSettings() override; + + // specializations of CGUIControl + bool OnMessage(CGUIMessage& message) override; + + void RegisterPeripheralManager(CPeripherals& manager); + void UnregisterPeripheralManager(); + + virtual void SetFileItem(const CFileItem* item); + +protected: + // implementations of ISettingCallback + void OnSettingChanged(const std::shared_ptr<const CSetting>& setting) override; + + // specialization of CGUIDialogSettingsBase + bool AllowResettingSettings() const override { return false; } + bool Save() override; + void OnResetSettings() override; + void SetupView() override; + + // specialization of CGUIDialogSettingsManualBase + void InitializeSettings() override; + + // Dialog state + CPeripherals* m_manager{nullptr}; + CFileItem* m_item; + bool m_initialising = false; + std::map<std::string, std::shared_ptr<CSetting>> m_settingsMap; +}; +} // namespace PERIPHERALS diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripherals.cpp b/xbmc/peripherals/dialogs/GUIDialogPeripherals.cpp new file mode 100644 index 0000000..7594cb2 --- /dev/null +++ b/xbmc/peripherals/dialogs/GUIDialogPeripherals.cpp @@ -0,0 +1,186 @@ +/* + * 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 "GUIDialogPeripherals.h" + +#include "FileItem.h" +#include "ServiceBroker.h" +#include "dialogs/GUIDialogSelect.h" +#include "guilib/GUIComponent.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/WindowIDs.h" +#include "messaging/ApplicationMessenger.h" +#include "messaging/helpers/DialogOKHelper.h" +#include "peripherals/Peripherals.h" +#include "peripherals/dialogs/GUIDialogPeripheralSettings.h" +#include "utils/Variant.h" + +#include <mutex> + +using namespace KODI; +using namespace PERIPHERALS; + +CGUIDialogPeripherals::CGUIDialogPeripherals() +{ + // Initialize CGUIControl via CGUIDialogSelect + SetID(WINDOW_DIALOG_PERIPHERALS); +} + +CGUIDialogPeripherals::~CGUIDialogPeripherals() = default; + +void CGUIDialogPeripherals::OnInitWindow() +{ + UpdatePeripheralsSync(); + CGUIDialogSelect::OnInitWindow(); +} + +void CGUIDialogPeripherals::RegisterPeripheralManager(CPeripherals& manager) +{ + m_manager = &manager; + m_manager->RegisterObserver(this); +} + +void CGUIDialogPeripherals::UnregisterPeripheralManager() +{ + if (m_manager != nullptr) + { + m_manager->UnregisterObserver(this); + m_manager = nullptr; + } +} + +CFileItemPtr CGUIDialogPeripherals::GetItem(unsigned int pos) const +{ + CFileItemPtr item; + + std::unique_lock<CCriticalSection> lock(m_peripheralsMutex); + + if (static_cast<int>(pos) < m_peripherals.Size()) + item = m_peripherals[pos]; + + return item; +} + +void CGUIDialogPeripherals::Show(CPeripherals& manager) +{ + CGUIDialogPeripherals* pDialog = + CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogPeripherals>( + WINDOW_DIALOG_PERIPHERALS); + if (pDialog == nullptr) + return; + + pDialog->Reset(); + + int iPos = -1; + do + { + pDialog->SetHeading(CVariant{35000}); + pDialog->SetUseDetails(true); + + pDialog->RegisterPeripheralManager(manager); + + pDialog->Open(); + + pDialog->UnregisterPeripheralManager(); + + iPos = pDialog->IsConfirmed() ? pDialog->GetSelectedItem() : -1; + + if (iPos >= 0) + { + CFileItemPtr pItem = pDialog->GetItem(iPos); + + // Show an error if the peripheral doesn't have any settings + PeripheralPtr peripheral = manager.GetByPath(pItem->GetPath()); + if (!peripheral || peripheral->GetSettings().empty()) + { + MESSAGING::HELPERS::ShowOKDialogText(CVariant{35000}, CVariant{35004}); + continue; + } + + CGUIDialogPeripheralSettings* pSettingsDialog = + CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogPeripheralSettings>( + WINDOW_DIALOG_PERIPHERAL_SETTINGS); + if (pItem && pSettingsDialog) + { + // Pass peripheral item properties to settings dialog so skin authors + // Can use it to show more detailed information about the device + pSettingsDialog->SetProperty("vendor", pItem->GetProperty("vendor")); + pSettingsDialog->SetProperty("product", pItem->GetProperty("product")); + pSettingsDialog->SetProperty("bus", pItem->GetProperty("bus")); + pSettingsDialog->SetProperty("location", pItem->GetProperty("location")); + pSettingsDialog->SetProperty("class", pItem->GetProperty("class")); + pSettingsDialog->SetProperty("version", pItem->GetProperty("version")); + + // Open settings dialog + pSettingsDialog->SetFileItem(pItem.get()); + pSettingsDialog->RegisterPeripheralManager(manager); + pSettingsDialog->Open(); + pSettingsDialog->UnregisterPeripheralManager(); + } + } + } while (pDialog->IsConfirmed()); +} + +bool CGUIDialogPeripherals::OnMessage(CGUIMessage& message) +{ + switch (message.GetMessage()) + { + case GUI_MSG_REFRESH_LIST: + { + if (m_manager && message.GetControlId() == -1) + UpdatePeripheralsSync(); + return true; + } + default: + break; + } + + return CGUIDialogSelect::OnMessage(message); +} + +void CGUIDialogPeripherals::Notify(const Observable& obs, const ObservableMessage msg) +{ + switch (msg) + { + case ObservableMessagePeripheralsChanged: + UpdatePeripheralsAsync(); + break; + default: + break; + } +} + +void CGUIDialogPeripherals::UpdatePeripheralsAsync() +{ + CGUIMessage msg(GUI_MSG_REFRESH_LIST, GetID(), -1); + CServiceBroker::GetAppMessenger()->SendGUIMessage(msg); +} + +void CGUIDialogPeripherals::UpdatePeripheralsSync() +{ + int iPos = GetSelectedItem(); + + std::unique_lock<CCriticalSection> lock(m_peripheralsMutex); + + CFileItemPtr selectedItem; + if (iPos > 0) + selectedItem = GetItem(iPos); + + m_peripherals.Clear(); + m_manager->GetDirectory("peripherals://all/", m_peripherals); + SetItems(m_peripherals); + + if (selectedItem) + { + for (int i = 0; i < m_peripherals.Size(); i++) + { + if (m_peripherals[i]->GetPath() == selectedItem->GetPath()) + SetSelected(i); + } + } +} diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripherals.h b/xbmc/peripherals/dialogs/GUIDialogPeripherals.h new file mode 100644 index 0000000..d4a2f5d --- /dev/null +++ b/xbmc/peripherals/dialogs/GUIDialogPeripherals.h @@ -0,0 +1,51 @@ +/* + * 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. + */ + +#pragma once + +#include "FileItem.h" +#include "dialogs/GUIDialogSelect.h" +#include "threads/CriticalSection.h" +#include "utils/Observer.h" + +namespace PERIPHERALS +{ +class CPeripherals; + +class CGUIDialogPeripherals : public CGUIDialogSelect, protected Observer +{ +public: + CGUIDialogPeripherals(); + ~CGUIDialogPeripherals() override; + + void RegisterPeripheralManager(CPeripherals& manager); + void UnregisterPeripheralManager(); + + CFileItemPtr GetItem(unsigned int pos) const; + + static void Show(CPeripherals& manager); + + // implementation of CGUIControl via CGUIDialogSelect + bool OnMessage(CGUIMessage& message) override; + + // implementation of Observer + void Notify(const Observable& obs, const ObservableMessage msg) override; + +private: + // implementation of CGUIWindow via CGUIDialogSelect + void OnInitWindow() override; + + void ShowInternal(); + void UpdatePeripheralsAsync(); + void UpdatePeripheralsSync(); + + CPeripherals* m_manager = nullptr; + CFileItemList m_peripherals; + mutable CCriticalSection m_peripheralsMutex; +}; +} // namespace PERIPHERALS |