summaryrefslogtreecommitdiff
path: root/indra/llui/llscrolllistctrl.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llscrolllistctrl.h')
-rw-r--r--indra/llui/llscrolllistctrl.h527
1 files changed, 527 insertions, 0 deletions
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
new file mode 100644
index 0000000000..426e817215
--- /dev/null
+++ b/indra/llui/llscrolllistctrl.h
@@ -0,0 +1,527 @@
+/**
+ * @file llscrolllistctrl.h
+ * @brief LLScrollListCtrl base class
+ *
+ * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#ifndef LL_SCROLLLISTCTRL_H
+#define LL_SCROLLLISTCTRL_H
+
+#include <vector>
+#include <deque>
+
+#include "lluictrl.h"
+#include "llctrlselectioninterface.h"
+#include "llfontgl.h"
+#include "llui.h"
+#include "llstring.h"
+#include "llimagegl.h"
+#include "lleditmenuhandler.h"
+#include "llviewborder.h"
+#include "llframetimer.h"
+#include "llcheckboxctrl.h"
+
+class LLScrollbar;
+class LLScrollListCtrl;
+
+class LLScrollListCell
+{
+public:
+ virtual ~LLScrollListCell() {};
+ virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const = 0; // truncate to given width, if possible
+ virtual S32 getWidth() const = 0;
+ virtual S32 getHeight() const = 0;
+ virtual const LLString& getText() const { return LLString::null; }
+ virtual const LLString& getTextLower() const { return LLString::null; }
+ virtual const BOOL getVisible() const { return TRUE; }
+ virtual void setWidth(S32 width) = 0;
+ virtual void highlightText(S32 num_chars) {}
+
+ virtual BOOL handleClick() { return FALSE; }
+ virtual void setEnabled(BOOL enable) { }
+};
+
+class LLScrollListText : public LLScrollListCell
+{
+ static U32 sCount;
+public:
+ LLScrollListText( const LLString& text, const LLFontGL* font, S32 width = 0, U8 font_style = LLFontGL::NORMAL, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
+ /*virtual*/ ~LLScrollListText();
+
+ virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const;
+ virtual S32 getWidth() const { return mWidth; }
+ virtual void setWidth(S32 width) { mWidth = width; }
+ virtual S32 getHeight() const { return llround(mFont->getLineHeight()); }
+ virtual const LLString& getText() const { return mText.getString(); }
+ virtual const BOOL getVisible() const { return mVisible; }
+ virtual void highlightText(S32 num_chars) {mHighlightChars = num_chars;}
+ void setText(const LLString& text);
+
+private:
+ LLUIString mText;
+ const LLFontGL* mFont;
+ LLColor4* mColor;
+ const U8 mFontStyle;
+ S32 mWidth;
+ S32 mEllipsisWidth; // in pixels, of "..."
+ BOOL mVisible;
+ S32 mHighlightChars;
+
+ LLPointer<LLImageGL> mRoundedRectImage;
+};
+
+class LLScrollListIcon : public LLScrollListCell
+{
+public:
+ LLScrollListIcon( LLImageGL* icon, S32 width = 0, LLUUID image_id = LLUUID::null);
+ /*virtual*/ ~LLScrollListIcon();
+ virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const { gl_draw_image(0, 0, mIcon); }
+ virtual S32 getWidth() const { return mWidth; }
+ virtual S32 getHeight() const { return mIcon->getHeight(); }
+ virtual const LLString& getText() const { return mImageUUID; }
+ virtual const LLString& getTextLower() const { return mImageUUID; }
+ virtual void setWidth(S32 width) { mWidth = width; }
+
+private:
+ LLPointer<LLImageGL> mIcon;
+ LLString mImageUUID;
+ S32 mWidth;
+};
+
+class LLScrollListCheck : public LLScrollListCell
+{
+public:
+ LLScrollListCheck( LLCheckBoxCtrl* check_box, S32 width = 0);
+ /*virtual*/ ~LLScrollListCheck();
+ virtual void drawToWidth(S32 width, const LLColor4& color, const LLColor4& highlight_color) const;
+ virtual S32 getWidth() const { return mWidth; }
+ virtual S32 getHeight() const { return 0; }
+ virtual void setWidth(S32 width) { mWidth = width; }
+
+ virtual BOOL handleClick();
+ virtual void setEnabled(BOOL enable) { if (mCheckBox) mCheckBox->setEnabled(enable); }
+
+ LLCheckBoxCtrl* getCheckBox() { return mCheckBox; }
+
+private:
+ LLCheckBoxCtrl* mCheckBox;
+ S32 mWidth;
+};
+
+class LLScrollListColumn
+{
+public:
+ // Default constructor
+ LLScrollListColumn() : mName(""), mSortingColumn(""), mLabel(""), mWidth(-1), mRelWidth(-1.0), mDynamicWidth(FALSE), mIndex(-1), mParentCtrl(NULL), mButton(NULL) { }
+
+ LLScrollListColumn(LLString name, LLString label, S32 width, F32 relwidth)
+ : mName(name), mSortingColumn(name), mLabel(label), mWidth(width), mRelWidth(relwidth), mDynamicWidth(FALSE), mIndex(-1), mParentCtrl(NULL), mButton(NULL) { }
+
+ LLScrollListColumn(const LLSD &sd)
+ {
+ mName = sd.get("name").asString();
+ mSortingColumn = mName;
+ if (sd.has("sort"))
+ {
+ mSortingColumn = sd.get("sort").asString();
+ }
+ mLabel = sd.get("label").asString();
+ if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0)
+ {
+ mRelWidth = (F32)sd.get("relwidth").asReal();
+ if (mRelWidth < 0) mRelWidth = 0;
+ if (mRelWidth > 1) mRelWidth = 1;
+ mDynamicWidth = FALSE;
+ mWidth = 0;
+ }
+ else if(sd.has("dynamicwidth") && (BOOL)sd.get("dynamicwidth").asBoolean() == TRUE)
+ {
+ mDynamicWidth = TRUE;
+ mRelWidth = -1;
+ mWidth = 0;
+ }
+ else
+ {
+ mWidth = sd.get("width").asInteger();
+ mDynamicWidth = FALSE;
+ mRelWidth = -1;
+ }
+ mIndex = -1;
+ mParentCtrl = NULL;
+ mButton = NULL;
+ }
+
+ LLString mName;
+ LLString mSortingColumn;
+ LLString mLabel;
+ S32 mWidth;
+ F32 mRelWidth;
+ BOOL mDynamicWidth;
+ S32 mIndex;
+ LLScrollListCtrl *mParentCtrl;
+ LLButton *mButton;
+};
+
+class LLScrollListItem
+{
+public:
+ LLScrollListItem( BOOL enabled = TRUE, void* userdata = NULL, const LLUUID& uuid = LLUUID::null )
+ : mSelected(FALSE), mEnabled( enabled ), mUserdata( userdata ), mItemValue( uuid ), mColumns() {}
+ LLScrollListItem( LLSD item_value, void* userdata = NULL )
+ : mSelected(FALSE), mEnabled( TRUE ), mUserdata( userdata ), mItemValue( item_value ), mColumns() {}
+
+ virtual ~LLScrollListItem();
+
+ void setSelected( BOOL b ) { mSelected = b; }
+ BOOL getSelected() const { return mSelected; }
+
+ void setEnabled( BOOL b );
+ BOOL getEnabled() const { return mEnabled; }
+
+ void setUserdata( void* userdata ) { mUserdata = userdata; }
+ void* getUserdata() const { return mUserdata; }
+
+ LLUUID getUUID() const { return mItemValue.asUUID(); }
+ LLSD getValue() const { return mItemValue; }
+
+ // If width = 0, just use the width of the text. Otherwise override with
+ // specified width in pixels.
+ void addColumn( const LLString& text, const LLFontGL* font, S32 width = 0 , U8 font_style = LLFontGL::NORMAL, BOOL visible = TRUE)
+ { mColumns.push_back( new LLScrollListText(text, font, width, font_style, LLColor4::black, FALSE, visible) ); }
+
+ void addColumn( LLImageGL* icon, S32 width = 0 )
+ { mColumns.push_back( new LLScrollListIcon(icon, width) ); }
+
+ void addColumn( LLCheckBoxCtrl* check, S32 width = 0 )
+ { mColumns.push_back( new LLScrollListCheck(check,width) ); }
+
+ void setNumColumns(S32 columns);
+
+ void setColumn( S32 column, LLScrollListCell *cell );
+
+ S32 getNumColumns() const { return mColumns.size(); }
+
+ LLScrollListCell *getColumn(const S32 i) const { if (i < (S32)mColumns.size()) { return mColumns[i]; } return NULL; }
+
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+ LLString getContentsCSV();
+
+private:
+ BOOL mSelected;
+ BOOL mEnabled;
+ void* mUserdata;
+ LLSD mItemValue;
+ std::vector<LLScrollListCell *> mColumns;
+};
+
+
+class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
+ public LLCtrlListInterface, public LLCtrlScrollInterface
+{
+public:
+ LLScrollListCtrl(
+ const LLString& name,
+ const LLRect& rect,
+ void (*commit_callback)(LLUICtrl*, void*),
+ void* callback_userdata,
+ BOOL allow_multiple_selection,
+ BOOL draw_border = TRUE);
+
+ virtual ~LLScrollListCtrl();
+ virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_SCROLL_LIST; }
+ virtual LLString getWidgetTag() const { return LL_SCROLL_LIST_CTRL_TAG; }
+ virtual LLXMLNodePtr getXML(bool save_children = true) const;
+ void setScrollListParameters(LLXMLNodePtr node);
+ static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+
+ S32 isEmpty() const;
+
+ void deleteAllItems() { clearRows(); }
+
+ // Sets an array of column descriptors
+ void setColumnHeadings(LLSD headings);
+ // Numerical based sort by column function (used by LLComboBox)
+ void sortByColumn(U32 column, BOOL ascending);
+
+ // LLCtrlListInterface functions
+ virtual S32 getItemCount() const;
+ // Adds a single column descriptor: ["name" : string, "label" : string, "width" : integer, "relwidth" : integer ]
+ virtual void addColumn(const LLSD& column, EAddPosition pos = ADD_BOTTOM);
+ virtual void clearColumns();
+ virtual void setColumnLabel(const LLString& column, const LLString& label);
+ // Adds a single element, from an array of:
+ // "columns" => [ "column" => column name, "value" => value, "type" => type, "font" => font, "font-style" => style ], "id" => uuid
+ // Creates missing columns automatically.
+ virtual LLScrollListItem* addElement(const LLSD& value, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
+ // Simple add element. Takes a single array of:
+ // [ "value" => value, "font" => font, "font-style" => style ]
+ virtual LLScrollListItem* addSimpleElement(const LLString& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD());
+ virtual void clearRows(); // clears all elements
+ virtual void sortByColumn(LLString name, BOOL ascending);
+
+ // These functions take and return an array of arrays of elements, as above
+ virtual void setValue(const LLSD& value );
+ virtual LLSD getValue() const;
+
+ LLCtrlSelectionInterface* getSelectionInterface() { return (LLCtrlSelectionInterface*)this; }
+ LLCtrlListInterface* getListInterface() { return (LLCtrlListInterface*)this; }
+ LLCtrlScrollInterface* getScrollInterface() { return (LLCtrlScrollInterface*)this; }
+
+ // DEPRECATED: Use setSelectedByValue() below.
+ BOOL setCurrentByID( const LLUUID& id ) { return selectByID(id); }
+ virtual LLUUID getCurrentID() { return getStringUUIDSelectedItem(); }
+
+ BOOL operateOnSelection(EOperation op);
+ BOOL operateOnAll(EOperation op);
+
+ // returns FALSE if unable to set the max count so low
+ BOOL setMaxItemCount(S32 max_count);
+
+ BOOL selectByID( const LLUUID& id ); // FALSE if item not found
+
+ // Match item by value.asString(), which should work for string, integer, uuid.
+ // Returns FALSE if not found.
+ BOOL setSelectedByValue(LLSD value, BOOL selected);
+
+ virtual BOOL isSelected(LLSD value);
+
+ BOOL selectFirstItem();
+ BOOL selectNthItem( S32 index );
+
+ void deleteSingleItem( S32 index ) ;
+ void deleteSelectedItems();
+ void deselectAllItems(BOOL no_commit_on_change = FALSE); // by default, go ahead and commit on selection change
+
+ void highlightNthItem( S32 index );
+ void setDoubleClickCallback( void (*cb)(void*) ) { mOnDoubleClickCallback = cb; }
+ void setMaxiumumSelectCallback( void (*cb)(void*) ) { mOnMaximumSelectCallback = cb; }
+
+ void swapWithNext(S32 index);
+ void swapWithPrevious(S32 index);
+
+ void setCanSelect(BOOL can_select) { mCanSelect = can_select; }
+ virtual BOOL getCanSelect() const { return mCanSelect; }
+
+ S32 getItemIndex( LLScrollListItem* item );
+ S32 getItemIndex( LLUUID& item_id );
+
+ // "Simple" interface: use this when you're creating a list that contains only unique strings, only
+ // one of which can be selected at a time.
+ LLScrollListItem* addSimpleItem( const LLString& item_text, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE );
+ // Add an item with an associated LLSD
+ LLScrollListItem* addSimpleItem(const LLString& item_text, LLSD sd, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0 );
+
+ BOOL selectSimpleItem( const LLString& item, BOOL case_sensitive = TRUE ); // FALSE if item not found
+ BOOL selectSimpleItemByPrefix(const LLString& target, BOOL case_sensitive);
+ BOOL selectSimpleItemByPrefix(const LLWString& target, BOOL case_sensitive);
+ const LLString& getSimpleSelectedItem(S32 column = 0) const;
+ LLSD getSimpleSelectedValue();
+
+ // DEPRECATED: Use LLSD versions of addSimpleItem() and getSimpleSelectedValue().
+ // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which
+ // has an associated, unique UUID, and only one of which can be selected at a time.
+ LLScrollListItem* addStringUUIDItem(const LLString& item_text, const LLUUID& id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, S32 column_width = 0);
+ LLUUID getStringUUIDSelectedItem();
+
+ // "Full" interface: use this when you're creating a list that has one or more of the following:
+ // * contains icons
+ // * contains multiple columns
+ // * allows multiple selection
+ // * has items that are not guarenteed to have unique names
+ // * has additional per-item data (e.g. a UUID or void* userdata)
+ //
+ // To add items using this approach, create new LLScrollListItems and LLScrollListCells. Add the
+ // cells (column entries) to each item, and add the item to the LLScrollListCtrl.
+ //
+ // The LLScrollListCtrl owns its items and is responsible for deleting them
+ // (except in the case that the addItem() call fails, in which case it is up
+ // to the caller to delete the item)
+
+ // returns FALSE if item faile to be added to list, does NOT delete 'item'
+ // TomY TODO - Deprecate this API and remove it
+ BOOL addItem( LLScrollListItem* item, EAddPosition pos = ADD_BOTTOM );
+ LLScrollListItem* getFirstSelected() const;
+ virtual S32 getFirstSelectedIndex();
+ std::vector<LLScrollListItem*> getAllSelected() const;
+
+ LLScrollListItem* getLastSelectedItem() const { return mLastSelected; }
+
+ // iterate over all items
+ LLScrollListItem* getFirstData() const;
+ std::vector<LLScrollListItem*> getAllData() const;
+
+ void setAllowMultipleSelection(BOOL mult ) { mAllowMultipleSelection = mult; }
+
+ void setBgWriteableColor(const LLColor4 &c) { mBgWriteableColor = c; }
+ void setReadOnlyBgColor(const LLColor4 &c) { mBgReadOnlyColor = c; }
+ void setBgSelectedColor(const LLColor4 &c) { mBgSelectedColor = c; }
+ void setBgStripeColor(const LLColor4& c) { mBgStripeColor = c; }
+ void setFgSelectedColor(const LLColor4 &c) { mFgSelectedColor = c; }
+ void setFgUnselectedColor(const LLColor4 &c){ mFgUnselectedColor = c; }
+ void setHighlightedColor(const LLColor4 &c) { mHighlightedColor = c; }
+ void setFgDisableColor(const LLColor4 &c) { mFgDisabledColor = c; }
+
+ void setBackgroundVisible(BOOL b) { mBackgroundVisible = b; }
+ void setDrawStripes(BOOL b) { mDrawStripes = b; }
+ void setColumnPadding(const S32 c) { mColumnPadding = c; }
+ void setCommitOnKeyboardMovement(BOOL b) { mCommitOnKeyboardMovement = b; }
+ void setCommitOnSelectionChange(BOOL b) { mCommitOnSelectionChange = b; }
+ void setAllowKeyboardMovement(BOOL b) { mAllowKeyboardMovement = b; }
+
+ void setMaxSelectable(U32 max_selected) { mMaxSelectable = max_selected; }
+ S32 getMaxSelectable() { return mMaxSelectable; }
+
+
+ virtual S32 getScrollPos();
+ virtual void setScrollPos( S32 pos );
+
+ S32 getSearchColumn() { return mSearchColumn; }
+ void setSearchColumn(S32 column) { mSearchColumn = column; }
+
+ void clearSearchString() { mSearchString.clear(); }
+
+ // Overridden from LLView
+ virtual void draw();
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+ virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent);
+ virtual BOOL handleUnicodeCharHere(llwchar uni_char, BOOL called_from_parent);
+ virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ virtual void setEnabled(BOOL enabled);
+ virtual void setFocus( BOOL b );
+ virtual void onFocusLost();
+
+ virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+ virtual void arrange(S32 max_width, S32 max_height);
+ virtual LLRect getRequiredRect();
+ static BOOL rowPreceeds(LLScrollListItem *new_row, LLScrollListItem *test_row);
+
+ // Used "internally" by the scroll bar.
+ static void onScrollChange( S32 new_pos, LLScrollbar* src, void* userdata );
+
+ static void onClickColumn(void *userdata);
+
+ void updateColumns();
+ void updateColumnButtons();
+
+ void setDisplayHeading(BOOL display);
+ void setHeadingHeight(S32 heading_height);
+ void setHeadingFont(const LLFontGL* heading_font);
+ void setCollapseEmptyColumns(BOOL collapse);
+ void setIsPopup(BOOL is_popup) { mIsPopup = is_popup; }
+
+ LLScrollListItem* hitItem(S32 x,S32 y);
+ virtual void scrollToShowSelected();
+
+ // LLEditMenuHandler functions
+ virtual void copy();
+ virtual BOOL canCopy();
+
+ virtual void cut();
+ virtual BOOL canCut();
+
+ virtual void doDelete();
+ virtual BOOL canDoDelete();
+
+ virtual void selectAll();
+ virtual BOOL canSelectAll();
+
+ virtual void deselect();
+ virtual BOOL canDeselect();
+
+ void setNumDynamicColumns(int num) { mNumDynamicWidthColumns = num; }
+ void setTotalStaticColumnWidth(int width) { mTotalStaticColumnWidth = width; }
+
+protected:
+ void selectPrevItem(BOOL extend_selection);
+ void selectNextItem(BOOL extend_selection);
+ void drawItems();
+ void updateLineHeight();
+ void reportInvalidInput();
+ BOOL isRepeatedChars(const LLWString& string) const;
+ void selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE);
+ void deselectItem(LLScrollListItem* itemp);
+ void commitIfChanged();
+
+protected:
+ S32 mCurIndex; // For get[First/Next]Data
+ S32 mCurSelectedIndex; // For get[First/Next]Selected
+
+ S32 mLineHeight; // the max height of a single line
+ S32 mScrollLines; // how many lines we've scrolled down
+ S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight
+ S32 mHeadingHeight; // the height of the column header buttons, if visible
+ U32 mMaxSelectable;
+ const LLFontGL* mHeadingFont; // the font to use for column head buttons, if visible
+ LLScrollbar* mScrollbar;
+ BOOL mAllowMultipleSelection;
+ BOOL mAllowKeyboardMovement;
+ BOOL mCommitOnKeyboardMovement;
+ BOOL mCommitOnSelectionChange;
+ BOOL mSelectionChanged;
+ BOOL mCanSelect;
+ BOOL mDisplayColumnButtons;
+ BOOL mCollapseEmptyColumns;
+ BOOL mIsPopup;
+
+ typedef std::deque<LLScrollListItem *> item_list;
+ item_list mItemList;
+
+ LLScrollListItem *mLastSelected;
+
+ S32 mMaxItemCount;
+
+ LLRect mItemListRect;
+
+ S32 mColumnPadding;
+
+ BOOL mBackgroundVisible;
+ BOOL mDrawStripes;
+
+ LLColor4 mBgWriteableColor;
+ LLColor4 mBgReadOnlyColor;
+ LLColor4 mBgSelectedColor;
+ LLColor4 mBgStripeColor;
+ LLColor4 mFgSelectedColor;
+ LLColor4 mFgUnselectedColor;
+ LLColor4 mFgDisabledColor;
+ LLColor4 mHighlightedColor;
+
+ S32 mBorderThickness;
+ void (*mOnDoubleClickCallback)(void* userdata);
+ void (*mOnMaximumSelectCallback)(void* userdata );
+
+ S32 mHighlightedItem;
+ LLViewBorder* mBorder;
+
+ LLWString mSearchString;
+ LLFrameTimer mSearchTimer;
+
+ LLString mDefaultColumn;
+
+ S32 mSearchColumn;
+ S32 mNumDynamicWidthColumns;
+ S32 mTotalStaticColumnWidth;
+
+ static U32 sSortColumn;
+ static BOOL sSortAscending;
+
+ std::map<LLString, LLScrollListColumn> mColumns;
+ std::vector<LLScrollListColumn*> mColumnsIndexed;
+
+public:
+ // HACK: Did we draw one selected item this frame?
+ BOOL mDrewSelected;
+};
+
+const BOOL MULTIPLE_SELECT_YES = TRUE;
+const BOOL MULTIPLE_SELECT_NO = FALSE;
+
+const BOOL SHOW_BORDER_YES = TRUE;
+const BOOL SHOW_BORDER_NO = FALSE;
+
+#endif // LL_SCROLLLISTCTRL_H