aboutsummaryrefslogtreecommitdiff
path: root/mp/src/public/vgui_controls/ListPanel.h
blob: 9248856e6430d62b1965ef34c2c8032f4df6a80f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================//

#ifndef LISTPANEL_H
#define LISTPANEL_H

#ifdef _WIN32
#pragma once
#endif

#include <utllinkedlist.h>
#include <utlvector.h>
#include <utlrbtree.h>
#include <vgui/VGUI.h>
#include <vgui_controls/Panel.h>

class KeyValues;

namespace vgui
{

class ScrollBar;
class TextImage;
class ImagePanel;
class Label;
class Button;
class IDraggerEvent;
class FastSortListPanelItem;

//-----------------------------------------------------------------------------
// Purpose: Generic class for ListPanel items
//-----------------------------------------------------------------------------
class ListPanelItem
{
public:
	ListPanelItem() :
		kv( 0 ),
		userData( 0 ),
		m_pDragData( 0 ),
		m_bImage( false ),
		m_nImageIndex( -1 ),
		m_nImageIndexSelected( -1 ),
		m_pIcon( 0 )
	{
	}

	KeyValues		*kv;
	unsigned int 	userData;
	KeyValues		*m_pDragData;
	bool			m_bImage;
	int				m_nImageIndex;
	int				m_nImageIndexSelected;
	IImage			*m_pIcon;
};

typedef int __cdecl SortFunc( 
	ListPanel *pPanel, 
	const ListPanelItem &item1,
	const ListPanelItem &item2 );

//-----------------------------------------------------------------------------
// Purpose: A spread-sheet type data view, similar to MFC's 
//-----------------------------------------------------------------------------
class ListPanel : public Panel
{
	DECLARE_CLASS_SIMPLE( ListPanel, Panel );

public:
	ListPanel(Panel *parent, const char *panelName);
	~ListPanel();

	// COLUMN HANDLING
	// all indices are 0 based, limit of 255 columns
	// columns are resizable by default
	enum ColumnFlags_e
	{
		COLUMN_FIXEDSIZE		= 0x01, // set to have the column be a fixed size
		COLUMN_RESIZEWITHWINDOW	= 0x02, // set to have the column grow with the parent dialog growing
		COLUMN_IMAGE			= 0x04,	// set if the column data is not text, but instead the index of the image to display
		COLUMN_HIDDEN			= 0x08,	// column is hidden by default
		COLUMN_UNHIDABLE		= 0x10,	// column is unhidable
	};

	// adds a column header
	virtual void AddColumnHeader(int index, const char *columnName, const char *columnText, int startingWidth, int minWidth, int maxWidth, int columnFlags = 0); 
	virtual void AddColumnHeader(int index, const char *columnName, const char *columnText, int width, int columnFlags = 0);

	virtual void RemoveColumn(int column);	// removes a column
	virtual int  FindColumn(const char *columnName);
	virtual void SetColumnHeaderHeight( int height );
	virtual void SetColumnHeaderText(int column, const char *text);
	virtual void SetColumnHeaderText(int column, wchar_t *text);
	virtual void SetColumnHeaderImage(int column, int imageListIndex);
	virtual void SetColumnHeaderTooltip(int column, const char *tooltipText);
	virtual void SetColumnTextAlignment( int column, int align );

	// Get information about the column headers.
	virtual int GetNumColumnHeaders() const;
	virtual bool GetColumnHeaderText( int index, char *pOut, int maxLen );

	virtual void SetSortFunc(int column, SortFunc *func);
	virtual void SetSortColumn(int column);
	virtual void SortList( void );
	virtual void SetColumnSortable(int column, bool sortable);
	virtual void SetColumnVisible(int column, bool visible);
	int GetSortColumn() const;

	// sets whether the user can add/remove columns (defaults to off)
	virtual void SetAllowUserModificationOfColumns(bool allowed);
	
	// DATA HANDLING
	// data->GetName() is used to uniquely identify an item
	// data sub items are matched against column header name to be used in the table
	virtual int AddItem(const KeyValues *data, unsigned int userData, bool bScrollToItem, bool bSortOnAdd); // Takes a copy of the data for use in the table. Returns the index the item is at.
	void SetItemDragData( int itemID, const KeyValues *data ); // Makes a copy of the keyvalues to store in the table. Used when dragging from the table. Only used if the caller enables drag support
	virtual int	GetItemCount( void );			// returns the number of VISIBLE items
	virtual int GetItem(const char *itemName);	// gets the row index of an item by name (data->GetName())
	virtual KeyValues *GetItem(int itemID); // returns pointer to data the row holds
	virtual int GetItemCurrentRow(int itemID);		// returns -1 if invalid index or item not visible
	virtual int GetItemIDFromRow(int currentRow);			// returns -1 if invalid row
	virtual unsigned int GetItemUserData(int itemID);
	virtual ListPanelItem *GetItemData(int itemID);
	virtual void SetUserData( int itemID, unsigned int userData );
	virtual int GetItemIDFromUserData( unsigned int userData );
	virtual void ApplyItemChanges(int itemID); // applies any changes to the data, performed by modifying the return of GetItem() above
	virtual void RemoveItem(int itemID); // removes an item from the table (changing the indices of all following items)
	virtual void RereadAllItems(); // updates the view with the new data

