PageRenderTime 31ms CodeModel.GetById 17ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

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