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 /*! 12 \file GUIControl.h 13 \brief 14 */ 15 16 #include "DirtyRegion.h" 17 #include "VisibleEffect.h" // needed for the CAnimation members 18 #include "guiinfo/GUIInfoBool.h" 19 #include "guiinfo/GUIInfoColor.h" // needed for CGUIInfoColor to handle infolabel'ed colors 20 #include "utils/Color.h" 21 #include "windowing/GraphicContext.h" // needed by any rendering operation (all controls) 22 23 #include <vector> 24 25 class CGUIListItem; // forward 26 class CAction; 27 class CMouseEvent; 28 class CGUIMessage; 29 class CGUIAction; 30 31 enum ORIENTATION { HORIZONTAL = 0, VERTICAL }; 32 33 class CControlState 34 { 35 public: CControlState(int id,int data)36 CControlState(int id, int data) 37 { 38 m_id = id; 39 m_data = data; 40 } 41 int m_id; 42 int m_data; 43 }; 44 45 struct GUICONTROLSTATS 46 { 47 unsigned int nCountTotal; 48 unsigned int nCountVisible; 49 ResetGUICONTROLSTATS50 void Reset() 51 { 52 nCountTotal = nCountVisible = 0; 53 }; 54 }; 55 56 /*! 57 \brief Results of OnMouseEvent() 58 Any value not equal to EVENT_RESULT_UNHANDLED indicates that the event was handled. 59 */ 60 enum EVENT_RESULT { EVENT_RESULT_UNHANDLED = 0x00, 61 EVENT_RESULT_HANDLED = 0x01, 62 EVENT_RESULT_PAN_HORIZONTAL = 0x02, 63 EVENT_RESULT_PAN_VERTICAL = 0x04, 64 EVENT_RESULT_PAN_VERTICAL_WITHOUT_INERTIA = 0x08, 65 EVENT_RESULT_PAN_HORIZONTAL_WITHOUT_INERTIA = 0x10, 66 EVENT_RESULT_ROTATE = 0x20, 67 EVENT_RESULT_ZOOM = 0x40, 68 EVENT_RESULT_SWIPE = 0x80 69 }; 70 71 /*! 72 \ingroup controls 73 \brief Base class for controls 74 */ 75 class CGUIControl 76 { 77 public: 78 CGUIControl(); 79 CGUIControl(int parentID, int controlID, float posX, float posY, float width, float height); 80 CGUIControl(const CGUIControl &); 81 virtual ~CGUIControl(void); 82 virtual CGUIControl *Clone() const=0; 83 84 virtual void DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyregions); 85 virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions); 86 virtual void DoRender(); Render()87 virtual void Render() {}; 88 // Called after the actual rendering is completed to trigger additional 89 // non GUI rendering operations RenderEx()90 virtual void RenderEx() {}; 91 92 /*! \brief Returns whether or not we have processed */ HasProcessed()93 bool HasProcessed() const { return m_hasProcessed; }; 94 95 // OnAction() is called by our window when we are the focused control. 96 // We should process any control-specific actions in the derived classes, 97 // and return true if we have taken care of the action. Returning false 98 // indicates that the message may be handed down to the window or application 99 // levels. This base class implementation handles basic movement, and should 100 // be called from the derived classes when the action has not been handled. 101 // Return true to indicate that the action has been dealt with. 102 virtual bool OnAction(const CAction &action); 103 104 // Common actions to make the code easier to read (no ugly switch statements in derived controls) 105 virtual void OnUp(); 106 virtual void OnDown(); 107 virtual void OnLeft(); 108 virtual void OnRight(); 109 virtual bool OnBack(); 110 virtual bool OnInfo(); 111 virtual void OnNextControl(); 112 virtual void OnPrevControl(); OnFocus()113 virtual void OnFocus() {}; OnUnFocus()114 virtual void OnUnFocus() {}; 115 116 /*! \brief React to a mouse event 117 118 Mouse events are sent from the window to all controls, and each control can react based on the event 119 and location of the event. 120 121 \param point the location in transformed skin coordinates from the upper left corner of the parent control. 122 \param event the mouse event to perform 123 \return EVENT_RESULT corresponding to whether the control handles this event 124 \sa HitTest, CanFocusFromPoint, CMouseEvent, EVENT_RESULT 125 */ 126 virtual EVENT_RESULT SendMouseEvent(const CPoint &point, const CMouseEvent &event); 127 128 /*! \brief Perform a mouse action 129 130 Mouse actions are sent from the window to all controls, and each control can react based on the event 131 and location of the actions. 132 133 \param point the location in transformed skin coordinates from the upper left corner of the parent control. 134 \param event the mouse event to perform 135 \return EVENT_RESULT corresponding to whether the control handles this event 136 \sa SendMouseEvent, HitTest, CanFocusFromPoint, CMouseEvent 137 */ OnMouseEvent(const CPoint & point,const CMouseEvent & event)138 virtual EVENT_RESULT OnMouseEvent(const CPoint &point, const CMouseEvent &event) { return EVENT_RESULT_UNHANDLED; }; 139 140 /*! \brief Unfocus the control if the given point on screen is not within it's boundary 141 \param point the location in transformed skin coordinates from the upper left corner of the parent control. 142 \sa CanFocusFromPoint 143 */ 144 virtual void UnfocusFromPoint(const CPoint &point); 145 146 /*! \brief Used to test whether the point is inside a control. 147 \param point location to test 148 \return true if the point is inside the bounds of this control. 149 \sa SetHitRect 150 */ 151 virtual bool HitTest(const CPoint &point) const; 152 153 virtual bool OnMessage(CGUIMessage& message); 154 virtual int GetID(void) const; SetID(int id)155 virtual void SetID(int id) { m_controlID = id; }; 156 int GetParentID() const; 157 virtual bool HasFocus() const; 158 virtual void AllocResources(); 159 virtual void FreeResources(bool immediately = false); 160 virtual void DynamicResourceAlloc(bool bOnOff); IsDynamicallyAllocated()161 virtual bool IsDynamicallyAllocated() { return false; }; 162 virtual bool CanFocus() const; 163 virtual bool IsVisible() const; IsVisibleFromSkin()164 bool IsVisibleFromSkin() const { return m_visibleFromSkinCondition; }; 165 virtual bool IsDisabled() const; 166 virtual void SetPosition(float posX, float posY); 167 virtual void SetHitRect(const CRect &rect, const UTILS::Color &color); 168 virtual void SetCamera(const CPoint &camera); 169 virtual void SetStereoFactor(const float &factor); 170 bool SetColorDiffuse(const KODI::GUILIB::GUIINFO::CGUIInfoColor &color); 171 CPoint GetRenderPosition() const; 172 virtual float GetXPosition() const; 173 virtual float GetYPosition() const; 174 virtual float GetWidth() const; 175 virtual float GetHeight() const; 176 177 void MarkDirtyRegion(const unsigned int dirtyState = DIRTY_STATE_CONTROL); IsControlDirty()178 bool IsControlDirty() const { return m_controlDirtyState != 0; }; 179 180 /*! \brief return the render region in screen coordinates of this control 181 */ GetRenderRegion()182 const CRect &GetRenderRegion() const { return m_renderRegion; }; 183 /*! \brief calculate the render region in parentcontrol coordinates of this control 184 Called during process to update m_renderRegion 185 */ 186 virtual CRect CalcRenderRegion() const; 187 188 /*! \brief Set actions to perform on navigation 189 \param actions ActionMap of actions 190 \sa SetNavigationAction 191 */ 192 typedef std::map<int, CGUIAction> ActionMap; 193 void SetActions(const ActionMap &actions); 194 195 /*! \brief Set actions to perform on navigation 196 Navigations are set if replace is true or if there is no previously set action 197 \param actionID id of the navigation action 198 \param action CGUIAction to set 199 \param replace Actions are set only if replace is true or there is no previously set action. Defaults to true 200 \sa SetNavigationActions 201 */ 202 void SetAction(int actionID, const CGUIAction &action, bool replace = true); 203 204 /*! \brief Get an action the control can be perform. 205 \param actionID The actionID to retrieve. 206 */ 207 CGUIAction GetAction(int actionID) const; 208 209 /*! \brief Start navigating in given direction. 210 */ 211 bool Navigate(int direction) const; 212 virtual void SetFocus(bool focus); 213 virtual void SetWidth(float width); 214 virtual void SetHeight(float height); 215 virtual void SetVisible(bool bVisible, bool setVisState = false); 216 void SetVisibleCondition(const std::string &expression, const std::string &allowHiddenFocus = ""); HasVisibleCondition()217 bool HasVisibleCondition() const { return m_visibleCondition != NULL; }; 218 void SetEnableCondition(const std::string &expression); 219 virtual void UpdateVisibility(const CGUIListItem *item); 220 virtual void SetInitialVisibility(); 221 virtual void SetEnabled(bool bEnable); SetInvalid()222 virtual void SetInvalid() { m_bInvalidated = true; }; SetPulseOnSelect(bool pulse)223 virtual void SetPulseOnSelect(bool pulse) { m_pulseOnSelect = pulse; }; GetDescription()224 virtual std::string GetDescription() const { return ""; }; GetDescriptionByIndex(int index)225 virtual std::string GetDescriptionByIndex(int index) const { return ""; }; 226 227 void SetAnimations(const std::vector<CAnimation> &animations); GetAnimations()228 const std::vector<CAnimation> &GetAnimations() const { return m_animations; }; 229 230 virtual void QueueAnimation(ANIMATION_TYPE anim); 231 virtual bool IsAnimating(ANIMATION_TYPE anim); 232 virtual bool HasAnimation(ANIMATION_TYPE anim); 233 CAnimation *GetAnimation(ANIMATION_TYPE type, bool checkConditions = true); 234 virtual void ResetAnimation(ANIMATION_TYPE type); 235 virtual void ResetAnimations(); 236 237 // push information updates 238 virtual void UpdateInfo(const CGUIListItem *item = NULL) {}; SetPushUpdates(bool pushUpdates)239 virtual void SetPushUpdates(bool pushUpdates) { m_pushedUpdates = pushUpdates; }; 240 IsGroup()241 virtual bool IsGroup() const { return false; }; IsContainer()242 virtual bool IsContainer() const { return false; }; GetCondition(int condition,int data)243 virtual bool GetCondition(int condition, int data) const { return false; }; 244 SetParentControl(CGUIControl * control)245 void SetParentControl(CGUIControl *control) { m_parentControl = control; }; GetParentControl(void)246 CGUIControl *GetParentControl(void) const { return m_parentControl; }; 247 virtual void SaveStates(std::vector<CControlState> &states); 248 virtual CGUIControl *GetControl(int id, std::vector<CGUIControl*> *idCollector = nullptr); 249 250 SetControlStats(GUICONTROLSTATS * controlStats)251 void SetControlStats(GUICONTROLSTATS *controlStats) { m_controlStats = controlStats; }; 252 virtual void UpdateControlStats(); 253 254 enum GUICONTROLTYPES { 255 GUICONTROL_UNKNOWN, 256 GUICONTROL_BUTTON, 257 GUICONTROL_FADELABEL, 258 GUICONTROL_IMAGE, 259 GUICONTROL_BORDEREDIMAGE, 260 GUICONTROL_LABEL, 261 GUICONTROL_LISTGROUP, 262 GUICONTROL_PROGRESS, 263 GUICONTROL_RADIO, 264 GUICONTROL_RSS, 265 GUICONTROL_SLIDER, 266 GUICONTROL_SETTINGS_SLIDER, 267 GUICONTROL_SPIN, 268 GUICONTROL_SPINEX, 269 GUICONTROL_TEXTBOX, 270 GUICONTROL_TOGGLEBUTTON, 271 GUICONTROL_VIDEO, 272 GUICONTROL_GAME, 273 GUICONTROL_MOVER, 274 GUICONTROL_RESIZE, 275 GUICONTROL_EDIT, 276 GUICONTROL_VISUALISATION, 277 GUICONTROL_RENDERADDON, 278 GUICONTROL_MULTI_IMAGE, 279 GUICONTROL_GROUP, 280 GUICONTROL_GROUPLIST, 281 GUICONTROL_SCROLLBAR, 282 GUICONTROL_LISTLABEL, 283 GUICONTROL_GAMECONTROLLER, 284 GUICONTAINER_LIST, 285 GUICONTAINER_WRAPLIST, 286 GUICONTAINER_FIXEDLIST, 287 GUICONTAINER_EPGGRID, 288 GUICONTAINER_PANEL, 289 GUICONTROL_RANGES 290 }; GetControlType()291 GUICONTROLTYPES GetControlType() const { return ControlType; } 292 293 enum GUIVISIBLE { HIDDEN = 0, DELAYED, VISIBLE }; 294 295 enum GUISCROLLVALUE { FOCUS = 0, NEVER, ALWAYS }; 296 297 #ifdef _DEBUG DumpTextureUse()298 virtual void DumpTextureUse() {}; 299 #endif 300 protected: 301 /*! 302 \brief Return the coordinates of the top left of the control, in the control's parent coordinates 303 \return The top left coordinates of the control 304 */ GetPosition()305 virtual CPoint GetPosition() const { return CPoint(GetXPosition(), GetYPosition()); }; 306 307 /*! \brief Called when the mouse is over the control. 308 Default implementation selects the control. 309 \param point location of the mouse in transformed skin coordinates 310 \return true if handled, false otherwise. 311 */ 312 virtual bool OnMouseOver(const CPoint &point); 313 314 /*! \brief Test whether we can focus a control from a point on screen 315 \param point the location in vanilla skin coordinates from the upper left corner of the parent control. 316 \return true if the control can be focused from this location 317 \sa UnfocusFromPoint, HitRect 318 */ 319 virtual bool CanFocusFromPoint(const CPoint &point) const; 320 321 virtual bool UpdateColors(); 322 virtual bool Animate(unsigned int currentTime); 323 virtual bool CheckAnimation(ANIMATION_TYPE animType); 324 void UpdateStates(ANIMATION_TYPE type, ANIMATION_PROCESS currentProcess, ANIMATION_STATE currentState); 325 bool SendWindowMessage(CGUIMessage &message) const; 326 327 // navigation and actions 328 ActionMap m_actions; 329 330 float m_posX; 331 float m_posY; 332 float m_height; 333 float m_width; 334 CRect m_hitRect; 335 UTILS::Color m_hitColor = 0xffffffff; 336 KODI::GUILIB::GUIINFO::CGUIInfoColor m_diffuseColor; 337 int m_controlID; 338 int m_parentID; 339 bool m_bHasFocus; 340 bool m_bInvalidated; 341 bool m_bAllocated; 342 bool m_pulseOnSelect; 343 GUICONTROLTYPES ControlType; 344 GUICONTROLSTATS *m_controlStats; 345 346 CGUIControl *m_parentControl; // our parent control if we're part of a group 347 348 // visibility condition/state 349 INFO::InfoPtr m_visibleCondition; 350 GUIVISIBLE m_visible; 351 bool m_visibleFromSkinCondition; 352 bool m_forceHidden; // set from the code when a hidden operation is given - overrides m_visible 353 KODI::GUILIB::GUIINFO::CGUIInfoBool m_allowHiddenFocus; 354 bool m_hasProcessed; 355 // enable/disable state 356 INFO::InfoPtr m_enableCondition; 357 bool m_enabled; 358 359 bool m_pushedUpdates; 360 361 // animation effects 362 std::vector<CAnimation> m_animations; 363 CPoint m_camera; 364 bool m_hasCamera; 365 float m_stereo; 366 TransformMatrix m_transform; 367 TransformMatrix m_cachedTransform; // Contains the absolute transform the control 368 369 static const unsigned int DIRTY_STATE_CONTROL = 1; //This control is dirty 370 static const unsigned int DIRTY_STATE_CHILD = 2; //One / more children are dirty 371 372 unsigned int m_controlDirtyState; 373 CRect m_renderRegion; // In screen coordinates 374 }; 375 376