PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llui/llscrolllistctrl.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 513 lines | 322 code | 107 blank | 84 comment | 6 complexity | b65b9664b98bfba18c579f68e806fb5d MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llscrolllistctrl.h
  3. * @brief A scrolling list of items. This is the one you want to use
  4. * in UI code. LLScrollListCell, LLScrollListItem, etc. are utility
  5. * classes.
  6. *
  7. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #ifndef LL_SCROLLLISTCTRL_H
  29. #define LL_SCROLLLISTCTRL_H
  30. #include <vector>
  31. #include <deque>
  32. #include "lluictrl.h"
  33. #include "llctrlselectioninterface.h"
  34. //#include "lldarray.h"
  35. #include "llfontgl.h"
  36. #include "llui.h"
  37. #include "llstring.h" // LLWString
  38. #include "lleditmenuhandler.h"
  39. #include "llframetimer.h"
  40. #include "llscrollbar.h"
  41. #include "lldate.h"
  42. #include "llscrolllistitem.h"
  43. #include "llscrolllistcolumn.h"
  44. #include "llviewborder.h"
  45. class LLScrollListCell;
  46. class LLTextBox;
  47. class LLContextMenu;
  48. class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
  49. public LLCtrlListInterface, public LLCtrlScrollInterface
  50. {
  51. public:
  52. struct Contents : public LLInitParam::Block<Contents>
  53. {
  54. Multiple<LLScrollListColumn::Params> columns;
  55. Multiple<LLScrollListItem::Params> rows;
  56. //Multiple<Contents> groups;
  57. Contents();
  58. };
  59. // *TODO: Add callbacks to Params
  60. typedef boost::function<void (void)> callback_t;
  61. template<typename T> struct maximum
  62. {
  63. typedef T result_type;
  64. template<typename InputIterator>
  65. T operator()(InputIterator first, InputIterator last) const
  66. {
  67. // If there are no slots to call, just return the
  68. // default-constructed value
  69. if(first == last ) return T();
  70. T max_value = *first++;
  71. while (first != last) {
  72. if (max_value < *first)
  73. max_value = *first;
  74. ++first;
  75. }
  76. return max_value;
  77. }
  78. };
  79. typedef boost::signals2::signal<S32 (S32,const LLScrollListItem*,const LLScrollListItem*),maximum<S32> > sort_signal_t;
  80. struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
  81. {
  82. // behavioral flags
  83. Optional<bool> multi_select,
  84. commit_on_keyboard_movement,
  85. mouse_wheel_opaque;
  86. // display flags
  87. Optional<bool> has_border,
  88. draw_heading,
  89. draw_stripes,
  90. background_visible,
  91. scroll_bar_bg_visible;
  92. // layout
  93. Optional<S32> column_padding,
  94. page_lines,
  95. heading_height;
  96. // sort and search behavior
  97. Optional<S32> search_column,
  98. sort_column;
  99. Optional<bool> sort_ascending;
  100. // colors
  101. Optional<LLUIColor> fg_unselected_color,
  102. fg_selected_color,
  103. bg_selected_color,
  104. fg_disable_color,
  105. bg_writeable_color,
  106. bg_readonly_color,
  107. bg_stripe_color,
  108. hovered_color,
  109. highlighted_color,
  110. scroll_bar_bg_color;
  111. Optional<Contents> contents;
  112. Optional<LLViewBorder::Params> border;
  113. Params();
  114. };
  115. protected:
  116. friend class LLUICtrlFactory;
  117. LLScrollListCtrl(const Params&);
  118. public:
  119. virtual ~LLScrollListCtrl();
  120. S32 isEmpty() const;
  121. void deleteAllItems() { clearRows(); }
  122. // Sets an array of column descriptors
  123. void setColumnHeadings(const LLSD& headings);
  124. void sortByColumnIndex(U32 column, BOOL ascending);
  125. // LLCtrlListInterface functions
  126. virtual S32 getItemCount() const;
  127. // Adds a single column descriptor: ["name" : string, "label" : string, "width" : integer, "relwidth" : integer ]
  128. virtual void addColumn(const LLScrollListColumn::Params& column, EAddPosition pos = ADD_BOTTOM);
  129. virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM);
  130. virtual void clearColumns();
  131. virtual void setColumnLabel(const std::string& column, const std::string& label);
  132. virtual bool preProcessChildNode(LLXMLNodePtr child);
  133. virtual LLScrollListColumn* getColumn(S32 index);
  134. virtual LLScrollListColumn* getColumn(const std::string& name);
  135. virtual S32 getNumColumns() const { return mColumnsIndexed.size(); }
  136. // Adds a single element, from an array of:
  137. // "columns" => [ "column" => column name, "value" => value, "type" => type, "font" => font, "font-style" => style ], "id" => uuid
  138. // Creates missing columns automatically.
  139. virtual LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
  140. virtual LLScrollListItem* addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM);
  141. virtual LLScrollListItem* addRow(const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM);
  142. // Simple add element. Takes a single array of:
  143. // [ "value" => value, "font" => font, "font-style" => style ]
  144. virtual void clearRows(); // clears all elements
  145. virtual void sortByColumn(const std::string& name, BOOL ascending);
  146. // These functions take and return an array of arrays of elements, as above
  147. virtual void setValue(const LLSD& value );
  148. virtual LLSD getValue() const;
  149. LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; }
  150. LLCtrlListInterface* getListInterface() { return (LLCtrlListInterface*)this; }
  151. LLCtrlScrollInterface* getScrollInterface() { return (LLCtrlScrollInterface*)this; }
  152. // DEPRECATED: Use setSelectedByValue() below.
  153. BOOL setCurrentByID( const LLUUID& id ) { return selectByID(id); }
  154. virtual LLUUID getCurrentID() const { return getStringUUIDSelectedItem(); }
  155. BOOL operateOnSelection(EOperation op);
  156. BOOL operateOnAll(EOperation op);
  157. // returns FALSE if unable to set the max count so low
  158. BOOL setMaxItemCount(S32 max_count);
  159. BOOL selectByID( const LLUUID& id ); // FALSE if item not found
  160. // Match item by value.asString(), which should work for string, integer, uuid.
  161. // Returns FALSE if not found.
  162. BOOL setSelectedByValue(const LLSD& value, BOOL selected);
  163. BOOL isSorted() const { return mSorted; }
  164. virtual BOOL isSelected(const LLSD& value) const;
  165. BOOL handleClick(S32 x, S32 y, MASK mask);
  166. BOOL selectFirstItem();
  167. BOOL selectNthItem( S32 index );
  168. BOOL selectItemRange( S32 first, S32 last );
  169. BOOL selectItemAt(S32 x, S32 y, MASK mask);
  170. void deleteSingleItem( S32 index );
  171. void deleteItems(const LLSD& sd);
  172. void deleteSelectedItems();
  173. void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change
  174. void clearHighlightedItems();
  175. virtual void mouseOverHighlightNthItem( S32 index );
  176. S32 getHighlightedItemInx() const { return mHighlightedItem; }
  177. void setDoubleClickCallback( callback_t cb ) { mOnDoubleClickCallback = cb; }
  178. void setMaximumSelectCallback( callback_t cb) { mOnMaximumSelectCallback = cb; }
  179. void setSortChangedCallback( callback_t cb) { mOnSortChangedCallback = cb; }
  180. // Convenience function; *TODO: replace with setter above + boost::bind() in calling code
  181. void setDoubleClickCallback( boost::function<void (void* userdata)> cb, void* userdata) { mOnDoubleClickCallback = boost::bind(cb, userdata); }
  182. void swapWithNext(S32 index);
  183. void swapWithPrevious(S32 index);
  184. void setCanSelect(BOOL can_select) { mCanSelect = can_select; }
  185. virtual BOOL getCanSelect() const { return mCanSelect; }
  186. S32 getItemIndex( LLScrollListItem* item ) const;
  187. S32 getItemIndex( const LLUUID& item_id ) const;
  188. void setCommentText( const std::string& comment_text);
  189. LLScrollListItem* addSeparator(EAddPosition pos);
  190. // "Simple" interface: use this when you're creating a list that contains only unique strings, only
  191. // one of which can be selected at a time.
  192. virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD());
  193. BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE ); // FALSE if item not found
  194. BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE);
  195. BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE);
  196. LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 );
  197. const std::string getSelectedItemLabel(S32 column = 0) const;
  198. LLSD getSelectedValue();
  199. // DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue().
  200. // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
  201. // has an associated, unique UUID, and only one of which can be selected at a time.
  202. LLScrollListItem* addStringUUIDItem(const std::string& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE);
  203. LLUUID getStringUUIDSelectedItem() const;
  204. LLScrollListItem* getFirstSelected() const;
  205. virtual S32 getFirstSelectedIndex() const;
  206. std::vector<LLScrollListItem*> getAllSelected() const;
  207. LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
  208. // iterate over all items
  209. LLScrollListItem* getFirstData() const;
  210. LLScrollListItem* getLastData() const;
  211. std::vector<LLScrollListItem*> getAllData() const;
  212. LLScrollListItem* getItem(const LLSD& sd) const;
  213. void setAllowMultipleSelection(BOOL mult ) { mAllowMultipleSelection = mult; }
  214. void setBgWriteableColor(const LLColor4 &c) { mBgWriteableColor = c; }
  215. void setReadOnlyBgColor(const LLColor4 &c) { mBgReadOnlyColor = c; }
  216. void setBgSelectedColor(const LLColor4 &c) { mBgSelectedColor = c; }
  217. void setBgStripeColor(const LLColor4& c) { mBgStripeColor = c; }
  218. void setFgSelectedColor(const LLColor4 &c) { mFgSelectedColor = c; }
  219. void setFgUnselectedColor(const LLColor4 &c){ mFgUnselectedColor = c; }
  220. void setHoveredColor(const LLColor4 &c) { mHoveredColor = c; }
  221. void setHighlightedColor(const LLColor4 &c) { mHighlightedColor = c; }
  222. void setFgDisableColor(const LLColor4 &c) { mFgDisabledColor = c; }
  223. void setBackgroundVisible(BOOL b) { mBackgroundVisible = b; }
  224. void setDrawStripes(BOOL b) { mDrawStripes = b; }
  225. void setColumnPadding(const S32 c) { mColumnPadding = c; }
  226. S32 getColumnPadding() { return mColumnPadding; }
  227. void setCommitOnKeyboardMovement(BOOL b) { mCommitOnKeyboardMovement = b; }
  228. void setCommitOnSelectionChange(BOOL b) { mCommitOnSelectionChange = b; }
  229. void setAllowKeyboardMovement(BOOL b) { mAllowKeyboardMovement = b; }
  230. void setMaxSelectable(U32 max_selected) { mMaxSelectable = max_selected; }
  231. S32 getMaxSelectable() { return mMaxSelectable; }
  232. virtual S32 getScrollPos() const;
  233. virtual void setScrollPos( S32 pos );
  234. S32 getSearchColumn();
  235. void setSearchColumn(S32 column) { mSearchColumn = column; }
  236. S32 getColumnIndexFromOffset(S32 x);
  237. S32 getColumnOffsetFromIndex(S32 index);
  238. S32 getRowOffsetFromIndex(S32 index);
  239. void clearSearchString() { mSearchString.clear(); }
  240. // support right-click context menus for avatar/group lists
  241. enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP };
  242. void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; }
  243. // Overridden from LLView
  244. /*virtual*/ void draw();
  245. /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
  246. /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
  247. /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
  248. /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
  249. /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
  250. /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
  251. /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
  252. /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
  253. /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
  254. /*virtual*/ void setEnabled(BOOL enabled);
  255. /*virtual*/ void setFocus( BOOL b );
  256. /*virtual*/ void onFocusReceived();
  257. /*virtual*/ void onFocusLost();
  258. /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
  259. /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
  260. virtual BOOL isDirty() const;
  261. virtual void resetDirty(); // Clear dirty state
  262. virtual void updateLayout();
  263. virtual void fitContents(S32 max_width, S32 max_height);
  264. virtual LLRect getRequiredRect();
  265. static BOOL rowPreceeds(LLScrollListItem *new_row, LLScrollListItem *test_row);
  266. LLRect getItemListRect() { return mItemListRect; }
  267. /// Returns rect, in local coords, of a given row/column
  268. LLRect getCellRect(S32 row_index, S32 column_index);
  269. // Used "internally" by the scroll bar.
  270. void onScrollChange( S32 new_pos, LLScrollbar* src );
  271. static void onClickColumn(void *userdata);
  272. virtual void updateColumns();
  273. void calcColumnWidths();
  274. S32 getMaxContentWidth() { return mMaxContentWidth; }
  275. void setHeadingHeight(S32 heading_height);
  276. /**
  277. * Sets max visible lines without scroolbar, if this value equals to 0,
  278. * then display all items.
  279. */
  280. void setPageLines(S32 page_lines );
  281. void setCollapseEmptyColumns(BOOL collapse);
  282. LLScrollListItem* hitItem(S32 x,S32 y);
  283. virtual void scrollToShowSelected();
  284. // LLEditMenuHandler functions
  285. virtual void copy();
  286. virtual BOOL canCopy() const;
  287. virtual void cut();
  288. virtual BOOL canCut() const;
  289. virtual void selectAll();
  290. virtual BOOL canSelectAll() const;
  291. virtual void deselect();
  292. virtual BOOL canDeselect() const;
  293. void setNumDynamicColumns(S32 num) { mNumDynamicWidthColumns = num; }
  294. void updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width);
  295. S32 getTotalStaticColumnWidth() { return mTotalStaticColumnWidth; }
  296. std::string getSortColumnName();
  297. BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
  298. BOOL hasSortOrder() const;
  299. S32 selectMultiple( uuid_vec_t ids );
  300. // conceptually const, but mutates mItemList
  301. void updateSort() const;
  302. // sorts a list without affecting the permanent sort order (so further list insertions can be unsorted, for example)
  303. void sortOnce(S32 column, BOOL ascending);
  304. // manually call this whenever editing list items in place to flag need for resorting
  305. void setNeedsSort(bool val = true) { mSorted = !val; }
  306. void dirtyColumns(); // some operation has potentially affected column layout or ordering
  307. boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
  308. {
  309. if (!mSortCallback) mSortCallback = new sort_signal_t();
  310. return mSortCallback->connect(cb);
  311. }
  312. protected:
  313. // "Full" interface: use this when you're creating a list that has one or more of the following:
  314. // * contains icons
  315. // * contains multiple columns
  316. // * allows multiple selection
  317. // * has items that are not guarenteed to have unique names
  318. // * has additional per-item data (e.g. a UUID or void* userdata)
  319. //
  320. // To add items using this approach, create new LLScrollListItems and LLScrollListCells. Add the
  321. // cells (column entries) to each item, and add the item to the LLScrollListCtrl.
  322. //
  323. // The LLScrollListCtrl owns its items and is responsible for deleting them
  324. // (except in the case that the addItem() call fails, in which case it is up
  325. // to the caller to delete the item)
  326. //
  327. // returns FALSE if item faile to be added to list, does NOT delete 'item'
  328. BOOL addItem( LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM, BOOL requires_column = TRUE );
  329. typedef std::deque<LLScrollListItem *> item_list;
  330. item_list& getItemList() { return mItemList; }
  331. void updateLineHeight();
  332. private:
  333. void selectPrevItem(BOOL extend_selection);
  334. void selectNextItem(BOOL extend_selection);
  335. void drawItems();
  336. void updateLineHeightInsert(LLScrollListItem* item);
  337. void reportInvalidInput();
  338. BOOL isRepeatedChars(const LLWString& string) const;
  339. void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE);
  340. void deselectItem(LLScrollListItem* itemp);
  341. void commitIfChanged();
  342. BOOL setSort(S32 column, BOOL ascending);
  343. S32 getLinesPerPage();
  344. static void showNameDetails(std::string id, bool is_group);
  345. static void copyNameToClipboard(std::string id, bool is_group);
  346. static void copySLURLToClipboard(std::string id, bool is_group);
  347. S32 mLineHeight; // the max height of a single line
  348. S32 mScrollLines; // how many lines we've scrolled down
  349. S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight
  350. S32 mHeadingHeight; // the height of the column header buttons, if visible
  351. U32 mMaxSelectable;
  352. LLScrollbar* mScrollbar;
  353. BOOL mAllowMultipleSelection;
  354. BOOL mAllowKeyboardMovement;
  355. BOOL mCommitOnKeyboardMovement;
  356. BOOL mCommitOnSelectionChange;
  357. BOOL mSelectionChanged;
  358. BOOL mNeedsScroll;
  359. BOOL mMouseWheelOpaque;
  360. BOOL mCanSelect;
  361. const BOOL mDisplayColumnHeaders;
  362. BOOL mColumnsDirty;
  363. mutable item_list mItemList;
  364. LLScrollListItem *mLastSelected;
  365. S32 mMaxItemCount;
  366. LLRect mItemListRect;
  367. S32 mMaxContentWidth;
  368. S32 mColumnPadding;
  369. BOOL mBackgroundVisible;
  370. BOOL mDrawStripes;
  371. LLUIColor mBgWriteableColor;
  372. LLUIColor mBgReadOnlyColor;
  373. LLUIColor mBgSelectedColor;
  374. LLUIColor mBgStripeColor;
  375. LLUIColor mFgSelectedColor;
  376. LLUIColor mFgUnselectedColor;
  377. LLUIColor mFgDisabledColor;
  378. LLUIColor mHoveredColor;
  379. LLUIColor mHighlightedColor;
  380. S32 mBorderThickness;
  381. callback_t mOnDoubleClickCallback;
  382. callback_t mOnMaximumSelectCallback;
  383. callback_t mOnSortChangedCallback;
  384. S32 mHighlightedItem;
  385. class LLViewBorder* mBorder;
  386. LLContextMenu *mPopupMenu;
  387. LLView *mCommentTextView;
  388. LLWString mSearchString;
  389. LLFrameTimer mSearchTimer;
  390. S32 mSearchColumn;
  391. S32 mNumDynamicWidthColumns;
  392. S32 mTotalStaticColumnWidth;
  393. S32 mTotalColumnPadding;
  394. mutable bool mSorted;
  395. typedef std::map<std::string, LLScrollListColumn*> column_map_t;
  396. column_map_t mColumns;
  397. BOOL mDirty;
  398. S32 mOriginalSelection;
  399. ContextMenuType mContextMenuType;
  400. typedef std::vector<LLScrollListColumn*> ordered_columns_t;
  401. ordered_columns_t mColumnsIndexed;
  402. typedef std::pair<S32, BOOL> sort_column_t;
  403. std::vector<sort_column_t> mSortColumns;
  404. sort_signal_t* mSortCallback;
  405. }; // end class LLScrollListCtrl
  406. #endif // LL_SCROLLLISTCTRL_H