	virtual void RemoveAll();		// clears and deletes all the memory used by the data items
	virtual void DeleteAllItems();	// obselete, use RemoveAll();

	virtual void GetCellText(int itemID, int column, OUT_Z_BYTECAP(bufferSizeInBytes) wchar_t *buffer, int bufferSizeInBytes); // returns the data held by a specific cell
	virtual IImage *GetCellImage(int itemID, int column); //, ImagePanel *&buffer); // returns the image held by a specific cell

	// Use these until they return InvalidItemID to iterate all the items.
	virtual int FirstItem() const;
	virtual int NextItem( int iItem ) const;

	virtual int InvalidItemID() const;
	virtual bool IsValidItemID(int itemID);

	// sets whether the dataitem is visible or not
	// it is removed from the row list when it becomes invisible, but stays in the indexes
	// this is much faster than a normal remove
	virtual void SetItemVisible(int itemID, bool state);
	virtual void SetItemDisabled(int itemID, bool state );
	bool IsItemVisible( int itemID );

	virtual void SetFont(HFont font);

	// image handling
	virtual void SetImageList(ImageList *imageList, bool deleteImageListWhenDone);

	// SELECTION
	
	// returns the count of selected items
	virtual int GetSelectedItemsCount();

	// returns the selected item by selection index, valid in range [0, GetNumSelectedRows)
	virtual int GetSelectedItem(int selectionIndex);

	// sets no item as selected
	virtual void ClearSelectedItems();

	virtual bool IsItemSelected( int itemID );

	// adds a item to the select list
	virtual void AddSelectedItem( int itemID );

	// sets this single item as the only selected item
	virtual void SetSingleSelectedItem( int itemID );

	// returns the selected column, -1 for particular column selected
	virtual int GetSelectedColumn();

	// whether or not to select specific cells (off by default)
	virtual void SetSelectIndividualCells(bool state);

	// whether or not multiple cells/rows can be selected
	void SetMultiselectEnabled( bool bState );
	bool IsMultiselectEnabled() const;

	// sets a single cell - all other previous rows are cleared
	virtual void SetSelectedCell(int row, int column);

	virtual bool GetCellAtPos(int x, int y, int &row, int &column);	// returns true if any found, row and column are filled out. x, y are in screen space
	virtual bool GetCellBounds( int row, int column, int& x, int& y, int& wide, int& tall );

	// sets the text which is displayed when the list is empty
	virtual void SetEmptyListText(const char *text);
	virtual void SetEmptyListText(const wchar_t *text);

	// relayout the scroll bar in response to changing the items in the list panel
	// do this if you RemoveAll()
	void ResetScrollBar();

	// Attaches drag data to a particular item
	virtual void OnCreateDragData( KeyValues *msg );

	void		SetIgnoreDoubleClick( bool state );

	// 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();

	MESSAGE_FUNC_INT( ResizeColumnToContents, "ResizeColumnToContents", column );

#ifdef _X360
	virtual void NavigateTo();
#endif
	/// Version number for file format of user config.  This defaults to 1,
	/// and if you rearrange columns you can increment it to cause any old
	/// user configs (which will be screwed up) to be discarded.
	int m_nUserConfigFileVersion;

protected:
	// PAINTING
	virtual Panel *GetCellRenderer(int row, int column);

	// overrides
	virtual void OnMouseWheeled(int delta);
	virtual void OnSizeChanged(int wide, int tall); 
	virtual void PerformLayout();
	virtual void Paint();
	virtual void PaintBackground();
	virtual void ApplySchemeSettings(IScheme *pScheme);
	virtual void OnMousePressed( MouseCode code );
	virtual void OnMouseDoublePressed( MouseCode code );
#ifdef _X360
	virtual void OnKeyCodePressed(KeyCode code);
#else
	virtual void OnKeyCodePressed( KeyCode code );
#endif
	MESSAGE_FUNC( OnSliderMoved, "ScrollBarSliderMoved" );
	MESSAGE_FUNC_INT_INT( OnColumnResized, "ColumnResized", column, delta );
	MESSAGE_FUNC_INT( OnSetSortColumn, "SetSortColumn", column );
	MESSAGE_FUNC( OpenColumnChoiceMenu, "OpenColumnChoiceMenu" );
	MESSAGE_FUNC_INT( OnToggleColumnVisible, "ToggleColumnVisible", col );
	virtual float GetRowsPerPage();
	virtual int GetStartItem();

