//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef SECTIONEDLISTPANEL_H #define SECTIONEDLISTPANEL_H #ifdef _WIN32 #pragma once #endif #include #include #include #include #include #include namespace vgui { class SectionedListPanel; class SectionedListPanelHeader; class CItemButton; // sorting function, should return true if itemID1 should be displayed before itemID2 typedef bool (*SectionSortFunc_t)(SectionedListPanel *list, int itemID1, int itemID2); //----------------------------------------------------------------------------- // Purpose: List panel control that is divided up into discrete sections //----------------------------------------------------------------------------- class SectionedListPanel : public Panel { DECLARE_CLASS_SIMPLE( SectionedListPanel, Panel ); public: SectionedListPanel(vgui::Panel *parent, const char *name); ~SectionedListPanel(); // adds a new section; returns false if section already exists virtual void AddSection(int sectionID, const char *name, SectionSortFunc_t sortFunc = NULL); virtual void AddSection(int sectionID, const wchar_t *name, SectionSortFunc_t sortFunc = NULL); virtual void AddSection(int sectionID, SectionedListPanelHeader *pHeader, SectionSortFunc_t sortFunc = NULL); // clears all the sections - leaves the items in place virtual void RemoveAllSections(); // modifies section info virtual void SetSectionFgColor(int sectionID, Color color); virtual void SetSectionDividerColor( int sectionID, Color color); // forces a section to always be visible virtual void SetSectionAlwaysVisible(int sectionID, bool visible = true); virtual void SetSectionMinimumHeight(int sectionID, int iMinimumHeight); // adds a new column to a section enum ColumnFlags_e { HEADER_IMAGE = 0x01, // set if the header for the column is an image instead of text COLUMN_IMAGE = 0x02, // set if the column contains an image instead of text (images are looked up by index from the ImageList) (see SetImageList below) COLUMN_BRIGHT = 0x04, // set if the column text should be the bright color COLUMN_CENTER = 0x08, // set to center the text/image in the column COLUMN_RIGHT = 0x10, // set to right-align the text in the column }; virtual bool AddColumnToSection(int sectionID, const char *columnName, const char *columnText, int columnFlags, int width, HFont fallbackFont = INVALID_FONT ); virtual bool AddColumnToSection(int sectionID, const char *columnName, const wchar_t *columnText, int columnFlags, int width, HFont fallbackFont = INVALID_FONT ); // modifies the text in an existing column virtual bool ModifyColumn(int sectionID, const char *columnName, const wchar_t *columnText); // adds an item to the list; returns the itemID of the new item virtual int AddItem(int sectionID, const KeyValues *data); // modifies an existing item; returns false if the item does not exist virtual bool ModifyItem(int itemID, int sectionID, const KeyValues *data); // removes an item from the list; returns false if the item does not exist or is already removed virtual bool RemoveItem(int itemID); // clears the list virtual void RemoveAll() { DeleteAllItems(); } // DeleteAllItems() is deprecated, use RemoveAll(); virtual void DeleteAllItems(); // set the text color of an item virtual void SetItemFgColor(int itemID, Color color); //============================================================================= // HPE_BEGIN: // [menglish] Getters and setters for several item and section objects //============================================================================= virtual void SetItemBgColor( int itemID, Color color ); virtual int GetColumnIndexByName(int sectionID, char* name); virtual int GetLineSpacing() { return m_iLineSpacing; } //============================================================================= // HPE_END //============================================================================= virtual void SetItemFont( int itemID, HFont font ); virtual void SetItemEnabled( int itemID, bool bEnabled ); /* MESSAGES SENT: "RowSelected" "itemID" - the selected item id, -1 if nothing selected // when an item has been clicked on "RowContextMenu" "itemID" "RowLeftClick" "itemID" "RowDoubleLeftClick" "itemID" */ // returns the number of columns in a section virtual int GetColumnCountBySection(int sectionID); // returns the name of a column by section and column index; returns NULL if there are no more columns // valid range of columnIndex is [0, GetColumnCountBySection) virtual const char *GetColumnNameBySection(int sectionID, int columnIndex); virtual const wchar_t *GetColumnTextBySection(int sectionID, int columnIndex); virtual int GetColumnFlagsBySection(int sectionID, int columnIndex); virtual int GetColumnWidthBySection(int sectionID, int columnIndex); virtual HFont GetColumnFallbackFontBySection( int sectionID, int columnIndex ); // returns the id of the currently selected item, -1 if nothing is selected virtual int GetSelectedItem(); // sets which item is currently selected virtual void SetSelectedItem(int itemID); // remove selection virtual void ClearSelection( void ); // returns the data of a selected item // InvalidateItem(itemID) needs to be called if the KeyValues are modified virtual KeyValues *GetItemData(int itemID); // returns what section an item is in virtual int GetItemSection(int itemID); // forces an item to redraw (use when keyvalues have been modified) virtual void InvalidateItem(int itemID); // returns true if the itemID is valid for use virtual bool IsItemIDValid(int itemID); virtual int GetHighestItemID(); // returns the number of items (ignoring section dividers) virtual int GetItemCount(); // returns the item ID from the row, again ignoring section dividers - valid from [0, GetItemCount ) virtual int GetItemIDFromRow(int row); // returns the row that this itemID occupies. -1 if the itemID is invalid virtual int GetRowFromItemID(int itemID); // gets the local coordinates of a cell virtual bool GetCellBounds(int itemID, int column, int &x, int &y, int &wide, int &tall); // Gets the coordinates of a section header virtual bool GetSectionHeaderBounds(int sectionID, int &x, int &y, int &wide, int &tall); //============================================================================= // HPE_BEGIN: // [menglish] Get the bounds of an item or column. //============================================================================= // gets the local coordinates of a cell using the max width for every column virtual bool GetMaxCellBounds(int itemID, int column, int &x, int &y, int &wide, int &tall); // gets the local coordinates of an item virtual bool GetItemBounds(int itemID, int &x, int &y, int &wide, int &tall); // [tj] Accessors for clickability void SetClickable(bool clickable) { m_clickable = clickable; } bool IsClickable() { return m_clickable; } // [tj] Accessors for header drawing void SetDrawHeaders(bool drawHeaders) { m_bDrawSectionHeaders = drawHeaders; } bool GetDrawHeaders() { return m_bDrawSectionHeaders; } //============================================================================= // HPE_END //============================================================================= // set up a field for editing virtual void EnterEditMode(int itemID, int column, vgui::Panel *editPanel); // leaves editing mode virtual void LeaveEditMode(); // returns true if we are currently in inline editing mode virtual bool IsInEditMode(); // sets whether or not the vertical scrollbar should ever be displayed virtual void SetVerticalScrollbar(bool state); // returns the size required to fully draw the contents of the panel virtual void GetContentSize(int &wide, int &tall); // image handling virtual void SetImageList(ImageList *imageList, bool deleteImageListWhenDone); virtual void ScrollToItem(int iItem); virtual void SetProportional(bool state); HFont GetHeaderFont( void ) const; void SetHeaderFont( HFont hFont ); HFont GetRowFont( void ) const; void SetRowFont( HFont hFont ); void MoveSelectionDown( void ); void MoveSelectionUp( void ); ScrollBar *GetScrollBar( void ) { return m_pScrollBar; } void SetColumnWidthBySection(int sectionID, const char *columnName, int iWidth); protected: virtual void PerformLayout(); virtual void ApplySchemeSettings(IScheme *pScheme); virtual void ApplySettings(KeyValues *inResourceData); virtual void OnSizeChanged(int wide, int tall); virtual void OnMouseWheeled(int delta); virtual void OnMousePressed( MouseCode code); virtual void NavigateTo( void ); virtual void OnKeyCodePressed( KeyCode code ); virtual void OnSetFocus(); // called after the panel receives the keyboard focus public: virtual void SetFontSection(int sectionID, HFont font); virtual void SetItemBgHorizFillInset( int itemID, int nInset ); void SetColorOverrideForCell( int sectionID, int itemID, int columnID, Color clrOverride ); Color *GetColorOverrideForCell( int sectionID, int itemID, int columnID ); void ClearAllColorOverrideForCell(){ m_ColorOverrides.Purge(); } enum { BUTTON_HEIGHT_DEFAULT = 20, BUTTON_HEIGHT_SPACER = 7, DEFAULT_LINE_SPACING = 20, DEFAULT_SECTION_GAP = 8, COLUMN_DATA_INDENT = 6, COLUMN_DATA_GAP = 2, }; virtual void SetSectionDrawDividerBar( int sectionID, bool bDraw ); private: MESSAGE_FUNC( OnSliderMoved, "ScrollBarSliderMoved" ); int GetSectionTall(); void LayoutPanels(int &contentTall); // Returns the index of a new item button, reusing an existing item button if possible int GetNewItemButton(); friend class CItemButton; void SetSelectedItem(CItemButton *item); DHANDLE m_hSelectedItem; struct color_override_t { int m_SectionID; int m_ItemID; int m_ColumnID; Color m_clrOverride; }; struct column_t { char m_szColumnName[32]; wchar_t m_szColumnText[64]; int m_iColumnFlags; int m_iWidth; HFont m_hFallbackFont; }; struct section_t { int m_iID; bool m_bAlwaysVisible; SectionedListPanelHeader *m_pHeader; CUtlVector m_Columns; SectionSortFunc_t m_pSortFunc; int m_iMinimumHeight; }; CUtlVector m_Sections; CUtlLinkedList m_Items; CUtlLinkedList m_FreeItems; CUtlVector m_SortedItems; CUtlVector m_ColorOverrides; PHandle m_hEditModePanel; int m_iEditModeItemID; int m_iEditModeColumn; int m_iContentHeight; int m_iLineSpacing; // row height int m_iLineGap; // gap between rows int m_iSectionGap; int FindSectionIndexByID(int sectionID); void ReSortList(); ScrollBar *m_pScrollBar; ImageList *m_pImageList; bool m_bDeleteImageListWhenDone; bool m_bSortNeeded; bool m_bVerticalScrollbarEnabled; HFont m_hHeaderFont; HFont m_hRowFont; //============================================================================= // HPE_BEGIN: //============================================================================= // [tj] Whether or not this list should respond to the mouse bool m_clickable; // [tj] Whether or not this list should draw the headers for the sections bool m_bDrawSectionHeaders; //============================================================================= // HPE_END //============================================================================= CPanelAnimationVar( bool, m_bShowColumns, "show_columns", "false" ); }; class SectionedListPanelHeader : public Label { DECLARE_CLASS_SIMPLE( SectionedListPanelHeader, Label ); public: SectionedListPanelHeader(SectionedListPanel *parent, const char *name, int sectionID); SectionedListPanelHeader(SectionedListPanel *parent, const wchar_t *name, int sectionID); virtual void ApplySchemeSettings(IScheme *pScheme) OVERRIDE; virtual void Paint() OVERRIDE; virtual void PerformLayout() OVERRIDE; void SetColor(Color col); void SetDividerColor(Color col ); void DrawDividerBar(bool bDraw){ m_bDrawDividerBar = bDraw; } protected: int m_iSectionID; Color m_SectionDividerColor; SectionedListPanel *m_pListPanel; bool m_bDrawDividerBar; }; } // namespace vgui #endif // SECTIONEDLISTPANEL_H