1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2012, 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};
65
66
67class TreeTableModel : public AbstractTableModelBase {
68public:
69	virtual						~TreeTableModel();
70
71	virtual	void*				Root() const = 0;
72									// the root itself isn't shown
73
74	virtual	int32				CountChildren(void* parent) const = 0;
75	virtual	void*				ChildAt(void* parent, int32 index) const = 0;
76
77	virtual	bool				GetValueAt(void* object, int32 columnIndex,
78									BVariant& value) = 0;
79
80	virtual	void*				NodeForPath(const TreeTablePath& path) const;
81
82	virtual	bool				AddListener(TreeTableModelListener* listener);
83	virtual	void				RemoveListener(
84									TreeTableModelListener* listener);
85
86protected:
87			typedef BObjectList<TreeTableModelListener> ListenerList;
88
89protected:
90			void				NotifyNodesAdded(const TreeTablePath& path,
91									int32 childIndex, int32 count);
92			void				NotifyNodesRemoved(const TreeTablePath& path,
93									int32 childIndex, int32 count);
94			void				NotifyNodesChanged(const TreeTablePath& path,
95									int32 childIndex, int32 count);
96
97protected:
98			ListenerList		fListeners;
99};
100
101
102class TreeTableSelectionModel {
103public:
104								TreeTableSelectionModel(TreeTable* table);
105								~TreeTableSelectionModel();
106
107			int32				CountNodes();
108			void*				NodeAt(int32 index);
109			bool				GetPathAt(int32 index, TreeTablePath& _path);
110
111private:
112			friend class TreeTable;
113
114private:
115			void				_SelectionChanged();
116			void				_Update();
117			TreeTableNode*		_NodeAt(int32 index);
118
119private:
120			TreeTable*			fTreeTable;
121			TreeTableNode**		fNodes;
122			int32				fNodeCount;
123};
124
125
126class TreeTableToolTipProvider {
127public:
128	virtual						~TreeTableToolTipProvider();
129
130	virtual	bool				GetToolTipForTablePath(
131									const TreeTablePath& path,
132									int32 columnIndex, BToolTip** _tip) = 0;
133									// columnIndex can be -1, if not in a column
134};
135
136
137class TreeTableListener {
138public:
139	virtual						~TreeTableListener();
140
141	virtual	void				TreeTableSelectionChanged(TreeTable* table);
142	virtual	void				TreeTableNodeInvoked(TreeTable* table,
143									const TreeTablePath& path);
144	virtual	void				TreeTableNodeExpandedChanged(TreeTable* table,
145									const TreeTablePath& path, bool expanded);
146
147	virtual	void				TreeTableCellMouseDown(TreeTable* table,
148									const TreeTablePath& path,
149									int32 columnIndex, BPoint screenWhere,
150									uint32 buttons);
151	virtual	void				TreeTableCellMouseUp(TreeTable* table,
152									const TreeTablePath& path,
153									int32 columnIndex, BPoint screenWhere,
154									uint32 buttons);
155};
156
157
158class TreeTable : public AbstractTable, private TreeTableModelListener {
159public:
160								TreeTable(const char* name, uint32 flags,
161									border_style borderStyle = B_NO_BORDER,
162									bool showHorizontalScrollbar = true);
163								TreeTable(TreeTableModel* model,
164									const char* name, uint32 flags,
165									border_style borderStyle = B_NO_BORDER,
166									bool showHorizontalScrollbar = true);
167	virtual						~TreeTable();
168
169			bool				SetTreeTableModel(TreeTableModel* model);
170			TreeTableModel*		GetTreeTableModel() const	{ return fModel; }
171
172			void				SetToolTipProvider(
173									TreeTableToolTipProvider* toolTipProvider);
174			TreeTableToolTipProvider* ToolTipProvider() const
175									{ return fToolTipProvider; }
176
177			TreeTableSelectionModel* SelectionModel();
178
179			void				SelectNode(const TreeTablePath& path,
180									bool extendSelection);
181			void				DeselectNode(const TreeTablePath& path);
182			void				DeselectAllNodes();
183
184			bool				IsNodeExpanded(const TreeTablePath& path) const;
185			void				SetNodeExpanded(const TreeTablePath& path,
186									bool expanded,
187									bool expandAncestors = false);
188
189			void				ScrollToNode(const TreeTablePath& path);
190
191			bool				AddTreeTableListener(
192									TreeTableListener* listener);
193			void				RemoveTreeTableListener(
194									TreeTableListener* listener);
195
196protected:
197	virtual bool				GetToolTipAt(BPoint point, BToolTip** _tip);
198
199	virtual	void				SelectionChanged();
200
201	virtual	AbstractColumn*		CreateColumn(TableColumn* column);
202
203	virtual	void				ColumnMouseDown(AbstractColumn* column,
204									BRow* row, BField* field,
205									BPoint screenWhere, uint32 buttons);
206	virtual	void				ColumnMouseUp(AbstractColumn* column,
207									BRow* row, BField* field,
208									BPoint screenWhere, uint32 buttons);
209
210private:
211	virtual	void				TableNodesAdded(TreeTableModel* model,
212									const TreeTablePath& path, int32 childIndex,
213									int32 count);
214	virtual	void				TableNodesRemoved(TreeTableModel* model,
215									const TreeTablePath& path, int32 childIndex,
216									int32 count);
217	virtual	void				TableNodesChanged(TreeTableModel* model,
218									const TreeTablePath& path, int32 childIndex,
219									int32 count);
220
221private:
222			class Column;
223
224			friend class TreeTableSelectionModel;
225
226			typedef BObjectList<TreeTableListener>	ListenerList;
227
228private:
229	virtual	void				ExpandOrCollapse(BRow* row, bool expand);
230	virtual	void				ItemInvoked();
231
232			bool				_AddChildRows(TreeTableNode* parentNode,
233									int32 childIndex, int32 count,
234									int32 columnCount);
235			void				_RemoveChildRows(TreeTableNode* parentNode,
236									int32 childIndex, int32 count);
237
238			void				_SetNodeExpanded(TreeTableNode* node,
239									bool expanded,
240									bool expandAncestors = false);
241
242			TreeTableNode*		_NodeForPath(const TreeTablePath& path) const;
243			void				_GetPathForNode(TreeTableNode* node,
244									TreeTablePath& _path) const;
245
246private:
247			TreeTableModel*		fModel;
248			TreeTableToolTipProvider* fToolTipProvider;
249			TreeTableNode*		fRootNode;
250			TreeTableSelectionModel fSelectionModel;
251			ListenerList		fListeners;
252			int32				fIgnoreSelectionChange;
253};
254
255
256#endif	// TREE_TABLE_H
257