diff options
Diffstat (limited to 'xbmc/dialogs/GUIDialogSelect.cpp')
-rw-r--r-- | xbmc/dialogs/GUIDialogSelect.cpp | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/xbmc/dialogs/GUIDialogSelect.cpp b/xbmc/dialogs/GUIDialogSelect.cpp new file mode 100644 index 0000000..0f125b2 --- /dev/null +++ b/xbmc/dialogs/GUIDialogSelect.cpp @@ -0,0 +1,405 @@ +/* + * 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 "GUIDialogSelect.h" + +#include "FileItem.h" +#include "guilib/GUIMessage.h" +#include "guilib/LocalizeStrings.h" +#include "input/Key.h" +#include "utils/StringUtils.h" + +#define CONTROL_HEADING 1 +#define CONTROL_NUMBER_OF_ITEMS 2 +#define CONTROL_SIMPLE_LIST 3 +#define CONTROL_DETAILED_LIST 6 +#define CONTROL_EXTRA_BUTTON 5 +#define CONTROL_EXTRA_BUTTON2 8 +#define CONTROL_CANCEL_BUTTON 7 + +CGUIDialogSelect::CGUIDialogSelect() : CGUIDialogSelect(WINDOW_DIALOG_SELECT) {} + +CGUIDialogSelect::CGUIDialogSelect(int windowId) + : CGUIDialogBoxBase(windowId, "DialogSelect.xml"), + m_vecList(std::make_unique<CFileItemList>()), + m_bButtonEnabled(false), + m_bButton2Enabled(false), + m_bButtonPressed(false), + m_bButton2Pressed(false), + m_useDetails(false), + m_multiSelection(false) +{ + m_bConfirmed = false; + m_loadType = KEEP_IN_MEMORY; +} + +CGUIDialogSelect::~CGUIDialogSelect(void) = default; + +bool CGUIDialogSelect::OnMessage(CGUIMessage& message) +{ + switch (message.GetMessage()) + { + case GUI_MSG_WINDOW_DEINIT: + { + CGUIDialogBoxBase::OnMessage(message); + + m_bButtonEnabled = false; + m_bButton2Enabled = false; + m_useDetails = false; + m_multiSelection = false; + + // construct selected items list + m_selectedItems.clear(); + m_selectedItem = nullptr; + for (int i = 0 ; i < m_vecList->Size() ; i++) + { + CFileItemPtr item = m_vecList->Get(i); + if (item->IsSelected()) + { + m_selectedItems.push_back(i); + if (!m_selectedItem) + m_selectedItem = item; + } + } + m_vecList->Clear(); + return true; + } + break; + + case GUI_MSG_WINDOW_INIT: + { + m_bButtonPressed = false; + m_bButton2Pressed = false; + m_bConfirmed = false; + CGUIDialogBoxBase::OnMessage(message); + return true; + } + break; + + + case GUI_MSG_CLICKED: + { + int iControl = message.GetSenderId(); + if (m_viewControl.HasControl(CONTROL_SIMPLE_LIST)) + { + int iAction = message.GetParam1(); + if (ACTION_SELECT_ITEM == iAction || ACTION_MOUSE_LEFT_CLICK == iAction) + { + int iSelected = m_viewControl.GetSelectedItem(); + if (iSelected >= 0 && iSelected < m_vecList->Size()) + { + CFileItemPtr item(m_vecList->Get(iSelected)); + if (m_multiSelection) + item->Select(!item->IsSelected()); + else + { + for (int i = 0 ; i < m_vecList->Size() ; i++) + m_vecList->Get(i)->Select(false); + item->Select(true); + OnSelect(iSelected); + } + } + } + } + if (iControl == CONTROL_EXTRA_BUTTON2) + { + m_bButton2Pressed = true; + if (m_multiSelection) + m_bConfirmed = true; + Close(); + } + if (iControl == CONTROL_EXTRA_BUTTON) + { + m_selectedItem = nullptr; + m_bButtonPressed = true; + if (m_multiSelection) + m_bConfirmed = true; + Close(); + } + else if (iControl == CONTROL_CANCEL_BUTTON) + { + m_selectedItem = nullptr; + m_vecList->Clear(); + m_selectedItems.clear(); + m_bConfirmed = false; + Close(); + } + } + break; + case GUI_MSG_SETFOCUS: + { + if (m_viewControl.HasControl(message.GetControlId())) + { + if (m_vecList->IsEmpty()) + { + if (m_bButtonEnabled) + SET_CONTROL_FOCUS(CONTROL_EXTRA_BUTTON, 0); + else + SET_CONTROL_FOCUS(CONTROL_CANCEL_BUTTON, 0); + return true; + } + if (m_viewControl.GetCurrentControl() != message.GetControlId()) + { + m_viewControl.SetFocused(); + return true; + } + } + } + break; + } + + return CGUIDialogBoxBase::OnMessage(message); +} + +void CGUIDialogSelect::OnSelect(int idx) +{ + m_bConfirmed = true; + Close(); +} + +bool CGUIDialogSelect::OnBack(int actionID) +{ + m_selectedItem = nullptr; + m_vecList->Clear(); + m_selectedItems.clear(); + m_bConfirmed = false; + return CGUIDialogBoxBase::OnBack(actionID); +} + +void CGUIDialogSelect::Reset() +{ + m_bButtonEnabled = false; + m_bButtonPressed = false; + m_bButton2Enabled = false; + m_bButton2Pressed = false; + + m_useDetails = false; + m_multiSelection = false; + m_focusToButton = false; + m_selectedItem = nullptr; + m_vecList->Clear(); + m_selectedItems.clear(); +} + +int CGUIDialogSelect::Add(const std::string& strLabel) +{ + CFileItemPtr pItem(new CFileItem(strLabel)); + m_vecList->Add(pItem); + return m_vecList->Size() - 1; +} + +int CGUIDialogSelect::Add(const CFileItem& item) +{ + m_vecList->Add(CFileItemPtr(new CFileItem(item))); + return m_vecList->Size() - 1; +} + +void CGUIDialogSelect::SetItems(const CFileItemList& pList) +{ + // need to make internal copy of list to be sure dialog is owner of it + m_vecList->Clear(); + m_vecList->Copy(pList); + + m_viewControl.SetItems(*m_vecList); +} + +int CGUIDialogSelect::GetSelectedItem() const +{ + return m_selectedItems.size() > 0 ? m_selectedItems[0] : -1; +} + +const CFileItemPtr CGUIDialogSelect::GetSelectedFileItem() const +{ + if (m_selectedItem) + return m_selectedItem; + return CFileItemPtr(new CFileItem); +} + +const std::vector<int>& CGUIDialogSelect::GetSelectedItems() const +{ + return m_selectedItems; +} + +void CGUIDialogSelect::EnableButton(bool enable, int label) +{ + m_bButtonEnabled = enable; + m_buttonLabel = g_localizeStrings.Get(label); +} + +void CGUIDialogSelect::EnableButton(bool enable, const std::string& label) +{ + m_bButtonEnabled = enable; + m_buttonLabel = label; +} + +void CGUIDialogSelect::EnableButton2(bool enable, int label) +{ + m_bButton2Enabled = enable; + m_button2Label = g_localizeStrings.Get(label); +} + +void CGUIDialogSelect::EnableButton2(bool enable, const std::string& label) +{ + m_bButton2Enabled = enable; + m_button2Label = label; +} + +bool CGUIDialogSelect::IsButtonPressed() +{ + return m_bButtonPressed; +} + +bool CGUIDialogSelect::IsButton2Pressed() +{ + return m_bButton2Pressed; +} + +void CGUIDialogSelect::Sort(bool bSortOrder /*=true*/) +{ + m_vecList->Sort(SortByLabel, bSortOrder ? SortOrderAscending : SortOrderDescending); +} + +void CGUIDialogSelect::SetSelected(int iSelected) +{ + if (iSelected < 0 || iSelected >= m_vecList->Size() || + m_vecList->Get(iSelected).get() == NULL) + return; + + // only set m_iSelected if there is no multi-select + // or if it doesn't have a valid value yet + // or if the current value is bigger than the new one + // so that we always focus the item nearest to the beginning of the list + if (!m_multiSelection || !m_selectedItem || + (!m_selectedItems.empty() && m_selectedItems.back() > iSelected)) + m_selectedItem = m_vecList->Get(iSelected); + m_vecList->Get(iSelected)->Select(true); + m_selectedItems.push_back(iSelected); +} + +void CGUIDialogSelect::SetSelected(const std::string &strSelectedLabel) +{ + for (int index = 0; index < m_vecList->Size(); index++) + { + if (strSelectedLabel == m_vecList->Get(index)->GetLabel()) + { + SetSelected(index); + return; + } + } +} + +void CGUIDialogSelect::SetSelected(const std::vector<int>& selectedIndexes) +{ + for (auto i : selectedIndexes) + SetSelected(i); +} + +void CGUIDialogSelect::SetSelected(const std::vector<std::string> &selectedLabels) +{ + for (const auto& label : selectedLabels) + SetSelected(label); +} + +void CGUIDialogSelect::SetUseDetails(bool useDetails) +{ + m_useDetails = useDetails; +} + +void CGUIDialogSelect::SetMultiSelection(bool multiSelection) +{ + m_multiSelection = multiSelection; +} + +void CGUIDialogSelect::SetButtonFocus(bool buttonFocus) +{ + m_focusToButton = buttonFocus; +} + +CGUIControl *CGUIDialogSelect::GetFirstFocusableControl(int id) +{ + if (m_viewControl.HasControl(id)) + id = m_viewControl.GetCurrentControl(); + return CGUIDialogBoxBase::GetFirstFocusableControl(id); +} + +void CGUIDialogSelect::OnWindowLoaded() +{ + CGUIDialogBoxBase::OnWindowLoaded(); + m_viewControl.Reset(); + m_viewControl.SetParentWindow(GetID()); + m_viewControl.AddView(GetControl(CONTROL_SIMPLE_LIST)); + m_viewControl.AddView(GetControl(CONTROL_DETAILED_LIST)); +} + +void CGUIDialogSelect::OnInitWindow() +{ + m_viewControl.SetItems(*m_vecList); + m_selectedItems.clear(); + for(int i = 0 ; i < m_vecList->Size(); i++) + { + auto item = m_vecList->Get(i); + if (item->IsSelected()) + { + m_selectedItems.push_back(i); + if (m_selectedItem == nullptr) + m_selectedItem = item; + } + } + m_viewControl.SetCurrentView(m_useDetails ? CONTROL_DETAILED_LIST : CONTROL_SIMPLE_LIST); + + SET_CONTROL_LABEL(CONTROL_NUMBER_OF_ITEMS, + StringUtils::Format("{} {}", m_vecList->Size(), g_localizeStrings.Get(127))); + + if (m_multiSelection) + EnableButton(true, 186); + + if (m_bButtonEnabled) + { + SET_CONTROL_LABEL(CONTROL_EXTRA_BUTTON, m_buttonLabel); + SET_CONTROL_VISIBLE(CONTROL_EXTRA_BUTTON); + } + else + SET_CONTROL_HIDDEN(CONTROL_EXTRA_BUTTON); + + if (m_bButton2Enabled) + { + SET_CONTROL_LABEL(CONTROL_EXTRA_BUTTON2, m_button2Label); + SET_CONTROL_VISIBLE(CONTROL_EXTRA_BUTTON2); + } + else + SET_CONTROL_HIDDEN(CONTROL_EXTRA_BUTTON2); + + SET_CONTROL_LABEL(CONTROL_CANCEL_BUTTON, g_localizeStrings.Get(222)); + + CGUIDialogBoxBase::OnInitWindow(); + + // focus one of the buttons if explicitly requested + // ATTENTION: this must be done after calling CGUIDialogBoxBase::OnInitWindow() + if (m_focusToButton) + { + if (m_bButtonEnabled) + SET_CONTROL_FOCUS(CONTROL_EXTRA_BUTTON, 0); + else + SET_CONTROL_FOCUS(CONTROL_CANCEL_BUTTON, 0); + } + + // if nothing is selected, select first item + m_viewControl.SetSelectedItem(std::max(GetSelectedItem(), 0)); +} + +void CGUIDialogSelect::OnDeinitWindow(int nextWindowID) +{ + m_viewControl.Clear(); + CGUIDialogBoxBase::OnDeinitWindow(nextWindowID); +} + +void CGUIDialogSelect::OnWindowUnload() +{ + CGUIDialogBoxBase::OnWindowUnload(); + m_viewControl.Reset(); +} |