/xbmc/guilib/GUIWindowManager.h

http://github.com/xbmc/xbmc · C Header · 270 lines · 126 code · 43 blank · 101 comment · 2 complexity · 7765bb624147775a77a8c4e5eeaf7a45 MD5 · raw file

  1. /*
  2. * Copyright (C) 2005-2018 Team Kodi
  3. * This file is part of Kodi - https://kodi.tv
  4. *
  5. * SPDX-License-Identifier: GPL-2.0-or-later
  6. * See LICENSES/README.md for more information.
  7. */
  8. #pragma once
  9. #include "DirtyRegionTracker.h"
  10. #include "GUIWindow.h"
  11. #include "IMsgTargetCallback.h"
  12. #include "IWindowManagerCallback.h"
  13. #include "guilib/WindowIDs.h"
  14. #include "messaging/IMessageTarget.h"
  15. #include <list>
  16. #include <unordered_map>
  17. #include <utility>
  18. #include <vector>
  19. class CGUIDialog;
  20. class CGUIMediaWindow;
  21. #ifdef TARGET_WINDOWS_STORE
  22. #pragma pack(push, 8)
  23. #endif
  24. enum class DialogModalityType;
  25. #ifdef TARGET_WINDOWS_STORE
  26. #pragma pack(pop)
  27. #endif
  28. namespace KODI
  29. {
  30. namespace MESSAGING
  31. {
  32. class CApplicationMessenger;
  33. }
  34. }
  35. #define WINDOW_ID_MASK 0xffff
  36. /*!
  37. \ingroup winman
  38. \brief
  39. */
  40. class CGUIWindowManager : public KODI::MESSAGING::IMessageTarget
  41. {
  42. friend CGUIDialog;
  43. friend CGUIMediaWindow;
  44. public:
  45. CGUIWindowManager();
  46. ~CGUIWindowManager() override;
  47. bool SendMessage(CGUIMessage& message);
  48. bool SendMessage(int message, int senderID, int destID, int param1 = 0, int param2 = 0);
  49. bool SendMessage(CGUIMessage& message, int window);
  50. void Initialize();
  51. void Add(CGUIWindow* pWindow);
  52. void AddUniqueInstance(CGUIWindow *window);
  53. void AddCustomWindow(CGUIWindow* pWindow);
  54. void Remove(int id);
  55. void Delete(int id);
  56. void ActivateWindow(int iWindowID, const std::string &strPath = "");
  57. void ForceActivateWindow(int iWindowID, const std::string &strPath = "");
  58. void ChangeActiveWindow(int iNewID, const std::string &strPath = "");
  59. void ActivateWindow(int iWindowID, const std::vector<std::string>& params, bool swappingWindows = false, bool force = false);
  60. void PreviousWindow();
  61. void CloseDialogs(bool forceClose = false) const;
  62. void CloseInternalModalDialogs(bool forceClose = false) const;
  63. void OnApplicationMessage(KODI::MESSAGING::ThreadMessage* pMsg) override;
  64. int GetMessageMask() override;
  65. // OnAction() runs through our active dialogs and windows and sends the message
  66. // off to the callbacks (application, python, playlist player) and to the
  67. // currently focused window(s). Returns true only if the message is handled.
  68. bool OnAction(const CAction &action) const;
  69. /*! \brief Process active controls allowing them to animate before rendering.
  70. */
  71. void Process(unsigned int currentTime);
  72. /*! \brief Mark the screen as dirty, forcing a redraw at the next Render()
  73. */
  74. void MarkDirty();
  75. /*! \brief Mark a region as dirty, forcing a redraw at the next Render()
  76. */
  77. void MarkDirty(const CRect& rect);
  78. /*! \brief Rendering of the current window and any dialogs
  79. Render is called every frame to draw the current window and any dialogs.
  80. It should only be called from the application thread.
  81. Returns true only if it has rendered something.
  82. */
  83. bool Render();
  84. void RenderEx() const;
  85. /*! \brief Do any post render activities.
  86. */
  87. void AfterRender();
  88. /*! \brief Per-frame updating of the current window and any dialogs
  89. FrameMove is called every frame to update the current window and any dialogs
  90. on screen. It should only be called from the application thread.
  91. */
  92. void FrameMove();
  93. /*! \brief Return whether the window manager is initialized.
  94. The window manager is initialized on skin load - if the skin isn't yet loaded,
  95. no windows should be able to be initialized.
  96. \return true if the window manager is initialized, false otherwise.
  97. */
  98. bool Initialized() const { return m_initialized; };
  99. /*! \brief Create and initialize all windows and dialogs
  100. */
  101. void CreateWindows();
  102. /*! \brief Destroy and remove all windows and dialogs
  103. *
  104. * \return true on success, false if destruction fails for any window
  105. */
  106. bool DestroyWindows();
  107. /*! \brief Destroy and remove the window or dialog with the given id
  108. *
  109. *\param id the window id
  110. */
  111. void DestroyWindow(int id);
  112. /*! \brief Return the window of type \code{T} with the given id or
  113. * null if no window exists with the given id.
  114. *
  115. * \tparam T the window class type
  116. * \param id the window id
  117. * \return the window with for the given type \code{T} or null
  118. */
  119. template<typename T, typename std::enable_if<std::is_base_of<CGUIWindow,T>::value>::type* = nullptr>
  120. T* GetWindow(int id) const { return dynamic_cast<T *>(GetWindow(id)); };
  121. /*! \brief Return the window with the given id or null.
  122. *
  123. * \param id the window id
  124. * \return the window with the given id or null
  125. */
  126. CGUIWindow* GetWindow(int id) const;
  127. /*! \brief Return the dialog window with the given id or null.
  128. *
  129. * \param id the dialog window id
  130. * \return the dialog window with the given id or null
  131. */
  132. CGUIDialog* GetDialog(int id) const;
  133. void SetCallback(IWindowManagerCallback& callback);
  134. void DeInitialize();
  135. /*! \brief Register a dialog as active dialog
  136. *
  137. * \param dialog The dialog to register as active dialog
  138. */
  139. void RegisterDialog(CGUIWindow* dialog);
  140. void RemoveDialog(int id);
  141. /*! \brief Get the ID of the topmost dialog
  142. *
  143. * \param ignoreClosing ignore dialog is closing
  144. * \return the ID of the topmost dialog or WINDOW_INVALID if no dialog is active
  145. */
  146. int GetTopmostDialog(bool ignoreClosing = false) const;
  147. /*! \brief Get the ID of the topmost modal dialog
  148. *
  149. * \param ignoreClosing ignore dialog is closing
  150. * \return the ID of the topmost modal dialog or WINDOW_INVALID if no modal dialog is active
  151. */
  152. int GetTopmostModalDialog(bool ignoreClosing = false) const;
  153. void SendThreadMessage(CGUIMessage& message, int window = 0);
  154. void DispatchThreadMessages();
  155. // method to removed queued messages with message id in the requested message id list.
  156. // pMessageIDList: point to first integer of a 0 ends integer array.
  157. int RemoveThreadMessageByMessageIds(int *pMessageIDList);
  158. void AddMsgTarget( IMsgTargetCallback* pMsgTarget );
  159. int GetActiveWindow() const;
  160. int GetActiveWindowOrDialog() const;
  161. bool HasModalDialog(bool ignoreClosing) const;
  162. bool HasVisibleModalDialog() const;
  163. bool IsDialogTopmost(int id, bool modal = false) const;
  164. bool IsDialogTopmost(const std::string &xmlFile, bool modal = false) const;
  165. bool IsModalDialogTopmost(int id) const;
  166. bool IsModalDialogTopmost(const std::string &xmlFile) const;
  167. bool IsWindowActive(int id, bool ignoreClosing = true) const;
  168. bool IsWindowVisible(int id) const;
  169. bool IsWindowActive(const std::string &xmlFile, bool ignoreClosing = true) const;
  170. bool IsWindowVisible(const std::string &xmlFile) const;
  171. /*! \brief Checks if the given window is an addon window.
  172. *
  173. * \return true if the given window is an addon window, otherwise false.
  174. */
  175. bool IsAddonWindow(int id) const { return (id >= WINDOW_ADDON_START && id <= WINDOW_ADDON_END); };
  176. /*! \brief Checks if the given window is a python window.
  177. *
  178. * \return true if the given window is a python window, otherwise false.
  179. */
  180. bool IsPythonWindow(int id) const { return (id >= WINDOW_PYTHON_START && id <= WINDOW_PYTHON_END); };
  181. bool HasVisibleControls();
  182. #ifdef _DEBUG
  183. void DumpTextureUse();
  184. #endif
  185. private:
  186. void RenderPass() const;
  187. void LoadNotOnDemandWindows();
  188. void UnloadNotOnDemandWindows();
  189. void AddToWindowHistory(int newWindowID);
  190. /*!
  191. \brief Check if the given window id is in the window history, and if so, remove this
  192. window and all overlying windows from the history so that we always have a predictable
  193. "Back" behaviour for each window.
  194. \param windowID the window id to remove from the window history
  195. */
  196. void RemoveFromWindowHistory(int windowID);
  197. void ClearWindowHistory();
  198. void CloseWindowSync(CGUIWindow *window, int nextWindowID = 0);
  199. int GetTopmostDialog(bool modal, bool ignoreClosing) const;
  200. friend class KODI::MESSAGING::CApplicationMessenger;
  201. /*! \brief Activate the given window.
  202. *
  203. * \param windowID The window ID to activate.
  204. * \param params Parameter
  205. * \param swappingWindows True if the window should be swapped with the previous window instead of put it in the window history, otherwise false
  206. * \param force True to ignore checks which refuses opening the window, otherwise false
  207. */
  208. void ActivateWindow_Internal(int windowID, const std::vector<std::string> &params, bool swappingWindows, bool force = false);
  209. bool ProcessRenderLoop(bool renderOnly);
  210. bool HandleAction(const CAction &action) const;
  211. std::unordered_map<int, CGUIWindow*> m_mapWindows;
  212. std::vector<CGUIWindow*> m_vecCustomWindows;
  213. std::vector<CGUIWindow*> m_activeDialogs;
  214. std::vector<CGUIWindow*> m_deleteWindows;
  215. std::deque<int> m_windowHistory;
  216. IWindowManagerCallback* m_pCallback;
  217. std::list< std::pair<CGUIMessage*,int> > m_vecThreadMessages;
  218. CCriticalSection m_critSection;
  219. std::vector<IMsgTargetCallback*> m_vecMsgTargets;
  220. int m_iNested;
  221. bool m_initialized;
  222. mutable bool m_touchGestureActive{false};
  223. mutable bool m_inhibitTouchGestureEvents{false};
  224. CDirtyRegionList m_dirtyregions;
  225. CDirtyRegionTracker m_tracker;
  226. };