1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2009, Stephan Aßmus, superstippi@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef HEADER_VIEW_H
7#define HEADER_VIEW_H
8
9
10#include <View.h>
11
12#include <ObjectList.h>
13#include <Referenceable.h>
14#include <Variant.h>
15
16
17class Header;
18class HeaderModel;
19class HeaderViewListener;
20
21
22class HeaderRenderer {
23public:
24	virtual						~HeaderRenderer();
25
26	virtual	float				HeaderHeight(BView* view, const Header* header)
27									= 0;
28	virtual	float				PreferredHeaderWidth(BView* view,
29									const Header* header) = 0;
30	virtual	void				DrawHeader(BView* view, BRect frame,
31									BRect updateRect, const Header* header,
32									uint32 flags) = 0;
33	virtual	void				DrawHeaderBackground(BView* view, BRect frame,
34									BRect updateRect, uint32 flags);
35};
36
37
38class DefaultHeaderRenderer : public HeaderRenderer {
39public:
40								DefaultHeaderRenderer();
41	virtual						~DefaultHeaderRenderer();
42
43	virtual	float				HeaderHeight(BView* view, const Header* header);
44	virtual	float				PreferredHeaderWidth(BView* view,
45									const Header* header);
46	virtual	void				DrawHeader(BView* view, BRect frame,
47									BRect updateRect, const Header* header,
48									uint32 flags);
49};
50
51
52class HeaderListener {
53public:
54	virtual						~HeaderListener();
55
56	virtual	void				HeaderWidthChanged(Header* header);
57	virtual	void				HeaderWidthRestrictionsChanged(Header* header);
58	virtual	void				HeaderValueChanged(Header* header);
59	virtual	void				HeaderRendererChanged(Header* header);
60};
61
62
63class Header {
64public:
65								Header(int32 modelIndex = 0);
66								Header(float width, float minWidth,
67									float maxWidth, float preferredWidth,
68									int32 modelIndex = 0);
69
70			float				Width() const;
71			float				MinWidth() const;
72			float				MaxWidth() const;
73			float				PreferredWidth() const;
74
75			void				SetWidth(float width);
76			void				SetMinWidth(float width);
77			void				SetMaxWidth(float width);
78			void				SetPreferredWidth(float width);
79
80			bool				IsResizable() const;
81			void				SetResizable(bool resizable);
82
83			bool				GetValue(BVariant& _value) const;
84			void				SetValue(const BVariant& value);
85
86			int32				ModelIndex() const;
87			void				SetModelIndex(int32 index);
88
89			HeaderRenderer*		GetHeaderRenderer() const;
90			void				SetHeaderRenderer(HeaderRenderer* renderer);
91
92			void				AddListener(HeaderListener* listener);
93			void				RemoveListener(HeaderListener* listener);
94
95protected:
96			void				NotifyWidthChanged();
97			void				NotifyWidthRestrictionsChanged();
98			void				NotifyValueChanged();
99			void				NotifyRendererChanged();
100
101private:
102			typedef BObjectList<HeaderListener> ListenerList;
103
104private:
105			float				fWidth;
106			float				fMinWidth;
107			float				fMaxWidth;
108			float				fPreferredWidth;
109			BVariant			fValue;
110			HeaderRenderer*		fRenderer;
111			int32				fModelIndex;
112			bool				fResizable;
113			ListenerList		fListeners;
114};
115
116
117class HeaderModelListener {
118public:
119	virtual						~HeaderModelListener();
120
121	virtual	void				HeaderAdded(HeaderModel* model, int32 index);
122	virtual	void				HeaderRemoved(HeaderModel* model, int32 index);
123	virtual	void				HeaderMoved(HeaderModel* model,
124									int32 fromIndex, int32 toIndex);
125};
126
127
128class HeaderModel : public BReferenceable {
129public:
130								HeaderModel();
131	virtual						~HeaderModel();
132
133	virtual	int32				CountHeaders() const;
134	virtual	Header*				HeaderAt(int32 index) const;
135	virtual	int32				IndexOfHeader(Header* header) const;
136
137	virtual	bool				AddHeader(Header* header);
138	virtual	Header*				RemoveHeader(int32 index);
139	virtual	void				RemoveHeader(Header* header);
140	virtual	bool				MoveHeader(int32 fromIndex, int32 toIndex);
141
142	virtual	void				AddListener(HeaderModelListener* listener);
143	virtual	void				RemoveListener(HeaderModelListener* listener);
144
145protected:
146			void				NotifyHeaderAdded(int32 index);
147			void				NotifyHeaderRemoved(int32 index);
148			void				NotifyHeaderMoved(int32 fromIndex,
149									int32 toIndex);
150
151private:
152			typedef BObjectList<Header> HeaderList;
153			typedef BObjectList<HeaderModelListener> ListenerList;
154
155private:
156			HeaderList			fHeaders;
157			ListenerList		fListeners;
158};
159
160
161class HeaderView : public BView, private HeaderModelListener,
162	private HeaderListener {
163public:
164								HeaderView();
165	virtual						~HeaderView();
166
167	virtual	void				Draw(BRect updateRect);
168
169	virtual	void				MouseDown(BPoint where);
170	virtual	void				MouseUp(BPoint where);
171	virtual	void				MouseMoved(BPoint where, uint32 transit,
172									const BMessage* dragMessage);
173
174	virtual	BSize				MinSize();
175	virtual	BSize				MaxSize();
176	virtual	BSize				PreferredSize();
177
178			HeaderModel*		Model() const;
179			status_t			SetModel(HeaderModel* model);
180
181			BRect				HeaderFrame(int32 index) const;
182			int32				HeaderIndexAt(BPoint point) const;
183
184			void				AddListener(HeaderViewListener* listener);
185			void				RemoveListener(HeaderViewListener* listener);
186
187private:
188			struct HeaderEntry;
189
190			typedef BObjectList<HeaderEntry> HeaderEntryList;
191			typedef BObjectList<HeaderViewListener> ListenerList;
192
193			class State;
194			class DefaultState;
195			class ResizeState;
196
197			friend class DefaultState;
198			friend class ResizeState;
199
200private:
201	// HeaderModelListener
202	virtual	void				HeaderAdded(HeaderModel* model, int32 index);
203	virtual	void				HeaderRemoved(HeaderModel* model, int32 index);
204	virtual	void				HeaderMoved(HeaderModel* model,
205									int32 fromIndex, int32 toIndex);
206
207	// HeaderListener
208	virtual	void				HeaderWidthChanged(Header* header);
209	virtual	void				HeaderWidthRestrictionsChanged(Header* header);
210	virtual	void				HeaderValueChanged(Header* header);
211	virtual	void				HeaderRendererChanged(Header* header);
212
213			void				_HeaderPropertiesChanged(Header* header,
214									bool redrawNeeded, bool relayoutNeeded);
215			void				_InvalidateHeadersLayout(int32 firstIndex);
216			void				_InvalidateHeaders(int32 firstIndex,
217									int32 endIndex);
218			void				_ValidateHeadersLayout();
219
220			void				_SwitchState(State* newState);
221
222private:
223			HeaderModel*		fModel;
224			HeaderEntryList		fHeaderEntries;
225			float				fPreferredWidth;
226			float				fPreferredHeight;
227			bool				fLayoutValid;
228			ListenerList		fListeners;
229			State*				fDefaultState;
230			State*				fState;
231};
232
233
234class HeaderViewListener {
235public:
236	virtual						~HeaderViewListener();
237};
238
239
240#endif	// HEADER_VIEW_H
241