	// user configuration
	virtual void ApplyUserConfigSettings(KeyValues *userConfig);
	virtual void GetUserConfigSettings(KeyValues *userConfig);
	virtual bool HasUserConfigSettings();

	/* MESSAGES SENT
		"ItemSelected" - query which items are selected
		"ItemDeselected" - query which items are selected
	*/

public:
	virtual void SetSortColumnEx( int iPrimarySortColumn, int iSecondarySortColumn, bool bSortAscending );
	void GetSortColumnEx( int &iPrimarySortColumn, int &iSecondarySortColumn, bool &bSortAscending ) const;

private:
	// Cleans up allocations associated with a particular item
	void CleanupItem( FastSortListPanelItem *data );

	// adds the item into the column indexes
	void IndexItem(int itemID);

	// Purpose: 
	void UpdateSelection( vgui::MouseCode code, int x, int y, int row, int column );

	// Handles multiselect 
	void HandleMultiSelection( int itemID, int row, int column );

	// Handles addselect 
	void HandleAddSelection( int itemID, int row, int column );

	// pre-sorted columns
	struct IndexItem_t
	{
		ListPanelItem *dataItem;
		int duplicateIndex;
	};
	typedef CUtlRBTree<IndexItem_t, int> IndexRBTree_t;

	struct column_t
	{
		Button *m_pHeader;
		int	m_iMinWidth;
		int	m_iMaxWidth;
		bool m_bResizesWithWindow;
		Panel *m_pResizer;
		SortFunc *m_pSortFunc;
		bool m_bTypeIsText;
		bool m_bHidden;
		bool m_bUnhidable;
		IndexRBTree_t m_SortedTree;		
		int m_nContentAlignment;
	};

	// list of the column headers
	CUtlLinkedList<column_t, unsigned char> 		m_ColumnsData;

	// persistent list of all columns ever created, indexes into m_ColumnsData - used for matching up DATAITEM m_SortedTreeIndexes
	CUtlVector<unsigned char>						m_ColumnsHistory;

	// current list of columns, indexes into m_ColumnsData
	CUtlVector<unsigned char>						m_CurrentColumns;

	int				    m_iColumnDraggerMoved; // which column dragger was moved->which header to resize
	int					m_lastBarWidth;

	CUtlLinkedList<FastSortListPanelItem*, int>		m_DataItems;
	CUtlVector<int>									m_VisibleItems;

	// set to true if the table needs to be sorted before it's drawn next
	int 				m_iSortColumn;
	int 				m_iSortColumnSecondary;

	void 				ResortColumnRBTree(int col);
	static bool 		RBTreeLessFunc(vgui::ListPanel::IndexItem_t &item1, vgui::ListPanel::IndexItem_t &item2);

	TextImage			*m_pTextImage; // used in rendering
	ImagePanel			*m_pImagePanel; // used in rendering
	Label				*m_pLabel;	  // used in rendering
	ScrollBar			*m_hbar;
	ScrollBar			*m_vbar;

	int				m_iSelectedColumn;

	bool 			m_bNeedsSort : 1;
	bool 			m_bSortAscending : 1;
	bool 			m_bSortAscendingSecondary : 1;
	bool			m_bCanSelectIndividualCells : 1;
	bool			m_bShiftHeldDown : 1;
	bool			m_bMultiselectEnabled : 1;
	bool			m_bAllowUserAddDeleteColumns : 1;
	bool 			m_bDeleteImageListWhenDone : 1;
	bool			m_bIgnoreDoubleClick : 1;

	int				m_iHeaderHeight;
	int 			m_iRowHeight;
	
	// selection data
	CUtlVector<int> 	m_SelectedItems;		// array of selected rows
	int					m_LastItemSelected;	// remember the last row selected for future shift clicks

	int 		m_iTableStartX;
	int	 		m_iTableStartY;

	Color 		m_LabelFgColor;
	Color		m_DisabledColor;
	Color 		m_SelectionFgColor;
	Color		m_DisabledSelectionFgColor;

	ImageList 	*m_pImageList;
	TextImage 	*m_pEmptyListText;

	PHandle		m_hEditModePanel;
	int			m_iEditModeItemID;
	int			m_iEditModeColumn;

	void ResetColumnHeaderCommands();
};

}

#endif // LISTPANEL_H