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 GUIListContainer.h 13 \brief 14 */ 15 16 #include "GUIAction.h" 17 #include "IGUIContainer.h" 18 #include "utils/Stopwatch.h" 19 20 #include <list> 21 #include <utility> 22 #include <vector> 23 24 /*! 25 \ingroup controls 26 \brief 27 */ 28 29 class IListProvider; 30 class TiXmlNode; 31 class CGUIListItemLayout; 32 33 class CGUIBaseContainer : public IGUIContainer 34 { 35 public: 36 CGUIBaseContainer(int parentID, int controlID, float posX, float posY, float width, float height, ORIENTATION orientation, const CScroller& scroller, int preloadItems); 37 CGUIBaseContainer(const CGUIBaseContainer &); 38 ~CGUIBaseContainer(void) override; 39 40 bool OnAction(const CAction &action) override; 41 void OnDown() override; 42 void OnUp() override; 43 void OnLeft() override; 44 void OnRight() override; 45 bool OnMouseOver(const CPoint &point) override; 46 bool CanFocus() const override; 47 bool OnMessage(CGUIMessage& message) override; 48 void SetFocus(bool bOnOff) override; 49 void AllocResources() override; 50 void FreeResources(bool immediately = false) override; 51 void UpdateVisibility(const CGUIListItem *item = NULL) override; 52 53 virtual unsigned int GetRows() const; 54 55 virtual bool HasNextPage() const; 56 virtual bool HasPreviousPage() const; 57 58 void SetPageControl(int id); 59 60 std::string GetDescription() const override; 61 void SaveStates(std::vector<CControlState> &states) override; 62 virtual int GetSelectedItem() const; 63 64 void DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyregions) override; 65 void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) override; 66 67 void LoadLayout(TiXmlElement *layout); 68 void LoadListProvider(TiXmlElement *content, int defaultItem, bool defaultAlways); 69 70 CGUIListItemPtr GetListItem(int offset, unsigned int flag = 0) const override; 71 72 bool GetCondition(int condition, int data) const override; 73 std::string GetLabel(int info) const override; 74 75 /*! \brief Set the list provider for this container (for python). 76 \param provider the list provider to use for this container. 77 */ 78 void SetListProvider(IListProvider *provider); 79 80 /*! \brief Set the offset of the first item in the container from the container's position 81 Useful for lists/panels where the focused item may be larger than the non-focused items and thus 82 normally cut off from the clipping window defined by the container's position + size. 83 \param offset CPoint holding the offset in skin coordinates. 84 */ 85 void SetRenderOffset(const CPoint &offset); 86 SetClickActions(const CGUIAction & clickActions)87 void SetClickActions(const CGUIAction& clickActions) { m_clickActions = clickActions; }; SetFocusActions(const CGUIAction & focusActions)88 void SetFocusActions(const CGUIAction& focusActions) { m_focusActions = focusActions; }; SetUnFocusActions(const CGUIAction & unfocusActions)89 void SetUnFocusActions(const CGUIAction& unfocusActions) { m_unfocusActions = unfocusActions; }; 90 91 void SetAutoScrolling(const TiXmlNode *node); 92 void ResetAutoScrolling(); 93 void UpdateAutoScrolling(unsigned int currentTime); 94 95 #ifdef _DEBUG 96 void DumpTextureUse() override; 97 #endif 98 protected: 99 EVENT_RESULT OnMouseEvent(const CPoint &point, const CMouseEvent &event) override; 100 bool OnClick(int actionID); 101 102 virtual void ProcessItem(float posX, float posY, CGUIListItemPtr& item, bool focused, unsigned int currentTime, CDirtyRegionList &dirtyregions); 103 104 void Render() override; 105 virtual void RenderItem(float posX, float posY, CGUIListItem *item, bool focused); 106 virtual void Scroll(int amount); 107 virtual bool MoveDown(bool wrapAround); 108 virtual bool MoveUp(bool wrapAround); 109 virtual bool GetOffsetRange(int &minOffset, int &maxOffset) const; 110 virtual void ValidateOffset(); 111 virtual int CorrectOffset(int offset, int cursor) const; 112 virtual void UpdateLayout(bool refreshAllItems = false); 113 virtual void SetPageControlRange(); 114 virtual void UpdatePageControl(int offset); 115 virtual void CalculateLayout(); SelectItem(int item)116 virtual void SelectItem(int item) {}; SelectItemFromPoint(const CPoint & point)117 virtual bool SelectItemFromPoint(const CPoint &point) { return false; }; 118 virtual int GetCursorFromPoint(const CPoint &point, CPoint *itemPoint = NULL) const { return -1; }; 119 virtual void Reset(); GetNumItems()120 virtual size_t GetNumItems() const { return m_items.size(); }; 121 virtual int GetCurrentPage() const; 122 bool InsideLayout(const CGUIListItemLayout *layout, const CPoint &point) const; 123 void OnFocus() override; 124 void OnUnFocus() override; 125 void UpdateListProvider(bool forceRefresh = false); 126 127 int ScrollCorrectionRange() const; 128 inline float Size() const; 129 void FreeMemory(int keepStart, int keepEnd); 130 void GetCurrentLayouts(); 131 CGUIListItemLayout *GetFocusedLayout() const; 132 133 CPoint m_renderOffset; ///< \brief render offset of the first item in the list \sa SetRenderOffset 134 135 float m_analogScrollCount; 136 unsigned int m_lastHoldTime; 137 138 ORIENTATION m_orientation; 139 int m_itemsPerPage; 140 141 std::vector< CGUIListItemPtr > m_items; 142 typedef std::vector<CGUIListItemPtr> ::iterator iItems; 143 CGUIListItemPtr m_lastItem; 144 145 int m_pageControl; 146 147 std::list<CGUIListItemLayout> m_layouts; 148 std::list<CGUIListItemLayout> m_focusedLayouts; 149 150 CGUIListItemLayout *m_layout; 151 CGUIListItemLayout *m_focusedLayout; 152 bool m_layoutCondition = false; 153 bool m_focusedLayoutCondition = false; 154 155 void ScrollToOffset(int offset); 156 void SetContainerMoving(int direction); 157 void UpdateScrollOffset(unsigned int currentTime); 158 159 CScroller m_scroller; 160 161 IListProvider *m_listProvider; 162 163 bool m_wasReset; // true if we've received a Reset message until we've rendered once. Allows 164 // us to make sure we don't tell the infomanager that we've been moving when 165 // the "movement" was simply due to the list being repopulated (thus cursor position 166 // changing around) 167 168 void UpdateScrollByLetter(); 169 void GetCacheOffsets(int &cacheBefore, int &cacheAfter) const; GetCacheCount()170 int GetCacheCount() const { return m_cacheItems; }; ScrollingDown()171 bool ScrollingDown() const { return m_scroller.IsScrollingDown(); }; ScrollingUp()172 bool ScrollingUp() const { return m_scroller.IsScrollingUp(); }; 173 void OnNextLetter(); 174 void OnPrevLetter(); 175 void OnJumpLetter(const std::string& letter, bool skip = false); 176 void OnJumpSMS(int letter); 177 std::vector< std::pair<int, std::string> > m_letterOffsets; 178 179 /*! \brief Set the cursor position 180 Should be used by all base classes rather than directly setting it, as 181 this also marks the control as dirty (if needed) 182 */ 183 virtual void SetCursor(int cursor); GetCursor()184 inline int GetCursor() const { return m_cursor; }; 185 186 /*! \brief Set the container offset 187 Should be used by all base classes rather than directly setting it, as 188 this also marks the control as dirty (if needed) 189 */ 190 void SetOffset(int offset); 191 /*! \brief Returns the index of the first visible row 192 returns the first row. This may be outside of the range of available items. Use GetItemOffset() to retrieve the first visible item in the list. 193 \sa GetItemOffset 194 */ GetOffset()195 inline int GetOffset() const { return m_offset; }; 196 /*! \brief Returns the index of the first visible item 197 returns the first visible item. This will always be in the range of available items. Use GetOffset() to retrieve the first visible row in the list. 198 \sa GetOffset 199 */ GetItemOffset()200 inline int GetItemOffset() const { return CorrectOffset(GetOffset(), 0); } 201 202 // autoscrolling 203 INFO::InfoPtr m_autoScrollCondition; 204 int m_autoScrollMoveTime; // time between to moves 205 unsigned int m_autoScrollDelayTime; // current offset into the delay 206 bool m_autoScrollIsReversed; // scroll backwards 207 208 unsigned int m_lastRenderTime; 209 210 private: 211 bool OnContextMenu(); 212 213 int m_cursor; 214 int m_offset; 215 int m_cacheItems; 216 CStopWatch m_scrollTimer; 217 CStopWatch m_lastScrollStartTimer; 218 CStopWatch m_pageChangeTimer; 219 220 CGUIAction m_clickActions; 221 CGUIAction m_focusActions; 222 CGUIAction m_unfocusActions; 223 224 // letter match searching 225 CStopWatch m_matchTimer; 226 std::string m_match; 227 float m_scrollItemsPerFrame; 228 static const int letter_match_timeout = 1000; 229 230 bool m_gestureActive = false; 231 232 // early inertial scroll cancellation 233 bool m_waitForScrollEnd = false; 234 float m_lastScrollValue = 0.0f; 235 }; 236 237 238