105bd1efeSAxel Dörfler/*
27f9368caSlooncraz * Copyright 2001-2015 Haiku, Inc.
305bd1efeSAxel Dörfler * Distributed under the terms of the MIT License.
405bd1efeSAxel Dörfler *
505bd1efeSAxel Dörfler * Authors:
687c51182SJohn Scipione *		Stephan A��mus, superstippi@gmx.de
787c51182SJohn Scipione *		DarkWyrm, bpmagic@columbus.rr.com
887c51182SJohn Scipione *		John Scipione, jscipione@gmail.com
987c51182SJohn Scipione *		Ingo Weinhold, ingo_weinhold@gmx.de
1087c51182SJohn Scipione *		Clemens Zeidler, haiku@clemens-zeidler.de
117f9368caSlooncraz *		Joseph Groover <looncraz@looncraz.net>
1205bd1efeSAxel Dörfler */
1305bd1efeSAxel Dörfler
143a5082aaSAxel Dörfler
153a83c7b1SAxel Dörfler/*!	Base class for window decorators */
1605bd1efeSAxel Dörfler
173a5082aaSAxel Dörfler
18a3d04b0eSDarkWyrm#include "Decorator.h"
193a83c7b1SAxel Dörfler
203a83c7b1SAxel Dörfler#include <stdio.h>
2105bd1efeSAxel Dörfler
2205bd1efeSAxel Dörfler#include <Region.h>
2305bd1efeSAxel Dörfler
247f9368caSlooncraz#include "Desktop.h"
257f9368caSlooncraz#include "DesktopSettings.h"
263a83c7b1SAxel Dörfler#include "DrawingEngine.h"
277641924eSAdi Oanca
2805bd1efeSAxel Dörfler
29bb2e9b06SClemens ZeidlerDecorator::Tab::Tab()
30bb2e9b06SClemens Zeidler	:
31cfe0652aSJohn Scipione	tabRect(),
32cfe0652aSJohn Scipione
33bb2e9b06SClemens Zeidler	zoomRect(),
34bb2e9b06SClemens Zeidler	closeRect(),
35bb2e9b06SClemens Zeidler	minimizeRect(),
36bb2e9b06SClemens Zeidler
37bb2e9b06SClemens Zeidler	closePressed(false),
38bb2e9b06SClemens Zeidler	zoomPressed(false),
39bb2e9b06SClemens Zeidler	minimizePressed(false),
401c141573SClemens Zeidler
411c141573SClemens Zeidler	look(B_TITLED_WINDOW_LOOK),
421c141573SClemens Zeidler	flags(0),
43bb2e9b06SClemens Zeidler	isFocused(false),
44cfe0652aSJohn Scipione	title(""),
45cfe0652aSJohn Scipione
46cfe0652aSJohn Scipione	tabOffset(0),
47cfe0652aSJohn Scipione	tabLocation(0.0f),
48cfe0652aSJohn Scipione	textOffset(10.0f),
49cfe0652aSJohn Scipione
50cfe0652aSJohn Scipione	truncatedTitle(""),
51cfe0652aSJohn Scipione	truncatedTitleLength(0),
52cfe0652aSJohn Scipione
53cfe0652aSJohn Scipione	buttonFocus(false),
54cfe0652aSJohn Scipione	isHighlighted(false),
55bb2e9b06SClemens Zeidler
56cfe0652aSJohn Scipione	minTabSize(0.0f),
57cfe0652aSJohn Scipione	maxTabSize(0.0f)
58cfe0652aSJohn Scipione{
59cfe0652aSJohn Scipione	closeBitmaps[0] = closeBitmaps[1] = closeBitmaps[2] = closeBitmaps[3]
60cfe0652aSJohn Scipione		= minimizeBitmaps[0] = minimizeBitmaps[1] = minimizeBitmaps[2]
61cfe0652aSJohn Scipione		= minimizeBitmaps[3] = zoomBitmaps[0] = zoomBitmaps[1] = zoomBitmaps[2]
62cfe0652aSJohn Scipione		= zoomBitmaps[3] = NULL;
63bb2e9b06SClemens Zeidler}
64bb2e9b06SClemens Zeidler
65bb2e9b06SClemens Zeidler
663a83c7b1SAxel Dörfler/*!	\brief Constructor
673a83c7b1SAxel Dörfler
683a83c7b1SAxel Dörfler	Does general initialization of internal data members and creates a colorset
690a3f410fSAxel Dörfler	object.
703a83c7b1SAxel Dörfler
71106fe8b3SJohn Scipione	\param settings DesktopSettings pointer.
72cfe0652aSJohn Scipione	\param frame Decorator frame rectangle
73a3d04b0eSDarkWyrm*/
747f9368caSlooncrazDecorator::Decorator(DesktopSettings& settings, BRect frame,
757f9368caSlooncraz					Desktop* desktop)
7685f8bb71SAxel Dörfler	:
772cfe93e7SStephan Aßmus	fDrawingEngine(NULL),
7885f8bb71SAxel Dörfler	fDrawState(),
7985f8bb71SAxel Dörfler
80bb2e9b06SClemens Zeidler	fTitleBarRect(),
81cfe0652aSJohn Scipione	fFrame(frame),
822cfe93e7SStephan Aßmus	fResizeRect(),
832cfe93e7SStephan Aßmus	fBorderRect(),
8485f8bb71SAxel Dörfler
85cfe0652aSJohn Scipione	fLeftBorder(),
86cfe0652aSJohn Scipione	fTopBorder(),
87cfe0652aSJohn Scipione	fBottomBorder(),
88cfe0652aSJohn Scipione	fRightBorder(),
89cfe0652aSJohn Scipione
90cfe0652aSJohn Scipione	fBorderWidth(-1),
91cfe0652aSJohn Scipione
92bb2e9b06SClemens Zeidler	fTopTab(NULL),
9309301a49SClemens Zeidler
947f9368caSlooncraz	fDesktop(desktop),
9509301a49SClemens Zeidler	fFootprintValid(false)
96a3d04b0eSDarkWyrm{
972b602c73SIngo Weinhold	memset(&fRegionHighlights, HIGHLIGHT_NONE, sizeof(fRegionHighlights));
98a3d04b0eSDarkWyrm}
99a3d04b0eSDarkWyrm
10085f8bb71SAxel Dörfler
101106fe8b3SJohn Scipione/*!	\brief Destructor
1020a3f410fSAxel Dörfler
103a3d04b0eSDarkWyrm	Frees the color set and the title string
104a3d04b0eSDarkWyrm*/
10559345e26SStephan AßmusDecorator::~Decorator()
106a3d04b0eSDarkWyrm{
107a3d04b0eSDarkWyrm}
108a3d04b0eSDarkWyrm
10985f8bb71SAxel Dörfler
110bb2e9b06SClemens ZeidlerDecorator::Tab*
1111c141573SClemens ZeidlerDecorator::AddTab(DesktopSettings& settings, const char* title,
1121c141573SClemens Zeidler	window_look look, uint32 flags, int32 index, BRegion* updateRegion)
113bb2e9b06SClemens Zeidler{
114bb2e9b06SClemens Zeidler	Decorator::Tab* tab = _AllocateNewTab();
115bb2e9b06SClemens Zeidler	if (tab == NULL)
116bb2e9b06SClemens Zeidler		return NULL;
117bb2e9b06SClemens Zeidler	tab->title = title;
1181c141573SClemens Zeidler	tab->look = look;
1191c141573SClemens Zeidler	tab->flags = flags;
120bb2e9b06SClemens Zeidler
121bb2e9b06SClemens Zeidler	bool ok = false;
122bb2e9b06SClemens Zeidler	if (index >= 0) {
123bb2e9b06SClemens Zeidler		if (fTabList.AddItem(tab, index) == true)
124bb2e9b06SClemens Zeidler			ok = true;
125bb2e9b06SClemens Zeidler	} else if (fTabList.AddItem(tab) == true)
126bb2e9b06SClemens Zeidler		ok = true;
127bb2e9b06SClemens Zeidler
128bb2e9b06SClemens Zeidler	if (ok == false) {
129bb2e9b06SClemens Zeidler		delete tab;
130bb2e9b06SClemens Zeidler		return NULL;
131bb2e9b06SClemens Zeidler	}
132bb2e9b06SClemens Zeidler
1331c141573SClemens Zeidler	Decorator::Tab* oldTop = fTopTab;
1341c141573SClemens Zeidler	fTopTab = tab;
1351c141573SClemens Zeidler	if (_AddTab(settings, index, updateRegion) == false) {
136bb2e9b06SClemens Zeidler		fTabList.RemoveItem(tab);
137bb2e9b06SClemens Zeidler		delete tab;
1381c141573SClemens Zeidler		fTopTab = oldTop;
139bb2e9b06SClemens Zeidler		return NULL;
140bb2e9b06SClemens Zeidler	}
141bb2e9b06SClemens Zeidler
142bb2e9b06SClemens Zeidler	_InvalidateFootprint();
143bb2e9b06SClemens Zeidler	return tab;
144bb2e9b06SClemens Zeidler}
145bb2e9b06SClemens Zeidler
146bb2e9b06SClemens Zeidler
147bb2e9b06SClemens Zeidlerbool
148bb2e9b06SClemens ZeidlerDecorator::RemoveTab(int32 index, BRegion* updateRegion)
149bb2e9b06SClemens Zeidler{
150bb2e9b06SClemens Zeidler	Decorator::Tab* tab = fTabList.RemoveItemAt(index);
151bb2e9b06SClemens Zeidler	if (tab == NULL)
152bb2e9b06SClemens Zeidler		return false;
153bb2e9b06SClemens Zeidler
154bb2e9b06SClemens Zeidler	_RemoveTab(index, updateRegion);
155bb2e9b06SClemens Zeidler
156bb2e9b06SClemens Zeidler	delete tab;
157bb2e9b06SClemens Zeidler	_InvalidateFootprint();
158bb2e9b06SClemens Zeidler	return true;
159bb2e9b06SClemens Zeidler}
160bb2e9b06SClemens Zeidler
161bb2e9b06SClemens Zeidler
162bb2e9b06SClemens Zeidlerbool
163bb2e9b06SClemens ZeidlerDecorator::MoveTab(int32 from, int32 to, bool isMoving, BRegion* updateRegion)
164bb2e9b06SClemens Zeidler{
165bb2e9b06SClemens Zeidler	if (_MoveTab(from, to, isMoving, updateRegion) == false)
166bb2e9b06SClemens Zeidler		return false;
167bb2e9b06SClemens Zeidler	if (fTabList.MoveItem(from, to) == false) {
168bb2e9b06SClemens Zeidler		// move the tab back
169bb2e9b06SClemens Zeidler		_MoveTab(from, to, isMoving, updateRegion);
170bb2e9b06SClemens Zeidler		return false;
171bb2e9b06SClemens Zeidler	}
172bb2e9b06SClemens Zeidler	return true;
173bb2e9b06SClemens Zeidler}
174bb2e9b06SClemens Zeidler
175bb2e9b06SClemens Zeidler
176bb2e9b06SClemens Zeidlerint32
177bb2e9b06SClemens ZeidlerDecorator::TabAt(const BPoint& where) const
178bb2e9b06SClemens Zeidler{
179bb2e9b06SClemens Zeidler	for (int32 i = 0; i < fTabList.CountItems(); i++) {
180bb2e9b06SClemens Zeidler		Decorator::Tab* tab = fTabList.ItemAt(i);
181bb2e9b06SClemens Zeidler		if (tab->tabRect.Contains(where))
182bb2e9b06SClemens Zeidler			return i;
183bb2e9b06SClemens Zeidler	}
184bb2e9b06SClemens Zeidler
185bb2e9b06SClemens Zeidler	return -1;
186bb2e9b06SClemens Zeidler}
187bb2e9b06SClemens Zeidler
188bb2e9b06SClemens Zeidler
189bb2e9b06SClemens Zeidlervoid
19003b82a62SRene GollentDecorator::SetTopTab(int32 tab)
191bb2e9b06SClemens Zeidler{
192bb2e9b06SClemens Zeidler	fTopTab = fTabList.ItemAt(tab);
193bb2e9b06SClemens Zeidler}
194bb2e9b06SClemens Zeidler
195bb2e9b06SClemens Zeidler
1963a83c7b1SAxel Dörfler/*!	\brief Assigns a display driver to the decorator
19758468dfeSStephan Aßmus	\param driver A valid DrawingEngine object
198a3d04b0eSDarkWyrm*/
19959345e26SStephan Aßmusvoid
2002cfe93e7SStephan AßmusDecorator::SetDrawingEngine(DrawingEngine* engine)
201a3d04b0eSDarkWyrm{
2022cfe93e7SStephan Aßmus	fDrawingEngine = engine;
203a3d04b0eSDarkWyrm	// lots of subclasses will depend on the driver for text support, so call
20459345e26SStephan Aßmus	// _DoLayout() after we have it
205cfe0652aSJohn Scipione	if (fDrawingEngine != NULL)
20659345e26SStephan Aßmus		_DoLayout();
207a3d04b0eSDarkWyrm}
208a3d04b0eSDarkWyrm
20985f8bb71SAxel Dörfler
2103a83c7b1SAxel Dörfler/*!	\brief Sets the decorator's window flags
211a3d04b0eSDarkWyrm
212a3d04b0eSDarkWyrm	While this call will not update the screen, it will affect how future
213a3d04b0eSDarkWyrm	updates work and immediately affects input handling.
2143a83c7b1SAxel Dörfler
2153a83c7b1SAxel Dörfler	\param flags New value for the flags
216a3d04b0eSDarkWyrm*/
21759345e26SStephan Aßmusvoid
2181c141573SClemens ZeidlerDecorator::SetFlags(int32 tab, uint32 flags, BRegion* updateRegion)
219a3d04b0eSDarkWyrm{
2203a83c7b1SAxel Dörfler	// we're nice to our subclasses - we make sure B_NOT_{H|V|}_RESIZABLE
2213a83c7b1SAxel Dörfler	// are in sync (it's only a semantical simplification, not a necessity)
222fc21e33eSAxel Dörfler	if ((flags & (B_NOT_H_RESIZABLE | B_NOT_V_RESIZABLE))
223fc21e33eSAxel Dörfler			== (B_NOT_H_RESIZABLE | B_NOT_V_RESIZABLE))
224fc21e33eSAxel Dörfler		flags |= B_NOT_RESIZABLE;
225fc21e33eSAxel Dörfler	if (flags & B_NOT_RESIZABLE)
226fc21e33eSAxel Dörfler		flags |= B_NOT_H_RESIZABLE | B_NOT_V_RESIZABLE;
227fc21e33eSAxel Dörfler
2281c141573SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
2291c141573SClemens Zeidler	if (decoratorTab == NULL)
2301c141573SClemens Zeidler		return;
2311c141573SClemens Zeidler	_SetFlags(decoratorTab, flags, updateRegion);
232962281e8SClemens Zeidler	_InvalidateFootprint();
233962281e8SClemens Zeidler		// the border might have changed (smaller/larger tab)
234a3d04b0eSDarkWyrm}
235a3d04b0eSDarkWyrm
23685f8bb71SAxel Dörfler
2370a3f410fSAxel Dörfler/*!	\brief Called whenever the system fonts are changed.
2382a8283e4SDarkWyrm*/
23959345e26SStephan Aßmusvoid
2400a3f410fSAxel DörflerDecorator::FontsChanged(DesktopSettings& settings, BRegion* updateRegion)
2412a8283e4SDarkWyrm{
2427f9368caSlooncraz
24309301a49SClemens Zeidler	_FontsChanged(settings, updateRegion);
244962281e8SClemens Zeidler	_InvalidateFootprint();
2452a8283e4SDarkWyrm}
2462a8283e4SDarkWyrm
24785f8bb71SAxel Dörfler
2487f9368caSlooncraz/*!	\brief Called when a system colors change.
2497f9368caSlooncraz*/
2507f9368caSlooncrazvoid
2517f9368caSlooncrazDecorator::ColorsChanged(DesktopSettings& settings, BRegion* updateRegion)
2527f9368caSlooncraz{
2537f9368caSlooncraz	UpdateColors(settings);
2547f9368caSlooncraz
2557f9368caSlooncraz	if (updateRegion != NULL)
2567f9368caSlooncraz		updateRegion->Include(&GetFootprint());
2577f9368caSlooncraz
2587f9368caSlooncraz	_InvalidateBitmaps();
2597f9368caSlooncraz}
2607f9368caSlooncraz
2617f9368caSlooncraz
2623a83c7b1SAxel Dörfler/*!	\brief Sets the decorator's window look
26385f8bb71SAxel Dörfler	\param look New value for the look
264a3d04b0eSDarkWyrm*/
26559345e26SStephan Aßmusvoid
2661c141573SClemens ZeidlerDecorator::SetLook(int32 tab, DesktopSettings& settings, window_look look,
26785f8bb71SAxel Dörfler	BRegion* updateRect)
268a3d04b0eSDarkWyrm{
2691c141573SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
2701c141573SClemens Zeidler	if (decoratorTab == NULL)
2711c141573SClemens Zeidler		return;
2727f9368caSlooncraz
2731c141573SClemens Zeidler	_SetLook(decoratorTab, settings, look, updateRect);
274962281e8SClemens Zeidler	_InvalidateFootprint();
275962281e8SClemens Zeidler		// the border very likely changed
276a3d04b0eSDarkWyrm}
277a3d04b0eSDarkWyrm
27885f8bb71SAxel Dörfler
279bb2e9b06SClemens Zeidler/*!	\brief Returns the decorator's window look
280bb2e9b06SClemens Zeidler	\return the decorator's window look
281bb2e9b06SClemens Zeidler*/
282bb2e9b06SClemens Zeidlerwindow_look
2831c141573SClemens ZeidlerDecorator::Look(int32 tab) const
284bb2e9b06SClemens Zeidler{
2851c141573SClemens Zeidler	return TabAt(tab)->look;
286bb2e9b06SClemens Zeidler}
287bb2e9b06SClemens Zeidler
288bb2e9b06SClemens Zeidler
289bb2e9b06SClemens Zeidler/*!	\brief Returns the decorator's window flags
290bb2e9b06SClemens Zeidler	\return the decorator's window flags
291bb2e9b06SClemens Zeidler*/
292bb2e9b06SClemens Zeidleruint32
2931c141573SClemens ZeidlerDecorator::Flags(int32 tab) const
294bb2e9b06SClemens Zeidler{
2951c141573SClemens Zeidler	return TabAt(tab)->flags;
296bb2e9b06SClemens Zeidler}
297bb2e9b06SClemens Zeidler
298bb2e9b06SClemens Zeidler
299bb2e9b06SClemens Zeidler/*!	\brief Returns the decorator's border rectangle
300bb2e9b06SClemens Zeidler	\return the decorator's border rectangle
301bb2e9b06SClemens Zeidler*/
302bb2e9b06SClemens ZeidlerBRect
303bb2e9b06SClemens ZeidlerDecorator::BorderRect() const
304bb2e9b06SClemens Zeidler{
305bb2e9b06SClemens Zeidler	return fBorderRect;
306bb2e9b06SClemens Zeidler}
307bb2e9b06SClemens Zeidler
308bb2e9b06SClemens Zeidler
309bb2e9b06SClemens ZeidlerBRect
310bb2e9b06SClemens ZeidlerDecorator::TitleBarRect() const
311bb2e9b06SClemens Zeidler{
312bb2e9b06SClemens Zeidler	return fTitleBarRect;
313bb2e9b06SClemens Zeidler}
314bb2e9b06SClemens Zeidler
315bb2e9b06SClemens Zeidler
316bb2e9b06SClemens Zeidler/*!	\brief Returns the decorator's tab rectangle
317bb2e9b06SClemens Zeidler	\return the decorator's tab rectangle
318bb2e9b06SClemens Zeidler*/
319bb2e9b06SClemens ZeidlerBRect
320bb2e9b06SClemens ZeidlerDecorator::TabRect(int32 tab) const
321bb2e9b06SClemens Zeidler{
322bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
323bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
324bb2e9b06SClemens Zeidler		return BRect();
325bb2e9b06SClemens Zeidler	return decoratorTab->tabRect;
326bb2e9b06SClemens Zeidler}
327bb2e9b06SClemens Zeidler
328bb2e9b06SClemens Zeidler
329bb2e9b06SClemens ZeidlerBRect
330bb2e9b06SClemens ZeidlerDecorator::TabRect(Decorator::Tab* tab) const
331bb2e9b06SClemens Zeidler{
332bb2e9b06SClemens Zeidler	return tab->tabRect;
333bb2e9b06SClemens Zeidler}
334bb2e9b06SClemens Zeidler
335bb2e9b06SClemens Zeidler
3363a83c7b1SAxel Dörfler/*!	\brief Sets the close button's value.
3370a3f410fSAxel Dörfler
33859345e26SStephan Aßmus	Note that this does not update the button's look - it just updates the
33959345e26SStephan Aßmus	internal button value
3403a83c7b1SAxel Dörfler
34145b17fdeSJohn Scipione	\param tab The tab index
34245b17fdeSJohn Scipione	\param pressed Whether the button is down or not
343a3d04b0eSDarkWyrm*/
34459345e26SStephan Aßmusvoid
345bb2e9b06SClemens ZeidlerDecorator::SetClose(int32 tab, bool pressed)
346a3d04b0eSDarkWyrm{
347bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
348bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
349bb2e9b06SClemens Zeidler		return;
350bb2e9b06SClemens Zeidler
351bb2e9b06SClemens Zeidler	if (pressed != decoratorTab->closePressed) {
352bb2e9b06SClemens Zeidler		decoratorTab->closePressed = pressed;
353bb2e9b06SClemens Zeidler		DrawClose(tab);
35459345e26SStephan Aßmus	}
355a3d04b0eSDarkWyrm}
356a3d04b0eSDarkWyrm
35745b17fdeSJohn Scipione
3583a83c7b1SAxel Dörfler/*!	\brief Sets the minimize button's value.
3590a3f410fSAxel Dörfler
36059345e26SStephan Aßmus	Note that this does not update the button's look - it just updates the
36159345e26SStephan Aßmus	internal button value
3623a83c7b1SAxel Dörfler
3633a83c7b1SAxel Dörfler	\param is_down Whether the button is down or not
364a3d04b0eSDarkWyrm*/
36559345e26SStephan Aßmusvoid
366bb2e9b06SClemens ZeidlerDecorator::SetMinimize(int32 tab, bool pressed)
367a3d04b0eSDarkWyrm{
368bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
369bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
370bb2e9b06SClemens Zeidler		return;
371bb2e9b06SClemens Zeidler
372bb2e9b06SClemens Zeidler	if (pressed != decoratorTab->minimizePressed) {
373bb2e9b06SClemens Zeidler		decoratorTab->minimizePressed = pressed;
374bb2e9b06SClemens Zeidler		DrawMinimize(tab);
37559345e26SStephan Aßmus	}
376a3d04b0eSDarkWyrm}
377a3d04b0eSDarkWyrm
3783a83c7b1SAxel Dörfler/*!	\brief Sets the zoom button's value.
3790a3f410fSAxel Dörfler
38059345e26SStephan Aßmus	Note that this does not update the button's look - it just updates the
38159345e26SStephan Aßmus	internal button value
3823a83c7b1SAxel Dörfler
3833a83c7b1SAxel Dörfler	\param is_down Whether the button is down or not
384a3d04b0eSDarkWyrm*/
38559345e26SStephan Aßmusvoid
386bb2e9b06SClemens ZeidlerDecorator::SetZoom(int32 tab, bool pressed)
387a3d04b0eSDarkWyrm{
388bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
389bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
390bb2e9b06SClemens Zeidler		return;
391bb2e9b06SClemens Zeidler
392bb2e9b06SClemens Zeidler	if (pressed != decoratorTab->zoomPressed) {
393bb2e9b06SClemens Zeidler		decoratorTab->zoomPressed = pressed;
394bb2e9b06SClemens Zeidler		DrawZoom(tab);
39559345e26SStephan Aßmus	}
39659345e26SStephan Aßmus}
39759345e26SStephan Aßmus
398614de12dSAxel Dörfler
3993a83c7b1SAxel Dörfler/*!	\brief Updates the value of the decorator title
40059345e26SStephan Aßmus	\param string New title value
40159345e26SStephan Aßmus*/
40259345e26SStephan Aßmusvoid
403bb2e9b06SClemens ZeidlerDecorator::SetTitle(int32 tab, const char* string, BRegion* updateRegion)
40459345e26SStephan Aßmus{
405bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
406bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
407bb2e9b06SClemens Zeidler		return;
408bb2e9b06SClemens Zeidler
409bb2e9b06SClemens Zeidler	decoratorTab->title.SetTo(string);
410bb2e9b06SClemens Zeidler	_SetTitle(decoratorTab, string, updateRegion);
41109301a49SClemens Zeidler
412962281e8SClemens Zeidler	_InvalidateFootprint();
413962281e8SClemens Zeidler		// the border very likely changed
414962281e8SClemens Zeidler
41559345e26SStephan Aßmus	// TODO: redraw?
416a3d04b0eSDarkWyrm}
417a3d04b0eSDarkWyrm
418614de12dSAxel Dörfler
4193a83c7b1SAxel Dörfler/*!	\brief Returns the decorator's title
420a3d04b0eSDarkWyrm	\return the decorator's title
421a3d04b0eSDarkWyrm*/
42259345e26SStephan Aßmusconst char*
423bb2e9b06SClemens ZeidlerDecorator::Title(int32 tab) const
424a3d04b0eSDarkWyrm{
425bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
426bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
427bb2e9b06SClemens Zeidler		return "";
4286f99a609SJohn Scipione
429bb2e9b06SClemens Zeidler	return decoratorTab->title;
430a3d04b0eSDarkWyrm}
431a3d04b0eSDarkWyrm
43285f8bb71SAxel Dörfler
433bb2e9b06SClemens Zeidlerconst char*
434bb2e9b06SClemens ZeidlerDecorator::Title(Decorator::Tab* tab) const
43559345e26SStephan Aßmus{
436bb2e9b06SClemens Zeidler	return tab->title;
4377641924eSAdi Oanca}
4387641924eSAdi Oanca
43985f8bb71SAxel Dörfler
440cfe0652aSJohn Scipionefloat
441cfe0652aSJohn ScipioneDecorator::TabLocation(int32 tab) const
442cfe0652aSJohn Scipione{
443cfe0652aSJohn Scipione	Decorator::Tab* decoratorTab = _TabAt(tab);
444cfe0652aSJohn Scipione	if (decoratorTab == NULL)
445cfe0652aSJohn Scipione		return 0.0f;
446cfe0652aSJohn Scipione
447cfe0652aSJohn Scipione	return (float)decoratorTab->tabOffset;
448cfe0652aSJohn Scipione}
449cfe0652aSJohn Scipione
450cfe0652aSJohn Scipione
451bb2e9b06SClemens Zeidlerbool
452bb2e9b06SClemens ZeidlerDecorator::SetTabLocation(int32 tab, float location, bool isShifting,
453bb2e9b06SClemens Zeidler	BRegion* updateRegion)
45459345e26SStephan Aßmus{
455bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
456bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
457bb2e9b06SClemens Zeidler		return false;
458bb2e9b06SClemens Zeidler	if (_SetTabLocation(decoratorTab, location, isShifting, updateRegion)) {
459bb2e9b06SClemens Zeidler		_InvalidateFootprint();
460bb2e9b06SClemens Zeidler		return true;
461bb2e9b06SClemens Zeidler	}
462bb2e9b06SClemens Zeidler	return false;
4637641924eSAdi Oanca}
4647641924eSAdi Oanca
46503b82a62SRene Gollent
4663a83c7b1SAxel Dörfler
467bb2e9b06SClemens Zeidler/*!	\brief Changes the focus value of the decorator
468bb2e9b06SClemens Zeidler
469bb2e9b06SClemens Zeidler	While this call will not update the screen, it will affect how future
470bb2e9b06SClemens Zeidler	updates work.
471bb2e9b06SClemens Zeidler
472bb2e9b06SClemens Zeidler	\param active True if active, false if not
47359345e26SStephan Aßmus*/
474bb2e9b06SClemens Zeidlervoid
475bb2e9b06SClemens ZeidlerDecorator::SetFocus(int32 tab, bool active)
47659345e26SStephan Aßmus{
477bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
478bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
479bb2e9b06SClemens Zeidler		return;
480bb2e9b06SClemens Zeidler	decoratorTab->isFocused = active;
481bb2e9b06SClemens Zeidler	_SetFocus(decoratorTab);
482bb2e9b06SClemens Zeidler	// TODO: maybe it would be cleaner to handle the redraw here.
48359345e26SStephan Aßmus}
48459345e26SStephan Aßmus
4853a83c7b1SAxel Dörfler
48659345e26SStephan Aßmusbool
487bb2e9b06SClemens ZeidlerDecorator::IsFocus(int32 tab) const
48859345e26SStephan Aßmus{
489bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
490bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
491bb2e9b06SClemens Zeidler		return false;
49278a987ccSJohn Scipione
493bb2e9b06SClemens Zeidler	return decoratorTab->isFocused;
494bb2e9b06SClemens Zeidler};
49559345e26SStephan Aßmus
4963a83c7b1SAxel Dörfler
49759345e26SStephan Aßmusbool
498bb2e9b06SClemens ZeidlerDecorator::IsFocus(Decorator::Tab* tab) const
49959345e26SStephan Aßmus{
500bb2e9b06SClemens Zeidler	return tab->isFocused;
50159345e26SStephan Aßmus}
50259345e26SStephan Aßmus
5033a83c7b1SAxel Dörfler
5043a83c7b1SAxel Dörfler//	#pragma mark - virtual methods
5053a83c7b1SAxel Dörfler
5063a83c7b1SAxel Dörfler
50709301a49SClemens Zeidler/*!	\brief Returns a cached footprint if available otherwise recalculate it
508a3d04b0eSDarkWyrm*/
50909301a49SClemens Zeidlerconst BRegion&
51009301a49SClemens ZeidlerDecorator::GetFootprint()
511a3d04b0eSDarkWyrm{
51209301a49SClemens Zeidler	if (!fFootprintValid) {
51309301a49SClemens Zeidler		_GetFootprint(&fFootprint);
51409301a49SClemens Zeidler		fFootprintValid = true;
51509301a49SClemens Zeidler	}
51609301a49SClemens Zeidler	return fFootprint;
51759345e26SStephan Aßmus}
518247a9343SDarkWyrm
519247a9343SDarkWyrm
5207f9368caSlooncraz/*!	\brief Returns our Desktop object pointer
5217f9368caSlooncraz*/
5227f9368caSlooncraz::Desktop*
5237f9368caSlooncrazDecorator::GetDesktop()
5247f9368caSlooncraz{
5257f9368caSlooncraz	return fDesktop;
5267f9368caSlooncraz}
5277f9368caSlooncraz
5287f9368caSlooncraz
52989d652d5SIngo Weinhold/*!	\brief Performs hit-testing for the decorator.
53089d652d5SIngo Weinhold
53189d652d5SIngo Weinhold	The base class provides a basic implementation, recognizing only button and
53289d652d5SIngo Weinhold	tab hits. Derived classes must override/enhance it to handle borders and
53389d652d5SIngo Weinhold	corners correctly.
53489d652d5SIngo Weinhold
53589d652d5SIngo Weinhold	\param where The point to be tested.
53689d652d5SIngo Weinhold	\return Either of the following, depending on what was hit:
53789d652d5SIngo Weinhold		- \c REGION_NONE: None of the decorator regions.
53889d652d5SIngo Weinhold		- \c REGION_TAB: The window tab (but none of the buttons embedded).
53989d652d5SIngo Weinhold		- \c REGION_CLOSE_BUTTON: The close button.
54089d652d5SIngo Weinhold		- \c REGION_ZOOM_BUTTON: The zoom button.
54189d652d5SIngo Weinhold		- \c REGION_MINIMIZE_BUTTON: The minimize button.
54289d652d5SIngo Weinhold		- \c REGION_LEFT_BORDER: The left border.
54389d652d5SIngo Weinhold		- \c REGION_RIGHT_BORDER: The right border.
54489d652d5SIngo Weinhold		- \c REGION_TOP_BORDER: The top border.
54589d652d5SIngo Weinhold		- \c REGION_BOTTOM_BORDER: The bottom border.
54689d652d5SIngo Weinhold		- \c REGION_LEFT_TOP_CORNER: The left-top corner.
54789d652d5SIngo Weinhold		- \c REGION_LEFT_BOTTOM_CORNER: The left-bottom corner.
54889d652d5SIngo Weinhold		- \c REGION_RIGHT_TOP_CORNER: The right-top corner.
54989d652d5SIngo Weinhold		- \c REGION_RIGHT_BOTTOM_CORNER The right-bottom corner.
55059345e26SStephan Aßmus*/
55189d652d5SIngo WeinholdDecorator::Region
552bb2e9b06SClemens ZeidlerDecorator::RegionAt(BPoint where, int32& tabIndex) const
553bb2e9b06SClemens Zeidler{
554bb2e9b06SClemens Zeidler	tabIndex = -1;
555bb2e9b06SClemens Zeidler
556bb2e9b06SClemens Zeidler	for (int32 i = 0; i < fTabList.CountItems(); i++) {
557bb2e9b06SClemens Zeidler		Decorator::Tab* tab = fTabList.ItemAt(i);
558bb2e9b06SClemens Zeidler		if (tab->closeRect.Contains(where)) {
559bb2e9b06SClemens Zeidler			tabIndex = i;
560bb2e9b06SClemens Zeidler			return REGION_CLOSE_BUTTON;
561bb2e9b06SClemens Zeidler		}
562bb2e9b06SClemens Zeidler		if (tab->zoomRect.Contains(where)) {
563bb2e9b06SClemens Zeidler			tabIndex = i;
564bb2e9b06SClemens Zeidler			return REGION_ZOOM_BUTTON;
565bb2e9b06SClemens Zeidler		}
566bb2e9b06SClemens Zeidler		if (tab->tabRect.Contains(where)) {
567bb2e9b06SClemens Zeidler			tabIndex = i;
568bb2e9b06SClemens Zeidler			return REGION_TAB;
569bb2e9b06SClemens Zeidler		}
570bb2e9b06SClemens Zeidler	}
57189d652d5SIngo Weinhold
57289d652d5SIngo Weinhold	return REGION_NONE;
57359345e26SStephan Aßmus}
574a3d04b0eSDarkWyrm
5753a83c7b1SAxel Dörfler
5763a83c7b1SAxel Dörfler/*!	\brief Moves the decorator frame and all default rectangles
5770a3f410fSAxel Dörfler
578a3d04b0eSDarkWyrm	If a subclass implements this method, be sure to call Decorator::MoveBy
5793a83c7b1SAxel Dörfler	to ensure that internal members are also updated. All members of the
5803a83c7b1SAxel Dörfler	Decorator class are automatically moved in this method
5813a83c7b1SAxel Dörfler
5823a83c7b1SAxel Dörfler	\param x X Offset
5833a83c7b1SAxel Dörfler	\param y y Offset
584a3d04b0eSDarkWyrm*/
58559345e26SStephan Aßmusvoid
58659345e26SStephan AßmusDecorator::MoveBy(float x, float y)
587a3d04b0eSDarkWyrm{
588e067fed5SStephan Aßmus	MoveBy(BPoint(x, y));
589a3d04b0eSDarkWyrm}
590a3d04b0eSDarkWyrm
5913a83c7b1SAxel Dörfler
5923a83c7b1SAxel Dörfler/*!	\brief Moves the decorator frame and all default rectangles
5930a3f410fSAxel Dörfler
594a3d04b0eSDarkWyrm	If a subclass implements this method, be sure to call Decorator::MoveBy
5953a83c7b1SAxel Dörfler	to ensure that internal members are also updated. All members of the
5963a83c7b1SAxel Dörfler	Decorator class are automatically moved in this method
5973a83c7b1SAxel Dörfler
5983a83c7b1SAxel Dörfler	\param offset BPoint containing the offsets
599a3d04b0eSDarkWyrm*/
60059345e26SStephan Aßmusvoid
6013a83c7b1SAxel DörflerDecorator::MoveBy(BPoint offset)
602a3d04b0eSDarkWyrm{
60309301a49SClemens Zeidler	if (fFootprintValid)
60409301a49SClemens Zeidler		fFootprint.OffsetBy(offset.x, offset.y);
60509301a49SClemens Zeidler
60609301a49SClemens Zeidler	_MoveBy(offset);
607a3d04b0eSDarkWyrm}
608a3d04b0eSDarkWyrm
6093a83c7b1SAxel Dörfler
6103a83c7b1SAxel Dörfler/*!	\brief Resizes the decorator frame
6110a3f410fSAxel Dörfler
6123a83c7b1SAxel Dörfler	This is a required function for subclasses to implement - the default does
6133a83c7b1SAxel Dörfler	nothing. Note that window resize flags should be followed and fFrame should
6143a83c7b1SAxel Dörfler	be resized accordingly. It would also be a wise idea to ensure that the
6150a3f410fSAxel Dörfler	window's rectangles are not inverted.
6163a83c7b1SAxel Dörfler
6173a83c7b1SAxel Dörfler	\param x x offset
6183a83c7b1SAxel Dörfler	\param y y offset
619a3d04b0eSDarkWyrm*/
62059345e26SStephan Aßmusvoid
621e067fed5SStephan AßmusDecorator::ResizeBy(float x, float y, BRegion* dirty)
622a3d04b0eSDarkWyrm{
623e067fed5SStephan Aßmus	ResizeBy(BPoint(x, y), dirty);
624a3d04b0eSDarkWyrm}
625a3d04b0eSDarkWyrm
626b30e9021SStephan Aßmus
62709301a49SClemens Zeidlervoid
62809301a49SClemens ZeidlerDecorator::ResizeBy(BPoint offset, BRegion* dirty)
62909301a49SClemens Zeidler{
63009301a49SClemens Zeidler	_ResizeBy(offset, dirty);
631962281e8SClemens Zeidler	_InvalidateFootprint();
63209301a49SClemens Zeidler}
63309301a49SClemens Zeidler
63409301a49SClemens Zeidler
635cfe0652aSJohn Scipionevoid
636cfe0652aSJohn ScipioneDecorator::ExtendDirtyRegion(Region region, BRegion& dirty)
637cfe0652aSJohn Scipione{
638cfe0652aSJohn Scipione	switch (region) {
639cfe0652aSJohn Scipione		case REGION_TAB:
640cfe0652aSJohn Scipione			dirty.Include(fTitleBarRect);
641cfe0652aSJohn Scipione			break;
642cfe0652aSJohn Scipione
643cfe0652aSJohn Scipione		case REGION_CLOSE_BUTTON:
644cfe0652aSJohn Scipione			if ((fTopTab->flags & B_NOT_CLOSABLE) == 0) {
645cfe0652aSJohn Scipione				for (int32 i = 0; i < fTabList.CountItems(); i++)
646cfe0652aSJohn Scipione					dirty.Include(fTabList.ItemAt(i)->closeRect);
647cfe0652aSJohn Scipione			}
648cfe0652aSJohn Scipione			break;
649cfe0652aSJohn Scipione
650cfe0652aSJohn Scipione		case REGION_MINIMIZE_BUTTON:
651cfe0652aSJohn Scipione			if ((fTopTab->flags & B_NOT_MINIMIZABLE) == 0) {
652cfe0652aSJohn Scipione				for (int32 i = 0; i < fTabList.CountItems(); i++)
653cfe0652aSJohn Scipione					dirty.Include(fTabList.ItemAt(i)->minimizeRect);
654cfe0652aSJohn Scipione			}
655cfe0652aSJohn Scipione			break;
656cfe0652aSJohn Scipione
657cfe0652aSJohn Scipione		case REGION_ZOOM_BUTTON:
658cfe0652aSJohn Scipione			if ((fTopTab->flags & B_NOT_ZOOMABLE) == 0) {
659cfe0652aSJohn Scipione				for (int32 i = 0; i < fTabList.CountItems(); i++)
660cfe0652aSJohn Scipione					dirty.Include(fTabList.ItemAt(i)->zoomRect);
661cfe0652aSJohn Scipione			}
662cfe0652aSJohn Scipione			break;
663cfe0652aSJohn Scipione
664cfe0652aSJohn Scipione		case REGION_LEFT_BORDER:
665cfe0652aSJohn Scipione			if (fLeftBorder.IsValid()) {
666cfe0652aSJohn Scipione				// fLeftBorder doesn't include the corners, so we have to add
667cfe0652aSJohn Scipione				// them manually.
668cfe0652aSJohn Scipione				BRect rect(fLeftBorder);
669cfe0652aSJohn Scipione				rect.top = fTopBorder.top;
670cfe0652aSJohn Scipione				rect.bottom = fBottomBorder.bottom;
671cfe0652aSJohn Scipione				dirty.Include(rect);
672cfe0652aSJohn Scipione			}
673cfe0652aSJohn Scipione			break;
674cfe0652aSJohn Scipione
675cfe0652aSJohn Scipione		case REGION_RIGHT_BORDER:
676cfe0652aSJohn Scipione			if (fRightBorder.IsValid()) {
677cfe0652aSJohn Scipione				// fRightBorder doesn't include the corners, so we have to add
678cfe0652aSJohn Scipione				// them manually.
679cfe0652aSJohn Scipione				BRect rect(fRightBorder);
680cfe0652aSJohn Scipione				rect.top = fTopBorder.top;
681cfe0652aSJohn Scipione				rect.bottom = fBottomBorder.bottom;
682cfe0652aSJohn Scipione				dirty.Include(rect);
683cfe0652aSJohn Scipione			}
684cfe0652aSJohn Scipione			break;
685cfe0652aSJohn Scipione
686cfe0652aSJohn Scipione		case REGION_TOP_BORDER:
687cfe0652aSJohn Scipione			dirty.Include(fTopBorder);
688cfe0652aSJohn Scipione			break;
689cfe0652aSJohn Scipione
690cfe0652aSJohn Scipione		case REGION_BOTTOM_BORDER:
691cfe0652aSJohn Scipione			dirty.Include(fBottomBorder);
692cfe0652aSJohn Scipione			break;
693cfe0652aSJohn Scipione
694cfe0652aSJohn Scipione		case REGION_RIGHT_BOTTOM_CORNER:
695cfe0652aSJohn Scipione			if ((fTopTab->flags & B_NOT_RESIZABLE) == 0)
696cfe0652aSJohn Scipione				dirty.Include(fResizeRect);
697cfe0652aSJohn Scipione			break;
698cfe0652aSJohn Scipione
699cfe0652aSJohn Scipione		default:
700cfe0652aSJohn Scipione			break;
701cfe0652aSJohn Scipione	}
702cfe0652aSJohn Scipione}
703cfe0652aSJohn Scipione
704cfe0652aSJohn Scipione
7052b602c73SIngo Weinhold/*!	\brief Sets a specific highlight for a decorator region.
7062b602c73SIngo Weinhold
7072b602c73SIngo Weinhold	Can be overridden by derived classes, but the base class version must be
7082b602c73SIngo Weinhold	called, if the highlight shall be applied.
7092b602c73SIngo Weinhold
7102b602c73SIngo Weinhold	\param region The decorator region.
7112b602c73SIngo Weinhold	\param highlight The value identifying the kind of highlight.
7122b602c73SIngo Weinhold	\param dirty The dirty region to be extended, if the highlight changes. Can
7132b602c73SIngo Weinhold		be \c NULL.
7142b602c73SIngo Weinhold	\return \c true, if the highlight could be applied.
7152b602c73SIngo Weinhold*/
7162b602c73SIngo Weinholdbool
717bb2e9b06SClemens ZeidlerDecorator::SetRegionHighlight(Region region, uint8 highlight, BRegion* dirty,
718bb2e9b06SClemens Zeidler	int32 tab)
7192b602c73SIngo Weinhold{
7202b602c73SIngo Weinhold	int32 index = (int32)region - 1;
7212b602c73SIngo Weinhold	if (index < 0 || index >= REGION_COUNT - 1)
7222b602c73SIngo Weinhold		return false;
7232b602c73SIngo Weinhold
724a54ffcd2SClemens Zeidler	if (fRegionHighlights[index] == highlight)
725a54ffcd2SClemens Zeidler		return true;
7262b602c73SIngo Weinhold	fRegionHighlights[index] = highlight;
7272b602c73SIngo Weinhold
7282b602c73SIngo Weinhold	if (dirty != NULL)
7292b602c73SIngo Weinhold		ExtendDirtyRegion(region, *dirty);
7302b602c73SIngo Weinhold
7312b602c73SIngo Weinhold	return true;
7322b602c73SIngo Weinhold}
7332b602c73SIngo Weinhold
7342b602c73SIngo Weinhold
735b30e9021SStephan Aßmusbool
736b30e9021SStephan AßmusDecorator::SetSettings(const BMessage& settings, BRegion* updateRegion)
737b30e9021SStephan Aßmus{
73809301a49SClemens Zeidler	if (_SetSettings(settings, updateRegion)) {
739962281e8SClemens Zeidler		_InvalidateFootprint();
74009301a49SClemens Zeidler		return true;
74109301a49SClemens Zeidler	}
742b30e9021SStephan Aßmus	return false;
743b30e9021SStephan Aßmus}
744b30e9021SStephan Aßmus
745b30e9021SStephan Aßmus
746b30e9021SStephan Aßmusbool
747b30e9021SStephan AßmusDecorator::GetSettings(BMessage* settings) const
748b30e9021SStephan Aßmus{
749cfe0652aSJohn Scipione	if (!fTitleBarRect.IsValid())
750cfe0652aSJohn Scipione		return false;
751b30e9021SStephan Aßmus
752cfe0652aSJohn Scipione	if (settings->AddRect("tab frame", fTitleBarRect) != B_OK)
753cfe0652aSJohn Scipione		return false;
754b30e9021SStephan Aßmus
755cfe0652aSJohn Scipione	if (settings->AddFloat("border width", fBorderWidth) != B_OK)
756cfe0652aSJohn Scipione		return false;
7573a83c7b1SAxel Dörfler
758cfe0652aSJohn Scipione	// TODO only add the location of the tab of the window who requested the
759cfe0652aSJohn Scipione	// settings
760cfe0652aSJohn Scipione	for (int32 i = 0; i < fTabList.CountItems(); i++) {
761cfe0652aSJohn Scipione		Decorator::Tab* tab = _TabAt(i);
762cfe0652aSJohn Scipione		if (settings->AddFloat("tab location", (float)tab->tabOffset) != B_OK)
763cfe0652aSJohn Scipione			return false;
764cfe0652aSJohn Scipione	}
7653a83c7b1SAxel Dörfler
766cfe0652aSJohn Scipione	return true;
767a3d04b0eSDarkWyrm}
768a3d04b0eSDarkWyrm
7693a83c7b1SAxel Dörfler
77059345e26SStephan Aßmusvoid
771cfe0652aSJohn ScipioneDecorator::GetSizeLimits(int32* minWidth, int32* minHeight,
772cfe0652aSJohn Scipione	int32* maxWidth, int32* maxHeight) const
773a3d04b0eSDarkWyrm{
774cfe0652aSJohn Scipione	float minTabSize = 0;
775cfe0652aSJohn Scipione	if (CountTabs() > 0)
776cfe0652aSJohn Scipione		minTabSize = _TabAt(0)->minTabSize;
7773a83c7b1SAxel Dörfler
778cfe0652aSJohn Scipione	if (fTitleBarRect.IsValid()) {
779cfe0652aSJohn Scipione		*minWidth = (int32)roundf(max_c(*minWidth,
780cfe0652aSJohn Scipione			minTabSize - 2 * fBorderWidth));
781cfe0652aSJohn Scipione	}
782cfe0652aSJohn Scipione	if (fResizeRect.IsValid()) {
783cfe0652aSJohn Scipione		*minHeight = (int32)roundf(max_c(*minHeight,
784cfe0652aSJohn Scipione			fResizeRect.Height() - fBorderWidth));
785cfe0652aSJohn Scipione	}
786a3d04b0eSDarkWyrm}
787a3d04b0eSDarkWyrm
7883a83c7b1SAxel Dörfler
789bb2e9b06SClemens Zeidler//! draws the tab, title, and buttons
79059345e26SStephan Aßmusvoid
791bb2e9b06SClemens ZeidlerDecorator::DrawTab(int32 tabIndex)
792a3d04b0eSDarkWyrm{
793bb2e9b06SClemens Zeidler	Decorator::Tab* tab = fTabList.ItemAt(tabIndex);
794bb2e9b06SClemens Zeidler	if (tab == NULL)
795bb2e9b06SClemens Zeidler		return;
796bb2e9b06SClemens Zeidler
797bb2e9b06SClemens Zeidler	_DrawTab(tab, tab->tabRect);
79886b01082SClemens Zeidler	_DrawZoom(tab, false, tab->zoomRect);
79986b01082SClemens Zeidler	_DrawMinimize(tab, false, tab->minimizeRect);
800bb2e9b06SClemens Zeidler	_DrawTitle(tab, tab->tabRect);
80186b01082SClemens Zeidler	_DrawClose(tab, false, tab->closeRect);
802a3d04b0eSDarkWyrm}
803a3d04b0eSDarkWyrm
8043a83c7b1SAxel Dörfler
805cfe0652aSJohn Scipione//! draws the title
80659345e26SStephan Aßmusvoid
807cfe0652aSJohn ScipioneDecorator::DrawTitle(int32 tab)
808a3d04b0eSDarkWyrm{
809bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
810bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
811bb2e9b06SClemens Zeidler		return;
812cfe0652aSJohn Scipione	_DrawTitle(decoratorTab, decoratorTab->tabRect);
813a3d04b0eSDarkWyrm}
814a3d04b0eSDarkWyrm
8153a83c7b1SAxel Dörfler
816cfe0652aSJohn Scipione//! Draws the close button
81759345e26SStephan Aßmusvoid
818cfe0652aSJohn ScipioneDecorator::DrawClose(int32 tab)
819a3d04b0eSDarkWyrm{
820bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
821bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
822bb2e9b06SClemens Zeidler		return;
823106fe8b3SJohn Scipione
824cfe0652aSJohn Scipione	_DrawClose(decoratorTab, true, decoratorTab->closeRect);
825a3d04b0eSDarkWyrm}
826a3d04b0eSDarkWyrm
8273a83c7b1SAxel Dörfler
828cfe0652aSJohn Scipione//! draws the minimize button
82959345e26SStephan Aßmusvoid
830cfe0652aSJohn ScipioneDecorator::DrawMinimize(int32 tab)
831a3d04b0eSDarkWyrm{
832bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
833bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
834bb2e9b06SClemens Zeidler		return;
835cfe0652aSJohn Scipione
836cfe0652aSJohn Scipione	_DrawTab(decoratorTab, decoratorTab->minimizeRect);
837a3d04b0eSDarkWyrm}
838a3d04b0eSDarkWyrm
8393a83c7b1SAxel Dörfler
840a3d04b0eSDarkWyrm//! draws the zoom button
84159345e26SStephan Aßmusvoid
842bb2e9b06SClemens ZeidlerDecorator::DrawZoom(int32 tab)
843a3d04b0eSDarkWyrm{
844bb2e9b06SClemens Zeidler	Decorator::Tab* decoratorTab = fTabList.ItemAt(tab);
845bb2e9b06SClemens Zeidler	if (decoratorTab == NULL)
846bb2e9b06SClemens Zeidler		return;
84786b01082SClemens Zeidler	_DrawZoom(decoratorTab, true, decoratorTab->zoomRect);
848a3d04b0eSDarkWyrm}
849a3d04b0eSDarkWyrm
85023ae77aaSAxel Dörfler
851f7e1df75SStephan Aßmusrgb_color
85223ae77aaSAxel DörflerDecorator::UIColor(color_which which)
85323ae77aaSAxel Dörfler{
8547f9368caSlooncraz	DesktopSettings settings(fDesktop);
8557f9368caSlooncraz	return settings.UIColor(which);
85623ae77aaSAxel Dörfler}
85723ae77aaSAxel Dörfler
85823ae77aaSAxel Dörfler
859cfe0652aSJohn Scipionefloat
860cfe0652aSJohn ScipioneDecorator::BorderWidth()
8612b602c73SIngo Weinhold{
862cfe0652aSJohn Scipione	return fBorderWidth;
8632b602c73SIngo Weinhold}
8642b602c73SIngo Weinhold
8652b602c73SIngo Weinhold
866cfe0652aSJohn Scipionefloat
867cfe0652aSJohn ScipioneDecorator::TabHeight()
868a3d04b0eSDarkWyrm{
869cfe0652aSJohn Scipione	if (fTitleBarRect.IsValid())
870cfe0652aSJohn Scipione		return fTitleBarRect.Height();
871cfe0652aSJohn Scipione
872cfe0652aSJohn Scipione	return fBorderWidth;
873a3d04b0eSDarkWyrm}
874a3d04b0eSDarkWyrm
8753a83c7b1SAxel Dörfler
876cfe0652aSJohn Scipione// #pragma mark - Protected methods
877cfe0652aSJohn Scipione
878cfe0652aSJohn Scipione
879cfe0652aSJohn ScipioneDecorator::Tab*
880cfe0652aSJohn ScipioneDecorator::_AllocateNewTab()
881a3d04b0eSDarkWyrm{
882cfe0652aSJohn Scipione	Decorator::Tab* tab = new(std::nothrow) Decorator::Tab;
883cfe0652aSJohn Scipione	if (tab == NULL)
884cfe0652aSJohn Scipione		return NULL;
885cfe0652aSJohn Scipione
886cfe0652aSJohn Scipione	// Set appropriate colors based on the current focus value. In this case,
887cfe0652aSJohn Scipione	// each decorator defaults to not having the focus.
888cfe0652aSJohn Scipione	_SetFocus(tab);
889cfe0652aSJohn Scipione	return tab;
890a3d04b0eSDarkWyrm}
891a3d04b0eSDarkWyrm
8923a83c7b1SAxel Dörfler
893bb2e9b06SClemens Zeidlervoid
894bb2e9b06SClemens ZeidlerDecorator::_DrawTabs(BRect rect)
895bb2e9b06SClemens Zeidler{
896bb2e9b06SClemens Zeidler	Decorator::Tab* focusTab = NULL;
897bb2e9b06SClemens Zeidler	for (int32 i = 0; i < fTabList.CountItems(); i++) {
898bb2e9b06SClemens Zeidler		Decorator::Tab* tab = fTabList.ItemAt(i);
899bb2e9b06SClemens Zeidler		if (tab->isFocused) {
900bb2e9b06SClemens Zeidler			focusTab = tab;
901bb2e9b06SClemens Zeidler			continue;
902bb2e9b06SClemens Zeidler		}
903bb2e9b06SClemens Zeidler		_DrawTab(tab, rect);
904bb2e9b06SClemens Zeidler	}
905cfe0652aSJohn Scipione
906bb2e9b06SClemens Zeidler	if (focusTab != NULL)
907bb2e9b06SClemens Zeidler		_DrawTab(focusTab, rect);
908bb2e9b06SClemens Zeidler}
909bb2e9b06SClemens Zeidler
910bb2e9b06SClemens Zeidler
911cfe0652aSJohn Scipione//! Hook function called when the decorator changes focus
91259345e26SStephan Aßmusvoid
913cfe0652aSJohn ScipioneDecorator::_SetFocus(Decorator::Tab* tab)
914bb2e9b06SClemens Zeidler{
915bb2e9b06SClemens Zeidler}
916bb2e9b06SClemens Zeidler
917bb2e9b06SClemens Zeidler
918bb2e9b06SClemens Zeidlerbool
919bb2e9b06SClemens ZeidlerDecorator::_SetTabLocation(Decorator::Tab* tab, float location, bool isShifting,
920bb2e9b06SClemens Zeidler	BRegion* /*updateRegion*/)
921dae7413eSDarkWyrm{
922bb2e9b06SClemens Zeidler	return false;
923dae7413eSDarkWyrm}
924dae7413eSDarkWyrm
9253a83c7b1SAxel Dörfler
926cfe0652aSJohn ScipioneDecorator::Tab*
927cfe0652aSJohn ScipioneDecorator::_TabAt(int32 index) const
928a3d04b0eSDarkWyrm{
929cfe0652aSJohn Scipione	return static_cast<Decorator::Tab*>(fTabList.ItemAt(index));
930a3d04b0eSDarkWyrm}
93109301a49SClemens Zeidler
93209301a49SClemens Zeidler
93309301a49SClemens Zeidlervoid
93409301a49SClemens ZeidlerDecorator::_FontsChanged(DesktopSettings& settings, BRegion* updateRegion)
93509301a49SClemens Zeidler{
936cfe0652aSJohn Scipione	// get previous extent
937cfe0652aSJohn Scipione	if (updateRegion != NULL)
938cfe0652aSJohn Scipione		updateRegion->Include(&GetFootprint());
939cfe0652aSJohn Scipione
940cfe0652aSJohn Scipione	_InvalidateBitmaps();
941cfe0652aSJohn Scipione
942cfe0652aSJohn Scipione	_UpdateFont(settings);
943cfe0652aSJohn Scipione	_DoLayout();
944cfe0652aSJohn Scipione
945cfe0652aSJohn Scipione	_InvalidateFootprint();
946cfe0652aSJohn Scipione	if (updateRegion != NULL)
947cfe0652aSJohn Scipione		updateRegion->Include(&GetFootprint());
94809301a49SClemens Zeidler}
94909301a49SClemens Zeidler
95009301a49SClemens Zeidler
95109301a49SClemens Zeidlervoid
9521c141573SClemens ZeidlerDecorator::_SetLook(Decorator::Tab* tab, DesktopSettings& settings,
953cfe0652aSJohn Scipione	window_look look, BRegion* updateRegion)
95409301a49SClemens Zeidler{
955cfe0652aSJohn Scipione	// TODO: we could be much smarter about the update region
956cfe0652aSJohn Scipione
957cfe0652aSJohn Scipione	// get previous extent
958cfe0652aSJohn Scipione	if (updateRegion != NULL)
959cfe0652aSJohn Scipione		updateRegion->Include(&GetFootprint());
960cfe0652aSJohn Scipione
9611c141573SClemens Zeidler	tab->look = look;
962cfe0652aSJohn Scipione
963cfe0652aSJohn Scipione	_UpdateFont(settings);
964cfe0652aSJohn Scipione	_DoLayout();
965cfe0652aSJohn Scipione
966cfe0652aSJohn Scipione	_InvalidateFootprint();
967cfe0652aSJohn Scipione	if (updateRegion != NULL)
968cfe0652aSJohn Scipione		updateRegion->Include(&GetFootprint());
96909301a49SClemens Zeidler}
97009301a49SClemens Zeidler
97109301a49SClemens Zeidler
97209301a49SClemens Zeidlervoid
9731c141573SClemens ZeidlerDecorator::_SetFlags(Decorator::Tab* tab, uint32 flags, BRegion* updateRegion)
97409301a49SClemens Zeidler{
975cfe0652aSJohn Scipione	// TODO: we could be much smarter about the update region
976cfe0652aSJohn Scipione
977cfe0652aSJohn Scipione	// get previous extent
978cfe0652aSJohn Scipione	if (updateRegion != NULL)
979cfe0652aSJohn Scipione		updateRegion->Include(&GetFootprint());
980cfe0652aSJohn Scipione
9811c141573SClemens Zeidler	tab->flags = flags;
982cfe0652aSJohn Scipione	_DoLayout();
983cfe0652aSJohn Scipione
984cfe0652aSJohn Scipione	_InvalidateFootprint();
985cfe0652aSJohn Scipione	if (updateRegion != NULL)
986cfe0652aSJohn Scipione		updateRegion->Include(&GetFootprint());
98709301a49SClemens Zeidler}
98809301a49SClemens Zeidler
98909301a49SClemens Zeidler
99009301a49SClemens Zeidlervoid
99109301a49SClemens ZeidlerDecorator::_MoveBy(BPoint offset)
99209301a49SClemens Zeidler{
993bb2e9b06SClemens Zeidler	for (int32 i = 0; i < fTabList.CountItems(); i++) {
994bb2e9b06SClemens Zeidler		Decorator::Tab* tab = fTabList.ItemAt(i);
995bb2e9b06SClemens Zeidler
996bb2e9b06SClemens Zeidler		tab->zoomRect.OffsetBy(offset);
997bb2e9b06SClemens Zeidler		tab->closeRect.OffsetBy(offset);
998bb2e9b06SClemens Zeidler		tab->minimizeRect.OffsetBy(offset);
999bb2e9b06SClemens Zeidler		tab->tabRect.OffsetBy(offset);
1000bb2e9b06SClemens Zeidler	}
1001bb2e9b06SClemens Zeidler	fTitleBarRect.OffsetBy(offset);
100209301a49SClemens Zeidler	fFrame.OffsetBy(offset);
100309301a49SClemens Zeidler	fResizeRect.OffsetBy(offset);
100409301a49SClemens Zeidler	fBorderRect.OffsetBy(offset);
100509301a49SClemens Zeidler}
100609301a49SClemens Zeidler
100709301a49SClemens Zeidler
100809301a49SClemens Zeidlerbool
100909301a49SClemens ZeidlerDecorator::_SetSettings(const BMessage& settings, BRegion* updateRegion)
101009301a49SClemens Zeidler{
101109301a49SClemens Zeidler	return false;
101209301a49SClemens Zeidler}
101309301a49SClemens Zeidler
101409301a49SClemens Zeidler
101509301a49SClemens Zeidler/*!	\brief Returns the "footprint" of the entire window, including decorator
101609301a49SClemens Zeidler
101709301a49SClemens Zeidler	This function is required by all subclasses.
101809301a49SClemens Zeidler
101909301a49SClemens Zeidler	\param region Region to be changed to represent the window's screen
102009301a49SClemens Zeidler		footprint
102109301a49SClemens Zeidler*/
102209301a49SClemens Zeidlervoid
102309301a49SClemens ZeidlerDecorator::_GetFootprint(BRegion *region)
102409301a49SClemens Zeidler{
102509301a49SClemens Zeidler}
1026962281e8SClemens Zeidler
1027962281e8SClemens Zeidler
1028962281e8SClemens Zeidlervoid
1029962281e8SClemens ZeidlerDecorator::_InvalidateFootprint()
1030962281e8SClemens Zeidler{
1031962281e8SClemens Zeidler	fFootprintValid = false;
1032962281e8SClemens Zeidler}
1033cfe0652aSJohn Scipione
1034cfe0652aSJohn Scipione
1035cfe0652aSJohn Scipionevoid
1036cfe0652aSJohn ScipioneDecorator::_InvalidateBitmaps()
1037cfe0652aSJohn Scipione{
1038cfe0652aSJohn Scipione	for (int32 i = 0; i < fTabList.CountItems(); i++) {
1039cfe0652aSJohn Scipione		Decorator::Tab* tab = static_cast<Decorator::Tab*>(_TabAt(i));
1040cfe0652aSJohn Scipione		for (int32 index = 0; index < 4; index++) {
1041cfe0652aSJohn Scipione			tab->closeBitmaps[index] = NULL;
1042cfe0652aSJohn Scipione			tab->minimizeBitmaps[index] = NULL;
1043cfe0652aSJohn Scipione			tab->zoomBitmaps[index] = NULL;
1044cfe0652aSJohn Scipione		}
1045cfe0652aSJohn Scipione	}
1046cfe0652aSJohn Scipione}
1047