1/*
2Open Tracker License
3
4Terms and Conditions
5
6Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a copy of
9this software and associated documentation files (the "Software"), to deal in
10the Software without restriction, including without limitation the rights to
11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12of the Software, and to permit persons to whom the Software is furnished to do
13so, subject to the following conditions:
14
15The above copyright notice and this permission notice applies to all licensees
16and shall be included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25Except as contained in this notice, the name of Be Incorporated shall not be
26used in advertising or otherwise to promote the sale, use or other dealings in
27this Software without prior written authorization from Be Incorporated.
28
29Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30of Be Incorporated in the United States and other countries. Other brand product
31names are registered trademarks or trademarks of their respective holders.
32All rights reserved.
33*/
34
35/*******************************************************************************
36/
37/	File:			ColumnListView.h
38/
39/   Description:    Experimental multi-column list view.
40/
41/	Copyright 2000+, Be Incorporated, All Rights Reserved
42/
43*******************************************************************************/
44
45
46#ifndef _COLUMN_LIST_VIEW_H
47#define _COLUMN_LIST_VIEW_H
48
49#include <BeBuild.h>
50#include <View.h>
51#include <List.h>
52#include <Invoker.h>
53#include <ListView.h>
54
55class BScrollBar;
56
57namespace BPrivate {
58
59class OutlineView;
60class TitleView;
61class BRowContainer;
62class RecursiveOutlineIterator;
63
64}	// ns BPrivate
65
66class BColumn;
67class BColumnListView;
68class BField;
69class BRow;
70
71enum LatchType {
72	B_NO_LATCH					= 0,
73	B_OPEN_LATCH				= 1,
74	B_PRESSED_LATCH				= 2,
75	B_CLOSED_LATCH				= 3
76};
77
78typedef enum {
79	B_ALLOW_COLUMN_NONE			= 0,
80	B_ALLOW_COLUMN_MOVE			= 1,
81	B_ALLOW_COLUMN_RESIZE		= 2,
82	B_ALLOW_COLUMN_POPUP		= 4,
83	B_ALLOW_COLUMN_REMOVE		= 8
84} column_flags;
85
86enum ColumnListViewColor {
87	B_COLOR_BACKGROUND			= 0,
88	B_COLOR_TEXT				= 1,
89	B_COLOR_ROW_DIVIDER			= 2,
90	B_COLOR_SELECTION			= 3,
91	B_COLOR_SELECTION_TEXT		= 4,
92	B_COLOR_NON_FOCUS_SELECTION	= 5,
93	B_COLOR_EDIT_BACKGROUND		= 6,
94	B_COLOR_EDIT_TEXT			= 7,
95	B_COLOR_HEADER_BACKGROUND	= 8,
96	B_COLOR_HEADER_TEXT			= 9,
97	B_COLOR_SEPARATOR_LINE		= 10,
98	B_COLOR_SEPARATOR_BORDER	= 11,
99
100	B_COLOR_TOTAL				= 12
101};
102
103enum ColumnListViewFont {
104	B_FONT_ROW					= 0,
105	B_FONT_HEADER				= 1,
106
107	B_FONT_TOTAL				= 2
108};
109
110
111// A single row/column intersection in the list.
112class BField {
113public:
114								BField();
115	virtual						~BField();
116};
117
118// A single line in the list.  Each line contains a BField object
119// for each column in the list, associated by their "logical field"
120// index.  Hierarchies are formed by adding other BRow objects as
121// a parent of a row, using the AddRow() function in BColumnListView().
122class BRow {
123public:
124								BRow();
125								BRow(float height);
126	virtual 					~BRow();
127	virtual bool		 		HasLatch() const;
128
129			int32				CountFields() const;
130			BField*				GetField(int32 logicalFieldIndex);
131	const	BField*				GetField(int32 logicalFieldIndex) const;
132			void				SetField(BField* field,
133									int32 logicalFieldIndex);
134
135			float 				Height() const;
136			bool 				IsExpanded() const;
137			bool				IsSelected() const;
138
139			void				Invalidate();
140
141private:
142	// Blows up into the debugger if the validation fails.
143			void				ValidateFields() const;
144			void				ValidateField(const BField* field,
145									int32 logicalFieldIndex) const;
146private:
147			BList				fFields;
148			BPrivate::
149			BRowContainer*		fChildList;
150			bool				fIsExpanded;
151			float				fHeight;
152			BRow*				fNextSelected;
153			BRow*				fPrevSelected;
154			BRow*				fParent;
155			BColumnListView*	fList;
156
157
158	friend class BColumnListView;
159	friend class BPrivate::RecursiveOutlineIterator;
160	friend class BPrivate::OutlineView;
161};
162
163// Information about a single column in the list.  A column knows
164// how to display the BField objects that occur at its location in
165// each of the list's rows.  See ColumnTypes.h for particular
166// subclasses of BField and BColumn that handle common data types.
167class BColumn {
168public:
169								BColumn(float width, float minWidth,
170									float maxWidth,
171									alignment align = B_ALIGN_LEFT);
172	virtual 					~BColumn();
173
174			float				Width() const;
175			void				SetWidth(float width);
176			float				MinWidth() const;
177			float				MaxWidth() const;
178
179	virtual	void				DrawTitle(BRect rect, BView* targetView);
180	virtual	void				DrawField(BField* field, BRect rect,
181									BView* targetView);
182	virtual	int					CompareFields(BField* field1, BField* field2);
183
184	virtual void				MouseMoved(BColumnListView* parent, BRow* row,
185									BField* field, BRect fieldRect,
186									BPoint point, uint32 buttons, int32 code);
187	virtual void				MouseDown(BColumnListView* parent, BRow* row,
188									BField* field, BRect fieldRect,
189									BPoint point, uint32 buttons);
190	virtual	void				MouseUp(BColumnListView* parent, BRow* row,
191									BField* field);
192
193	virtual	void				GetColumnName(BString* into) const;
194	virtual	float				GetPreferredWidth(BField* field,
195									BView* parent) const;
196
197			bool				IsVisible() const;
198			void				SetVisible(bool);
199
200			bool				WantsEvents() const;
201			void				SetWantsEvents(bool);
202
203			bool				ShowHeading() const;
204			void				SetShowHeading(bool);
205
206			alignment			Alignment() const;
207			void				SetAlignment(alignment);
208
209			int32				LogicalFieldNum() const;
210
211	/*!
212		\param field The BField derivative to validate.
213
214			Implement this function on your BColumn derivatives to validate
215			BField derivatives that your BColumn will be drawing/manipulating.
216
217			This function will be called when BFields are added to the Column,
218			use dynamic_cast<> to determine if it is of a kind that your
219			BColumn know how ot handle. return false if it is not.
220
221			\note The debugger will be called if you return false from here
222			with information about what type of BField and BColumn and the
223			logical field index where it occured.
224
225			\note Do not call the inherited version of this, it just returns
226			true;
227	  */
228	virtual	bool				AcceptsField(const BField* field) const;
229
230private:
231			float				fWidth;
232			float 				fMinWidth;
233			float				fMaxWidth;
234			bool				fVisible;
235			int32				fFieldID;
236			BColumnListView*	fList;
237			bool				fSortAscending;
238			bool				fWantsEvents;
239			bool				fShowHeading;
240			alignment			fAlignment;
241
242	friend class BPrivate::OutlineView;
243	friend class BColumnListView;
244	friend class BPrivate::TitleView;
245};
246
247// The column list view class.
248class BColumnListView : public BView, public BInvoker {
249public:
250								BColumnListView(BRect rect,
251									const char* name, uint32 resizingMode,
252									uint32 flags, border_style = B_NO_BORDER,
253									bool showHorizontalScrollbar = true);
254								BColumnListView(const char* name,
255									uint32 flags, border_style = B_NO_BORDER,
256									bool showHorizontalScrollbar = true);
257	virtual						~BColumnListView();
258
259	// Interaction
260	virtual	bool				InitiateDrag(BPoint, bool wasSelected);
261	virtual	void				MessageDropped(BMessage*, BPoint point);
262	virtual	void				ExpandOrCollapse(BRow* row, bool expand);
263	virtual	status_t			Invoke(BMessage* message = NULL);
264	virtual	void				ItemInvoked();
265	virtual	void				SetInvocationMessage(BMessage* message);
266			BMessage* 			InvocationMessage() const;
267			uint32 				InvocationCommand() const;
268			BRow* 				FocusRow() const;
269			void 				SetFocusRow(int32 index, bool select = false);
270			void 				SetFocusRow(BRow* row, bool select = false);
271			void 				SetMouseTrackingEnabled(bool);
272
273	// Selection
274			list_view_type		SelectionMode() const;
275			void 				Deselect(BRow* row);
276			void 				AddToSelection(BRow* row);
277			void 				DeselectAll();
278			BRow*				CurrentSelection(BRow* lastSelected = 0) const;
279	virtual	void				SelectionChanged();
280	virtual	void				SetSelectionMessage(BMessage* message);
281			BMessage*			SelectionMessage();
282			uint32				SelectionCommand() const;
283			void				SetSelectionMode(list_view_type type);
284				// list_view_type is defined in ListView.h.
285
286	// Sorting
287			void				SetSortingEnabled(bool);
288			bool				SortingEnabled() const;
289			void				SetSortColumn(BColumn* column, bool add,
290									bool ascending);
291			void				ClearSortColumns();
292
293	// The status view is a little area in the lower left hand corner.
294			void				AddStatusView(BView* view);
295			BView*				RemoveStatusView();
296
297	// Column Manipulation
298			void				AddColumn(BColumn* column,
299									int32 logicalFieldIndex);
300			void				MoveColumn(BColumn* column, int32 index);
301			void				RemoveColumn(BColumn* column);
302			int32				CountColumns() const;
303			BColumn*			ColumnAt(int32 index) const;
304			BColumn*			ColumnAt(BPoint point) const;
305			void				SetColumnVisible(BColumn* column,
306									bool isVisible);
307			void				SetColumnVisible(int32, bool);
308			bool				IsColumnVisible(int32) const;
309			void				SetColumnFlags(column_flags flags);
310			void				ResizeColumnToPreferred(int32 index);
311			void				ResizeAllColumnsToPreferred();
312
313	// Row manipulation
314			const BRow*			RowAt(int32 index, BRow *parent = 0) const;
315			BRow*				RowAt(int32 index, BRow *parent = 0);
316			const BRow*			RowAt(BPoint) const;
317			BRow*				RowAt(BPoint);
318			bool				GetRowRect(const BRow* row, BRect* _rect) const;
319			bool				FindParent(BRow* row, BRow** _parent,
320									bool *_isVisible) const;
321			int32				IndexOf(BRow* row);
322			int32				CountRows(BRow* parent = 0) const;
323			void				AddRow(BRow* row, BRow* parent = NULL);
324			void				AddRow(BRow* row, int32 index,
325									BRow* parent = NULL);
326
327			void				ScrollTo(const BRow* Row);
328			void				ScrollTo(BPoint point);
329
330	// Does not delete row or children at this time.
331	// todo: Make delete row and children
332			void				RemoveRow(BRow* row);
333			void				UpdateRow(BRow* row);
334			bool				SwapRows(int32 index1, int32 index2, BRow*
335									parentRow1 = NULL, BRow* parentRow2 = NULL);
336			void				Clear();
337
338			void				InvalidateRow(BRow* row);
339
340	// Appearance (DEPRECATED)
341			void				GetFont(BFont* font) const
342									{ BView::GetFont(font); }
343	virtual	void				SetFont(const BFont* font,
344									uint32 mask = B_FONT_ALL);
345	virtual	void				SetHighColor(rgb_color);
346			void				SetSelectionColor(rgb_color);
347			void				SetBackgroundColor(rgb_color);
348			void				SetEditColor(rgb_color);
349			const rgb_color		SelectionColor() const;
350			const rgb_color		BackgroundColor() const;
351			const rgb_color		EditColor() const;
352
353	// Appearance (NEW STYLE)
354			void				SetColor(ColumnListViewColor colorIndex,
355									rgb_color color);
356			void				ResetColors();
357			void				SetFont(ColumnListViewFont fontIndex,
358									const BFont* font,
359									uint32 mask = B_FONT_ALL);
360			rgb_color			Color(ColumnListViewColor colorIndex) const;
361			void				GetFont(ColumnListViewFont fontIndex,
362									BFont* font) const;
363
364			BPoint				SuggestTextPosition(const BRow* row,
365									const BColumn* column = NULL) const;
366
367			BRect				GetFieldRect(const BRow* row,
368									const BColumn* column) const;
369
370			void				SetLatchWidth(float width);
371			float				LatchWidth() const;
372	virtual	void				DrawLatch(BView* view, BRect frame,
373									LatchType type, BRow* row);
374	virtual	void				MakeFocus(bool isfocus = true);
375			void				SaveState(BMessage* archive);
376			void				LoadState(BMessage* archive);
377
378			BView*				ScrollView() const
379									{ return (BView*)fOutlineView; }
380			void				SetEditMode(bool state);
381			void				Refresh();
382
383	virtual BSize				MinSize();
384	virtual BSize				PreferredSize();
385	virtual BSize				MaxSize();
386
387
388protected:
389	virtual	void 				MessageReceived(BMessage* message);
390	virtual	void 				KeyDown(const char* bytes, int32 numBytes);
391	virtual	void 				AttachedToWindow();
392	virtual	void 				WindowActivated(bool active);
393	virtual	void 				Draw(BRect updateRect);
394
395	virtual	void				LayoutInvalidated(bool descendants = false);
396	virtual	void				DoLayout();
397
398private:
399			void				_Init();
400			void				_UpdateColors();
401			void				_GetChildViewRects(const BRect& bounds,
402									BRect& titleRect, BRect& outlineRect,
403									BRect& vScrollBarRect,
404									BRect& hScrollBarRect);
405
406			rgb_color 			fColorList[B_COLOR_TOTAL];
407			bool				fCustomColors;
408			BPrivate::TitleView* fTitleView;
409			BPrivate::OutlineView* fOutlineView;
410			BList 				fColumns;
411			BScrollBar*			fHorizontalScrollBar;
412			BScrollBar* 		fVerticalScrollBar;
413			BList				fSortColumns;
414			BView*				fStatusView;
415			BMessage*			fSelectionMessage;
416			bool				fSortingEnabled;
417			float				fLatchWidth;
418			border_style		fBorderStyle;
419			bool				fShowingHorizontalScrollBar;
420};
421
422#endif // _COLUMN_LIST_VIEW_H
423