1/*
2 * Copyright 2001-2020 Haiku, Inc.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Stephan A��mus, superstippi@gmx.de
7 *		DarkWyrm, bpmagic@columbus.rr.com
8 *		John Scipione, jscipione@gmail.com
9 *		Ingo Weinhold, ingo_weinhold@gmx.de
10 *		Clemens Zeidler, haiku@clemens-zeidler.de
11 *		Joseph Groover, looncraz@looncraz.net
12 *		Tri-Edge AI
13 *		Jacob Secunda, secundja@gmail.com
14 */
15#ifndef DECORATOR_H
16#define DECORATOR_H
17
18
19#include <Rect.h>
20#include <Region.h>
21#include <String.h>
22#include <Window.h>
23
24#include "DrawState.h"
25#include "MultiLocker.h"
26
27class Desktop;
28class DesktopSettings;
29class DrawingEngine;
30class ServerBitmap;
31class ServerFont;
32class BRegion;
33
34
35class Decorator {
36public:
37	struct Tab {
38							Tab();
39		virtual				~Tab() {}
40
41		BRect				tabRect;
42
43		BRect				zoomRect;
44		BRect				closeRect;
45		BRect				minimizeRect;
46
47		bool				closePressed : 1;
48		bool				zoomPressed : 1;
49		bool				minimizePressed : 1;
50
51		window_look			look;
52		uint32				flags;
53		bool				isFocused : 1;
54
55		BString				title;
56
57		uint32				tabOffset;
58		float				tabLocation;
59		float				textOffset;
60
61		BString				truncatedTitle;
62		int32				truncatedTitleLength;
63
64		bool				buttonFocus : 1;
65
66		bool				isHighlighted : 1;
67
68		float				minTabSize;
69		float				maxTabSize;
70
71		ServerBitmap*		closeBitmaps[4];
72		ServerBitmap*		minimizeBitmaps[4];
73		ServerBitmap*		zoomBitmaps[4];
74	};
75
76	enum Region {
77		REGION_NONE,
78
79		REGION_TAB,
80
81		REGION_CLOSE_BUTTON,
82		REGION_ZOOM_BUTTON,
83		REGION_MINIMIZE_BUTTON,
84
85		REGION_LEFT_BORDER,
86		REGION_RIGHT_BORDER,
87		REGION_TOP_BORDER,
88		REGION_BOTTOM_BORDER,
89
90		REGION_LEFT_TOP_CORNER,
91		REGION_LEFT_BOTTOM_CORNER,
92		REGION_RIGHT_TOP_CORNER,
93		REGION_RIGHT_BOTTOM_CORNER,
94
95		REGION_COUNT
96	};
97
98	enum {
99		HIGHLIGHT_NONE,
100		HIGHLIGHT_RESIZE_BORDER,
101
102		HIGHLIGHT_USER_DEFINED
103	};
104
105								Decorator(DesktopSettings& settings,
106											BRect frame,
107											Desktop* desktop);
108	virtual						~Decorator();
109
110	virtual	Decorator::Tab*		AddTab(DesktopSettings& settings,
111									const char* title, window_look look,
112									uint32 flags, int32 index = -1,
113									BRegion* updateRegion = NULL);
114	virtual	bool				RemoveTab(int32 index,
115									BRegion* updateRegion = NULL);
116	virtual	bool				MoveTab(int32 from, int32 to, bool isMoving,
117									BRegion* updateRegion = NULL);
118
119	virtual int32				TabAt(const BPoint& where) const;
120			Decorator::Tab*		TabAt(int32 index) const
121									{ return fTabList.ItemAt(index); }
122			int32				CountTabs() const
123									{ return fTabList.CountItems(); }
124			void				SetTopTab(int32 tab);
125
126			void				SetDrawingEngine(DrawingEngine *driver);
127	inline	DrawingEngine*		GetDrawingEngine() const
128									{ return fDrawingEngine; }
129
130			void				FontsChanged(DesktopSettings& settings,
131									BRegion* updateRegion = NULL);
132			void				ColorsChanged(DesktopSettings& settings,
133									BRegion* updateRegion = NULL);
134
135	virtual void				UpdateColors(DesktopSettings& settings) = 0;
136
137			void				SetLook(int32 tab, DesktopSettings& settings,
138									window_look look,
139									BRegion* updateRegion = NULL);
140			void				SetFlags(int32 tab, uint32 flags,
141									BRegion* updateRegion = NULL);
142
143			window_look			Look(int32 tab) const;
144			uint32				Flags(int32 tab) const;
145
146			BRect				BorderRect() const;
147			BRect				TitleBarRect() const;
148			BRect				TabRect(int32 tab) const;
149			BRect				TabRect(Decorator::Tab* tab) const;
150
151			void				SetClose(int32 tab, bool pressed);
152			void				SetMinimize(int32 tab, bool pressed);
153			void				SetZoom(int32 tab, bool pressed);
154
155			const char*			Title(int32 tab) const;
156			const char*			Title(Decorator::Tab* tab) const;
157			void				SetTitle(int32 tab, const char* string,
158									BRegion* updateRegion = NULL);
159
160			void				SetFocus(int32 tab, bool focussed);
161			bool				IsFocus(int32 tab) const;
162			bool				IsFocus(Decorator::Tab* tab) const;
163
164	virtual	float				TabLocation(int32 tab) const;
165			bool				SetTabLocation(int32 tab, float location,
166									bool isShifting,
167									BRegion* updateRegion = NULL);
168				/*! \return true if tab location updated, false if out of
169					bounds or unsupported */
170
171	virtual	Region				RegionAt(BPoint where, int32& tab) const;
172
173			const BRegion&		GetFootprint();
174			::Desktop*			GetDesktop();
175
176			void				MoveBy(float x, float y);
177			void				MoveBy(BPoint offset);
178			void				ResizeBy(float x, float y, BRegion* dirty);
179			void				ResizeBy(BPoint offset, BRegion* dirty);
180			void				SetOutlinesDelta(BPoint delta, BRegion* dirty);
181			bool				IsOutlineResizing() const
182									{ return fOutlinesDelta != BPoint(0, 0); }
183
184	virtual	bool				SetRegionHighlight(Region region,
185									uint8 highlight, BRegion* dirty,
186									int32 tab = -1);
187	inline	uint8				RegionHighlight(Region region,
188									int32 tab = -1) const;
189
190			bool				SetSettings(const BMessage& settings,
191									BRegion* updateRegion = NULL);
192	virtual	bool				GetSettings(BMessage* settings) const;
193
194	virtual	void				GetSizeLimits(int32* minWidth, int32* minHeight,
195									int32* maxWidth, int32* maxHeight) const;
196	virtual	void				ExtendDirtyRegion(Region region, BRegion& dirty);
197
198	virtual	void				Draw(BRect updateRect) = 0;
199	virtual	void				Draw() = 0;
200
201	virtual	void				DrawTab(int32 tab);
202	virtual	void				DrawTitle(int32 tab);
203
204	virtual	void				DrawClose(int32 tab);
205	virtual	void				DrawMinimize(int32 tab);
206	virtual	void				DrawZoom(int32 tab);
207
208			rgb_color			UIColor(color_which which);
209
210			float				BorderWidth();
211			float				TabHeight();
212
213protected:
214	virtual	Decorator::Tab*		_AllocateNewTab();
215
216	virtual	void				_DoLayout() = 0;
217		//! method for calculating layout for the decorator
218	virtual	void				_DoOutlineLayout() = 0;
219
220	virtual	void				_DrawFrame(BRect rect) = 0;
221	virtual	void				_DrawOutlineFrame(BRect rect) = 0;
222	virtual	void				_DrawTabs(BRect rect);
223
224	virtual	void				_DrawTab(Decorator::Tab* tab, BRect rect) = 0;
225	virtual	void				_DrawTitle(Decorator::Tab* tab,
226									BRect rect) = 0;
227
228	virtual	void				_DrawButtons(Decorator::Tab* tab,
229									const BRect& invalid) = 0;
230	virtual	void				_DrawClose(Decorator::Tab* tab, bool direct,
231									BRect rect) = 0;
232	virtual	void				_DrawMinimize(Decorator::Tab* tab, bool direct,
233									BRect rect) = 0;
234	virtual	void				_DrawZoom(Decorator::Tab* tab, bool direct,
235									BRect rect) = 0;
236
237	virtual	void				_SetTitle(Decorator::Tab* tab,
238									const char* string,
239									BRegion* updateRegion = NULL) = 0;
240			int32				_TitleWidth(Decorator::Tab* tab) const
241									{ return tab->title.CountChars(); }
242
243	virtual	void				_SetFocus(Decorator::Tab* tab);
244	virtual	bool				_SetTabLocation(Decorator::Tab* tab,
245									float location, bool isShifting,
246									BRegion* updateRegion = NULL);
247
248	virtual	Decorator::Tab*		_TabAt(int32 index) const;
249
250	virtual void				_FontsChanged(DesktopSettings& settings,
251									BRegion* updateRegion = NULL);
252	virtual	void				_UpdateFont(DesktopSettings& settings) = 0;
253
254	virtual void				_SetLook(Decorator::Tab* tab,
255									DesktopSettings& settings,
256									window_look look,
257									BRegion* updateRegion = NULL);
258	virtual void				_SetFlags(Decorator::Tab* tab, uint32 flags,
259									BRegion* updateRegion = NULL);
260
261	virtual void				_MoveBy(BPoint offset);
262	virtual	void				_ResizeBy(BPoint offset, BRegion* dirty) = 0;
263
264	virtual void				_MoveOutlineBy(BPoint offset);
265	virtual void				_ResizeOutlineBy(BPoint offset, BRegion* dirty);
266	virtual void				_SetOutlinesDelta(BPoint delta, BRegion* dirty);
267
268	virtual bool				_SetSettings(const BMessage& settings,
269									BRegion* updateRegion = NULL);
270
271	virtual	bool				_AddTab(DesktopSettings& settings,
272									int32 index = -1,
273									BRegion* updateRegion = NULL) = 0;
274	virtual	bool				_RemoveTab(int32 index,
275									BRegion* updateRegion = NULL) = 0;
276	virtual	bool				_MoveTab(int32 from, int32 to, bool isMoving,
277									BRegion* updateRegion = NULL) = 0;
278
279	virtual	void				_GetFootprint(BRegion* region);
280	virtual void				_GetOutlineFootprint(BRegion* region);
281			void				_InvalidateFootprint();
282
283			void 				_InvalidateBitmaps();
284
285protected:
286	mutable		MultiLocker	fLocker;
287
288			DrawingEngine*		fDrawingEngine;
289			DrawState			fDrawState;
290
291			BPoint				fOutlinesDelta;
292
293			// Individual rects for handling window frame
294			// rendering the proper way
295			BRect				fTitleBarRect;
296			BRect				fFrame;
297			BRect				fResizeRect;
298			BRect				fBorderRect;
299			BRect				fOutlineBorderRect;
300
301			BRect				fLeftBorder;
302			BRect				fTopBorder;
303			BRect				fBottomBorder;
304			BRect				fRightBorder;
305
306			BRect				fLeftOutlineBorder;
307			BRect				fTopOutlineBorder;
308			BRect				fBottomOutlineBorder;
309			BRect				fRightOutlineBorder;
310
311			int32				fBorderWidth;
312			int32				fOutlineBorderWidth;
313
314			Decorator::Tab*		fTopTab;
315			BObjectList<Decorator::Tab>	fTabList;
316
317private:
318			Desktop*			fDesktop;
319			BRegion				fFootprint;
320			bool				fFootprintValid : 1;
321
322			uint8				fRegionHighlights[REGION_COUNT - 1];
323};
324
325
326uint8
327Decorator::RegionHighlight(Region region, int32 tab) const
328{
329	int32 index = (int32)region - 1;
330	return index >= 0 && index < REGION_COUNT - 1
331		? fRegionHighlights[index] : 0;
332}
333
334
335#endif	// DECORATOR_H
336