1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2012-2013, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef TREE_TABLE_H
7#define TREE_TABLE_H
8
9#include <vector>
10
11#include <ColumnTypes.h>
12#include <Variant.h>
13
14#include "table/AbstractTable.h"
15#include "table/TableColumn.h"
16
17
18class TreeTable;
19class TreeTableModel;
20class TreeTableNode;
21class TreeTableRow;
22
23
24class TreeTablePath {
25public:
26								TreeTablePath();
27								TreeTablePath(const TreeTablePath& other);
28								TreeTablePath(const TreeTablePath& other,
29									int32 childIndex);
30								~TreeTablePath();
31
32		bool					AddComponent(int32 childIndex);
33		int32					RemoveLastComponent();
34		void					Clear();
35
36		int32					CountComponents() const;
37		int32					ComponentAt(int32 index) const;
38
39		TreeTablePath&			operator=(const TreeTablePath& other);
40		bool					operator==(const TreeTablePath& other) const;
41		bool					operator!=(const TreeTablePath& other) const;
42
43private:
44		typedef std::vector<int32> ComponentVector;
45
46private:
47		ComponentVector			fComponents;
48};
49
50
51class TreeTableModelListener {
52public:
53	virtual						~TreeTableModelListener();
54
55	virtual	void				TableNodesAdded(TreeTableModel* model,
56									const TreeTablePath& path, int32 childIndex,
57									int32 count);
58	virtual	void				TableNodesRemoved(TreeTableModel* model,
59									const TreeTablePath& path, int32 childIndex,
60									int32 count);
61	virtual	void				TableNodesChanged(TreeTableModel* model,
62									const TreeTablePath& path, int32 childIndex,
63									int32 count);
64	virtual	void				TableModelReset(TreeTableModel* model);
65};
66
67
68class TreeTableModel : public AbstractTableModelBase {
69public:
70	virtual						~TreeTableModel();
71
72	virtual	void*				Root() const = 0;
73									// the root itself isn't shown
74
75	virtual	int32				CountChildren(void* parent) const = 0;
76	virtual	void*				ChildAt(void* parent, int32 index) const = 0;
77
78	virtual	bool				GetValueAt(void* object, int32 columnIndex,
79									BVariant& value) = 0;
80
81	virtual	void*				NodeForPath(const TreeTablePath& path) const;
82
83	virtual	bool				AddListener(TreeTableModelListener* listener);
84	virtual	void				RemoveListener(
85									TreeTableModelListener* listener);
86
87protected:
88			typedef BObjectList<TreeTableModelListener> ListenerList;
89
90protected:
91			void				NotifyNodesAdded(const TreeTablePath& path,
92									int32 childIndex, int32 count);
93			void				NotifyNodesRemoved(const TreeTablePath& path,
94									int32 childIndex, int32 count);
95			void				NotifyNodesChanged(const TreeTablePath& path,
96									int32 childIndex, int32 count);
97			void				NotifyTableModelReset();
98
99protected:
100			ListenerList		fListeners;
101};
102
103
104class TreeTableSelectionModel {
105public:
106								TreeTableSelectionModel(TreeTable* table);
107								~TreeTableSelectionModel();
108
109			int32				CountNodes();
110			void*				NodeAt(int32 index);
111			bool				GetPathAt(int32 index, TreeTablePath& _path);
112
113private:
114			friend class TreeTable;
115
116private:
117			void				_SelectionChanged();
118			void				_Update();
119			TreeTableNode*		_NodeAt(int32 index);
120
121private:
122			TreeTable*			fTreeTable;
123			TreeTableNode**		fNodes;
124			int32				fNodeCount;
125};
126
127
128class TreeTableToolTipProvider {
129public:
130	virtual						~TreeTableToolTipProvider();
131
132	virtual	bool				GetToolTipForTablePath(
133									const TreeTablePath& path,
134									int32 columnIndex, BToolTip** _tip) = 0;
135									// columnIndex can be -1, if not in a column
136};
137
138
139class TreeTableListener {
140public:
141	virtual						~TreeTableListener();
142
143	virtual	void				TreeTableSelectionChanged(TreeTable* table);
144	virtual	void				TreeTableNodeInvoked(TreeTable* table,
145									const TreeTablePath& path);
146	virtual	void				TreeTableNodeExpandedChanged(TreeTable* table,
147									const TreeTablePath& path, bool expanded);
148
149	virtual	void				TreeTableCellMouseDown(TreeTable* table,
150									const TreeTablePath& path,
151									int32 columnIndex, BPoint screenWhere,
152									uint32 buttons);
153	virtual	void				TreeTableCellMouseUp(TreeTable* table,
154									const TreeTablePath& path,
155									int32 columnIndex, BPoint screenWhere,
156									uint32 buttons);
157};
158
159
160class TreeTable : public AbstractTable, private TreeTableModelListener {
161public:
162								TreeTable(const char* name, uint32 flags,
163									border_style borderStyle = B_NO_BORDER,
164									bool showHorizontalScrollbar = true);
165								TreeTable(TreeTableModel* model,
166									const char* name, uint32 flags,
167									border_style borderStyle = B_NO_BORDER,
168									bool showHorizontalScrollbar = true);
169	virtual						~TreeTable();
170
171			bool				SetTreeTableModel(TreeTableModel* model);
172			TreeTableModel*		GetTreeTableModel() const	{ return fModel; }
173
174			void				SetToolTipProvider(
175									TreeTableToolTipProvider* toolTipProvider);
176			TreeTableToolTipProvider* ToolTipProvider() const
177									{ return fToolTipProvider; }
178
179			TreeTableSelectionModel* SelectionModel();
180
181			void				SelectNode(const TreeTablePath& path,
182									bool extendSelection);
183			void				DeselectNode(const TreeTablePath& path);
184			void				DeselectAllNodes();
185
186			bool				IsNodeExpanded(const TreeTablePath& path) const;
187			void				SetNodeExpanded(const TreeTablePath& path,
188									bool expanded,
189									bool expandAncestors = false);
190
191			void				ScrollToNode(const TreeTablePath& path);
192
193			bool				AddTreeTableListener(
194									TreeTableListener* listener);
195			void				RemoveTreeTableListener(
196									TreeTableListener* listener);
197
198	virtual	status_t			GetCellRectAt(const TreeTablePath& path,
199									int32 colIndex, BRect& _output) const;
200
201protected:
202	virtual bool				GetToolTipAt(BPoint point, BToolTip** _tip);
203
204	virtual	void				SelectionChanged();
205
206	virtual	AbstractColumn*		CreateColumn(TableColumn* column);
207
208	virtual	void				ColumnMouseDown(AbstractColumn* column,
209									BRow* row, BField* field,
210									BPoint screenWhere, uint32 buttons);
211	virtual	void				ColumnMouseUp(AbstractColumn* column,
212									BRow* row, BField* field,
213									BPoint screenWhere, uint32 buttons);
214
215private:
216	virtual	void				TableNodesAdded(TreeTableModel* model,
217									const TreeTablePath& path, int32 childIndex,
218									int32 count);
219	virtual	void				TableNodesRemoved(TreeTableModel* model,
220									const TreeTablePath& path, int32 childIndex,
221									int32 count);
222	virtual	void				TableNodesChanged(TreeTableModel* model,
223									const TreeTablePath& path, int32 childIndex,
224									int32 count);
225	virtual	void				TableModelReset(TreeTableModel* model);
226
227private:
228			class Column;
229
230			friend class TreeTableSelectionModel;
231
232			typedef BObjectList<TreeTableListener>	ListenerList;
233
234private:
235	virtual	void				ExpandOrCollapse(BRow* row, bool expand);
236	virtual	void				ItemInvoked();
237
238			bool				_AddChildRows(TreeTableNode* parentNode,
239									int32 childIndex, int32 count,
240									int32 columnCount);
241			void				_RemoveChildRows(TreeTableNode* parentNode,
242									int32 childIndex, int32 count);
243
244			void				_SetNodeExpanded(TreeTableNode* node,
245									bool expanded,
246									bool expandAncestors = false);
247
248			TreeTableNode*		_NodeForPath(const TreeTablePath& path) const;
249			void				_GetPathForNode(TreeTableNode* node,
250									TreeTablePath& _path) const;
251
252private:
253			TreeTableModel*		fModel;
254			TreeTableToolTipProvider* fToolTipProvider;
255			TreeTableNode*		fRootNode;
256			TreeTableSelectionModel fSelectionModel;
257			ListenerList		fListeners;
258			int32				fIgnoreSelectionChange;
259};
260
261
262#endif	// TREE_TABLE_H
263