xref: /haiku/src/kits/interface/ControlLook.cpp (revision a5a3b2d9a3d95cbae71eaf371708c73a1780ac0d)
1 /*
2  * Copyright 2009, Stephan Aßmus <superstippi@gmx.de>
3  * Copyright 2012-2015 Haiku, Inc. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  *
6  * Authors:
7  *		Stephan Aßmus, superstippi@gmx.de
8  *		John Scipione, jscipione@gmail.com
9  */
10 
11 
12 #include <ControlLook.h>
13 
14 #include <algorithm>
15 
16 #include <Control.h>
17 #include <GradientLinear.h>
18 #include <LayoutUtils.h>
19 #include <Region.h>
20 #include <Shape.h>
21 #include <String.h>
22 #include <View.h>
23 #include <Window.h>
24 
25 #include "ContainerWindow.h"
26 
27 
28 namespace BPrivate {
29 
30 
31 static const float kEdgeBevelLightTint = 0.59;
32 static const float kEdgeBevelShadowTint = 1.0735;
33 static const float kHoverTintFactor = 0.85;
34 
35 static const float kButtonPopUpIndicatorWidth = 11;
36 
37 
38 BControlLook::BControlLook():
39 	fCachedOutline(false),
40 	fCachedWorkspace(-1)
41 {
42 }
43 
44 
45 BControlLook::~BControlLook()
46 {
47 }
48 
49 
50 BAlignment
51 BControlLook::DefaultLabelAlignment() const
52 {
53 	return BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER);
54 }
55 
56 
57 float
58 BControlLook::DefaultLabelSpacing() const
59 {
60 	return ceilf(be_plain_font->Size() / 2.0);
61 }
62 
63 
64 float
65 BControlLook::DefaultItemSpacing() const
66 {
67 	return ceilf(be_plain_font->Size() * 0.85);
68 }
69 
70 
71 float
72 BControlLook::ComposeSpacing(float spacing)
73 {
74 	switch ((int)spacing) {
75 		case B_USE_DEFAULT_SPACING:
76 		case B_USE_ITEM_SPACING:
77 			return be_control_look->DefaultItemSpacing();
78 		case B_USE_HALF_ITEM_SPACING:
79 			return ceilf(be_control_look->DefaultItemSpacing() * 0.5f);
80 		case B_USE_WINDOW_SPACING:
81 			return be_control_look->DefaultItemSpacing();
82 		case B_USE_SMALL_SPACING:
83 			return ceilf(be_control_look->DefaultItemSpacing() * 0.7f);
84 		case B_USE_BIG_SPACING:
85 			return ceilf(be_control_look->DefaultItemSpacing() * 1.3f);
86 	}
87 
88 	return spacing;
89 }
90 
91 
92 uint32
93 BControlLook::Flags(BControl* control) const
94 {
95 	uint32 flags = B_IS_CONTROL;
96 
97 	if (!control->IsEnabled())
98 		flags |= B_DISABLED;
99 
100 	if (control->IsFocus() && control->Window() != NULL
101 		&& control->Window()->IsActive()) {
102 		flags |= B_FOCUSED;
103 	}
104 
105 	switch (control->Value()) {
106 		case B_CONTROL_ON:
107 			flags |= B_ACTIVATED;
108 			break;
109 		case B_CONTROL_PARTIALLY_ON:
110 			flags |= B_PARTIALLY_ACTIVATED;
111 			break;
112 	}
113 
114 	if (control->Parent() != NULL
115 		&& (control->Parent()->Flags() & B_DRAW_ON_CHILDREN) != 0) {
116 		// In this constellation, assume we want to render the control
117 		// against the already existing view contents of the parent view.
118 		flags |= B_BLEND_FRAME;
119 	}
120 
121 	return flags;
122 }
123 
124 
125 // #pragma mark -
126 
127 
128 void
129 BControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect,
130 	const rgb_color& base, const rgb_color& background, uint32 flags,
131 	uint32 borders)
132 {
133 	_DrawButtonFrame(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, base,
134 		background, 1.0, 1.0, flags, borders);
135 }
136 
137 
138 void
139 BControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect,
140 	float radius, const rgb_color& base, const rgb_color& background, uint32 flags,
141 	uint32 borders)
142 {
143 	_DrawButtonFrame(view, rect, updateRect, radius, radius, radius, radius,
144 		base, background, 1.0, 1.0, flags, borders);
145 }
146 
147 
148 void
149 BControlLook::DrawButtonFrame(BView* view, BRect& rect,
150 	const BRect& updateRect, float leftTopRadius, float rightTopRadius,
151 	float leftBottomRadius, float rightBottomRadius, const rgb_color& base,
152 	const rgb_color& background, uint32 flags,
153 	uint32 borders)
154 {
155 	_DrawButtonFrame(view, rect, updateRect, leftTopRadius, rightTopRadius,
156 		leftBottomRadius, rightBottomRadius, base, background,
157 		1.0, 1.0, flags, borders);
158 }
159 
160 
161 void
162 BControlLook::DrawButtonBackground(BView* view, BRect& rect,
163 	const BRect& updateRect, const rgb_color& base, uint32 flags,
164 	uint32 borders, orientation orientation)
165 {
166 	_DrawButtonBackground(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f,
167 		base, false, flags, borders, orientation);
168 }
169 
170 
171 void
172 BControlLook::DrawButtonBackground(BView* view, BRect& rect,
173 	const BRect& updateRect, float radius, const rgb_color& base, uint32 flags,
174 	uint32 borders, orientation orientation)
175 {
176 	_DrawButtonBackground(view, rect, updateRect, radius, radius, radius,
177 		radius, base, false, flags, borders, orientation);
178 }
179 
180 
181 void
182 BControlLook::DrawButtonBackground(BView* view, BRect& rect,
183 	const BRect& updateRect, float leftTopRadius, float rightTopRadius,
184 	float leftBottomRadius, float rightBottomRadius, const rgb_color& base,
185 	uint32 flags, uint32 borders, orientation orientation)
186 {
187 	_DrawButtonBackground(view, rect, updateRect, leftTopRadius,
188 		rightTopRadius, leftBottomRadius, rightBottomRadius, base, false, flags,
189 		borders, orientation);
190 }
191 
192 
193 void
194 BControlLook::DrawMenuBarBackground(BView* view, BRect& rect,
195 	const BRect& updateRect, const rgb_color& base, uint32 flags,
196 	uint32 borders)
197 {
198 	if (!rect.IsValid() || !rect.Intersects(updateRect))
199 		return;
200 
201 	// the surface edges
202 
203 	// colors
204 	float topTint;
205 	float bottomTint;
206 
207 	if ((flags & B_ACTIVATED) != 0) {
208 		rgb_color bevelColor1 = tint_color(base, 1.40);
209 		rgb_color bevelColor2 = tint_color(base, 1.25);
210 
211 		topTint = 1.25;
212 		bottomTint = 1.20;
213 
214 		_DrawFrame(view, rect,
215 			bevelColor1, bevelColor1,
216 			bevelColor2, bevelColor2,
217 			borders & B_TOP_BORDER);
218 	} else {
219 		rgb_color cornerColor = tint_color(base, 0.9);
220 		rgb_color bevelColorTop = tint_color(base, 0.5);
221 		rgb_color bevelColorLeft = tint_color(base, 0.7);
222 		rgb_color bevelColorRightBottom = tint_color(base, 1.08);
223 
224 		topTint = 0.69;
225 		bottomTint = 1.03;
226 
227 		_DrawFrame(view, rect,
228 			bevelColorLeft, bevelColorTop,
229 			bevelColorRightBottom, bevelColorRightBottom,
230 			cornerColor, cornerColor,
231 			borders);
232 	}
233 
234 	// draw surface top
235 	_FillGradient(view, rect, base, topTint, bottomTint);
236 }
237 
238 
239 void
240 BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect,
241 	const BRect& updateRect, const rgb_color& base,
242 	const rgb_color& background, uint32 flags, uint32 borders)
243 {
244 	_DrawButtonFrame(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, base,
245 		background, 0.6, 1.0, flags, borders);
246 }
247 
248 
249 void
250 BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect,
251 	const BRect& updateRect, float radius, const rgb_color& base,
252 	const rgb_color& background, uint32 flags, uint32 borders)
253 {
254 	_DrawButtonFrame(view, rect, updateRect, radius, radius, radius, radius,
255 		base, background, 0.6, 1.0, flags, borders);
256 }
257 
258 
259 void
260 BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect,
261 	const BRect& updateRect, float leftTopRadius,
262 	float rightTopRadius, float leftBottomRadius,
263 	float rightBottomRadius, const rgb_color& base,
264 	const rgb_color& background, uint32 flags, uint32 borders)
265 {
266 	_DrawButtonFrame(view, rect, updateRect, leftTopRadius, rightTopRadius,
267 		leftBottomRadius, rightBottomRadius, base, background, 0.6, 1.0,
268 		flags, borders);
269 }
270 
271 
272 void
273 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect,
274 	const BRect& updateRect, const rgb_color& base, bool popupIndicator,
275 	uint32 flags)
276 {
277 	_DrawMenuFieldBackgroundOutside(view, rect, updateRect,
278 		0.0f, 0.0f, 0.0f, 0.0f, base, popupIndicator, flags);
279 }
280 
281 
282 void
283 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect,
284 	const BRect& updateRect, const rgb_color& base, uint32 flags,
285 	uint32 borders)
286 {
287 	_DrawMenuFieldBackgroundInside(view, rect, updateRect,
288 		0.0f, 0.0f, 0.0f, 0.0f, base, flags, borders);
289 }
290 
291 
292 void
293 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect,
294 	const BRect& updateRect, float radius, const rgb_color& base,
295 	bool popupIndicator, uint32 flags)
296 {
297 	_DrawMenuFieldBackgroundOutside(view, rect, updateRect, radius, radius,
298 		radius, radius, base, popupIndicator, flags);
299 }
300 
301 
302 void
303 BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect,
304 	const BRect& updateRect, float leftTopRadius, float rightTopRadius,
305 	float leftBottomRadius, float rightBottomRadius, const rgb_color& base,
306 	bool popupIndicator, uint32 flags)
307 {
308 	_DrawMenuFieldBackgroundOutside(view, rect, updateRect, leftTopRadius,
309 		rightTopRadius, leftBottomRadius, rightBottomRadius, base,
310 		popupIndicator, flags);
311 }
312 
313 
314 void
315 BControlLook::DrawMenuBackground(BView* view, BRect& rect,
316 	const BRect& updateRect, const rgb_color& base, uint32 flags,
317 	uint32 borders)
318 {
319 	if (!rect.IsValid() || !rect.Intersects(updateRect))
320 		return;
321 
322 	// surface top color
323 	rgb_color background = tint_color(base, 0.75);
324 
325 	// inner bevel colors
326 	rgb_color bevelLightColor;
327 	rgb_color bevelShadowColor;
328 
329 	if ((flags & B_DISABLED) != 0) {
330 		bevelLightColor = tint_color(background, 0.80);
331 		bevelShadowColor = tint_color(background, 1.07);
332 	} else {
333 		bevelLightColor = tint_color(background, 0.6);
334 		bevelShadowColor = tint_color(background, 1.12);
335 	}
336 
337 	// draw inner bevel
338 	_DrawFrame(view, rect,
339 		bevelLightColor, bevelLightColor,
340 		bevelShadowColor, bevelShadowColor,
341 		borders);
342 
343 	// draw surface top
344 	view->SetHighColor(background);
345 	view->FillRect(rect);
346 }
347 
348 
349 void
350 BControlLook::DrawMenuItemBackground(BView* view, BRect& rect,
351 	const BRect& updateRect, const rgb_color& base, uint32 flags,
352 	uint32 borders)
353 {
354 	if (!rect.IsValid() || !rect.Intersects(updateRect))
355 		return;
356 
357 	// surface edges
358 	float topTint;
359 	float bottomTint;
360 	rgb_color selectedColor = base;
361 
362 	if ((flags & B_ACTIVATED) != 0) {
363 		topTint = 0.9;
364 		bottomTint = 1.05;
365 	} else if ((flags & B_DISABLED) != 0) {
366 		topTint = 0.80;
367 		bottomTint = 1.07;
368 	} else {
369 		topTint = 0.6;
370 		bottomTint = 1.12;
371 	}
372 
373 	rgb_color bevelLightColor = tint_color(selectedColor, topTint);
374 	rgb_color bevelShadowColor = tint_color(selectedColor, bottomTint);
375 
376 	// draw surface edges
377 	_DrawFrame(view, rect,
378 		bevelLightColor, bevelLightColor,
379 		bevelShadowColor, bevelShadowColor,
380 		borders);
381 
382 	// draw surface top
383 	view->SetLowColor(selectedColor);
384 //	_FillGradient(view, rect, selectedColor, topTint, bottomTint);
385 	_FillGradient(view, rect, selectedColor, bottomTint, topTint);
386 }
387 
388 
389 void
390 BControlLook::DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect,
391 	const rgb_color& base, const rgb_color& barColor, float progressPosition)
392 {
393 	if (!rect.Intersects(updateRect))
394 		return;
395 
396 	_DrawOuterResessedFrame(view, rect, base, 0.6);
397 
398 	// colors
399 	rgb_color dark1BorderColor = tint_color(base, 1.3);
400 	rgb_color dark2BorderColor = tint_color(base, 1.2);
401 	rgb_color dark1FilledBorderColor = tint_color(barColor, 1.20);
402 	rgb_color dark2FilledBorderColor = tint_color(barColor, 1.45);
403 
404 	BRect filledRect(rect);
405 	filledRect.right = progressPosition - 1;
406 
407 	BRect nonfilledRect(rect);
408 	nonfilledRect.left = progressPosition;
409 
410 	bool filledSurface = filledRect.Width() > 0;
411 	bool nonfilledSurface = nonfilledRect.Width() > 0;
412 
413 	if (filledSurface) {
414 		_DrawFrame(view, filledRect,
415 			dark1FilledBorderColor, dark1FilledBorderColor,
416 			dark2FilledBorderColor, dark2FilledBorderColor);
417 
418 		_FillGlossyGradient(view, filledRect, barColor, 0.55, 0.68, 0.76, 0.90);
419 	}
420 
421 	if (nonfilledSurface) {
422 		_DrawFrame(view, nonfilledRect, dark1BorderColor, dark1BorderColor,
423 			dark2BorderColor, dark2BorderColor,
424 			B_TOP_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER);
425 
426 		if (nonfilledRect.left < nonfilledRect.right) {
427 			// shadow from fill bar, or left border
428 			rgb_color leftBorder = dark1BorderColor;
429 			if (filledSurface)
430 				leftBorder = tint_color(base, 0.50);
431 			view->SetHighColor(leftBorder);
432 			view->StrokeLine(nonfilledRect.LeftTop(),
433 				nonfilledRect.LeftBottom());
434 			nonfilledRect.left++;
435 		}
436 
437 		_FillGradient(view, nonfilledRect, base, 0.25, 0.06);
438 	}
439 }
440 
441 
442 void
443 BControlLook::DrawCheckBox(BView* view, BRect& rect, const BRect& updateRect,
444 	const rgb_color& base, uint32 flags)
445 {
446 	if (!rect.Intersects(updateRect))
447 		return;
448 
449 	rgb_color dark1BorderColor;
450 	rgb_color dark2BorderColor;
451 	rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
452 
453 	if ((flags & B_DISABLED) != 0) {
454 		_DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags);
455 
456 		dark1BorderColor = tint_color(base, 1.15);
457 		dark2BorderColor = tint_color(base, 1.15);
458 	} else if ((flags & B_CLICKED) != 0) {
459 		dark1BorderColor = tint_color(base, 1.50);
460 		dark2BorderColor = tint_color(base, 1.48);
461 
462 		_DrawFrame(view, rect,
463 			dark1BorderColor, dark1BorderColor,
464 			dark2BorderColor, dark2BorderColor);
465 
466 		dark2BorderColor = dark1BorderColor;
467 	} else {
468 		_DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags);
469 
470 		dark1BorderColor = tint_color(base, 1.40);
471 		dark2BorderColor = tint_color(base, 1.38);
472 	}
473 
474 	if ((flags & B_FOCUSED) != 0) {
475 		dark1BorderColor = navigationColor;
476 		dark2BorderColor = navigationColor;
477 	}
478 
479 	_DrawFrame(view, rect,
480 		dark1BorderColor, dark1BorderColor,
481 		dark2BorderColor, dark2BorderColor);
482 
483 	if ((flags & B_DISABLED) != 0)
484 		_FillGradient(view, rect, base, 0.4, 0.2);
485 	else
486 		_FillGradient(view, rect, base, 0.15, 0.0);
487 
488 	rgb_color markColor;
489 	if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) {
490 		view->SetHighColor(markColor);
491 
492 		BFont font;
493 		view->GetFont(&font);
494 		float inset = std::max(2.0f, roundf(font.Size() / 6));
495 		rect.InsetBy(inset, inset);
496 
497 		float penSize = std::max(1.0f, ceilf(rect.Width() / 3.5f));
498 		if (penSize > 1.0f && fmodf(penSize, 2.0f) == 0.0f) {
499 			// Tweak ends to "include" the pixel at the index,
500 			// we need to do this in order to produce results like R5,
501 			// where coordinates were inclusive
502 			rect.right++;
503 			rect.bottom++;
504 		}
505 
506 		view->SetPenSize(penSize);
507 		view->SetDrawingMode(B_OP_OVER);
508 		view->StrokeLine(rect.LeftTop(), rect.RightBottom());
509 		view->StrokeLine(rect.LeftBottom(), rect.RightTop());
510 	}
511 }
512 
513 
514 void
515 BControlLook::DrawRadioButton(BView* view, BRect& rect, const BRect& updateRect,
516 	const rgb_color& base, uint32 flags)
517 {
518 	if (!rect.Intersects(updateRect))
519 		return;
520 
521 	rgb_color borderColor;
522 	rgb_color bevelLight;
523 	rgb_color bevelShadow;
524 	rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
525 
526 	if ((flags & B_DISABLED) != 0) {
527 		borderColor = tint_color(base, 1.15);
528 		bevelLight = base;
529 		bevelShadow = base;
530 	} else if ((flags & B_CLICKED) != 0) {
531 		borderColor = tint_color(base, 1.50);
532 		bevelLight = borderColor;
533 		bevelShadow = borderColor;
534 	} else {
535 		borderColor = tint_color(base, 1.45);
536 		bevelLight = tint_color(base, 0.55);
537 		bevelShadow = tint_color(base, 1.11);
538 	}
539 
540 	if ((flags & B_FOCUSED) != 0) {
541 		borderColor = navigationColor;
542 	}
543 
544 	BGradientLinear bevelGradient;
545 	bevelGradient.AddColor(bevelShadow, 0);
546 	bevelGradient.AddColor(bevelLight, 255);
547 	bevelGradient.SetStart(rect.LeftTop());
548 	bevelGradient.SetEnd(rect.RightBottom());
549 
550 	view->FillEllipse(rect, bevelGradient);
551 	rect.InsetBy(1, 1);
552 
553 	bevelGradient.MakeEmpty();
554 	bevelGradient.AddColor(borderColor, 0);
555 	bevelGradient.AddColor(tint_color(borderColor, 0.8), 255);
556 	view->FillEllipse(rect, bevelGradient);
557 	rect.InsetBy(1, 1);
558 
559 	float topTint;
560 	float bottomTint;
561 	if ((flags & B_DISABLED) != 0) {
562 		topTint = 0.4;
563 		bottomTint = 0.2;
564 	} else {
565 		topTint = 0.15;
566 		bottomTint = 0.0;
567 	}
568 
569 	BGradientLinear gradient;
570 	_MakeGradient(gradient, rect, base, topTint, bottomTint);
571 	view->FillEllipse(rect, gradient);
572 
573 	rgb_color markColor;
574 	if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) {
575 		view->SetHighColor(markColor);
576 		BFont font;
577 		view->GetFont(&font);
578 		float inset = roundf(font.Size() / 4);
579 		rect.InsetBy(inset, inset);
580 		view->FillEllipse(rect);
581 	}
582 }
583 
584 
585 void
586 BControlLook::DrawScrollBarBackground(BView* view, BRect& rect1, BRect& rect2,
587 	const BRect& updateRect, const rgb_color& base, uint32 flags,
588 	orientation orientation)
589 {
590 	DrawScrollBarBackground(view, rect1, updateRect, base, flags, orientation);
591 	DrawScrollBarBackground(view, rect2, updateRect, base, flags, orientation);
592 }
593 
594 
595 void
596 BControlLook::DrawScrollBarBackground(BView* view, BRect& rect,
597 	const BRect& updateRect, const rgb_color& base, uint32 flags,
598 	orientation orientation)
599 {
600 	if (!rect.IsValid() || !rect.Intersects(updateRect))
601 		return;
602 
603 	float gradient1Tint;
604 	float gradient2Tint;
605 	float darkEdge1Tint;
606 	float darkEdge2Tint;
607 	float shadowTint;
608 
609 	if ((flags & B_DISABLED) != 0) {
610 		gradient1Tint = 0.9;
611 		gradient2Tint = 0.8;
612 		darkEdge1Tint = B_DARKEN_2_TINT;
613 		darkEdge2Tint = B_DARKEN_2_TINT;
614 		shadowTint = gradient1Tint;
615 	} else {
616 		gradient1Tint = 1.10;
617 		gradient2Tint = 1.05;
618 		darkEdge1Tint = B_DARKEN_3_TINT;
619 		darkEdge2Tint = B_DARKEN_2_TINT;
620 		shadowTint = gradient1Tint;
621 	}
622 
623 	rgb_color darkEdge1 = tint_color(base, darkEdge1Tint);
624 	rgb_color darkEdge2 = tint_color(base, darkEdge2Tint);
625 	rgb_color shadow = tint_color(base, shadowTint);
626 
627 	if (orientation == B_HORIZONTAL) {
628 		// dark vertical line on left edge
629 		if (rect.Width() > 0) {
630 			view->SetHighColor(darkEdge1);
631 			view->StrokeLine(rect.LeftTop(), rect.LeftBottom());
632 			rect.left++;
633 		}
634 		// dark vertical line on right edge
635 		if (rect.Width() >= 0) {
636 			view->SetHighColor(darkEdge2);
637 			view->StrokeLine(rect.RightTop(), rect.RightBottom());
638 			rect.right--;
639 		}
640 		// vertical shadow line after left edge
641 		if (rect.Width() >= 0) {
642 			view->SetHighColor(shadow);
643 			view->StrokeLine(rect.LeftTop(), rect.LeftBottom());
644 			rect.left++;
645 		}
646 		// fill
647 		if (rect.Width() >= 0) {
648 			_FillGradient(view, rect, base, gradient1Tint, gradient2Tint,
649 				orientation);
650 		}
651 	} else {
652 		// dark vertical line on top edge
653 		if (rect.Height() > 0) {
654 			view->SetHighColor(darkEdge1);
655 			view->StrokeLine(rect.LeftTop(), rect.RightTop());
656 			rect.top++;
657 		}
658 		// dark vertical line on bottom edge
659 		if (rect.Height() >= 0) {
660 			view->SetHighColor(darkEdge2);
661 			view->StrokeLine(rect.LeftBottom(), rect.RightBottom());
662 			rect.bottom--;
663 		}
664 		// horizontal shadow line after top edge
665 		if (rect.Height() >= 0) {
666 			view->SetHighColor(shadow);
667 			view->StrokeLine(rect.LeftTop(), rect.RightTop());
668 			rect.top++;
669 		}
670 		// fill
671 		if (rect.Height() >= 0) {
672 			_FillGradient(view, rect, base, gradient1Tint, gradient2Tint,
673 				orientation);
674 		}
675 	}
676 }
677 
678 
679 void
680 BControlLook::DrawScrollViewFrame(BView* view, BRect& rect,
681 	const BRect& updateRect, BRect verticalScrollBarFrame,
682 	BRect horizontalScrollBarFrame, const rgb_color& base,
683 	border_style border, uint32 flags, uint32 _borders)
684 {
685 	// calculate scroll corner rect before messing with the "rect"
686 	BRect scrollCornerFillRect(rect.right, rect.bottom,
687 		rect.right, rect.bottom);
688 
689 	if (horizontalScrollBarFrame.IsValid())
690 		scrollCornerFillRect.left = horizontalScrollBarFrame.right + 1;
691 
692 	if (verticalScrollBarFrame.IsValid())
693 		scrollCornerFillRect.top = verticalScrollBarFrame.bottom + 1;
694 
695 	if (border == B_NO_BORDER) {
696 		if (scrollCornerFillRect.IsValid()) {
697 			view->SetHighColor(base);
698 			view->FillRect(scrollCornerFillRect);
699 		}
700 		return;
701 	}
702 
703 	bool excludeScrollCorner = border == B_FANCY_BORDER
704 		&& horizontalScrollBarFrame.IsValid()
705 		&& verticalScrollBarFrame.IsValid();
706 
707 	uint32 borders = _borders;
708 	if (excludeScrollCorner) {
709 		rect.bottom = horizontalScrollBarFrame.top;
710 		rect.right = verticalScrollBarFrame.left;
711 		borders &= ~(B_RIGHT_BORDER | B_BOTTOM_BORDER);
712 	}
713 
714 	rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT);
715 
716 	if (border == B_FANCY_BORDER)
717 		_DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders);
718 
719 	if ((flags & B_FOCUSED) != 0) {
720 		rgb_color focusColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
721 		_DrawFrame(view, rect, focusColor, focusColor, focusColor, focusColor,
722 			borders);
723 	} else {
724 		_DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor,
725 			scrollbarFrameColor, scrollbarFrameColor, borders);
726 	}
727 
728 	if (excludeScrollCorner) {
729 		horizontalScrollBarFrame.InsetBy(-1, -1);
730 		// do not overdraw the top edge
731 		horizontalScrollBarFrame.top += 2;
732 		borders = _borders;
733 		borders &= ~B_TOP_BORDER;
734 		_DrawOuterResessedFrame(view, horizontalScrollBarFrame, base,
735 			1.0, 1.0, flags, borders);
736 		_DrawFrame(view, horizontalScrollBarFrame, scrollbarFrameColor,
737 			scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor,
738 			borders);
739 
740 		verticalScrollBarFrame.InsetBy(-1, -1);
741 		// do not overdraw the left edge
742 		verticalScrollBarFrame.left += 2;
743 		borders = _borders;
744 		borders &= ~B_LEFT_BORDER;
745 		_DrawOuterResessedFrame(view, verticalScrollBarFrame, base,
746 			1.0, 1.0, flags, borders);
747 		_DrawFrame(view, verticalScrollBarFrame, scrollbarFrameColor,
748 			scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor,
749 			borders);
750 
751 		// exclude recessed frame
752 		scrollCornerFillRect.top++;
753 		scrollCornerFillRect.left++;
754 	}
755 
756 	if (scrollCornerFillRect.IsValid()) {
757 		view->SetHighColor(base);
758 		view->FillRect(scrollCornerFillRect);
759 	}
760 }
761 
762 
763 void
764 BControlLook::DrawArrowShape(BView* view, BRect& rect, const BRect& updateRect,
765 	const rgb_color& base, uint32 direction, uint32 flags, float tint)
766 {
767 	BPoint tri1, tri2, tri3;
768 	float hInset = rect.Width() / 3;
769 	float vInset = rect.Height() / 3;
770 	rect.InsetBy(hInset, vInset);
771 
772 	switch (direction) {
773 		case B_LEFT_ARROW:
774 			tri1.Set(rect.right, rect.top);
775 			tri2.Set(rect.right - rect.Width() / 1.33,
776 				(rect.top + rect.bottom + 1) / 2);
777 			tri3.Set(rect.right, rect.bottom + 1);
778 			break;
779 		case B_RIGHT_ARROW:
780 			tri1.Set(rect.left + 1, rect.bottom + 1);
781 			tri2.Set(rect.left + 1 + rect.Width() / 1.33,
782 				(rect.top + rect.bottom + 1) / 2);
783 			tri3.Set(rect.left + 1, rect.top);
784 			break;
785 		case B_UP_ARROW:
786 			tri1.Set(rect.left, rect.bottom);
787 			tri2.Set((rect.left + rect.right + 1) / 2,
788 				rect.bottom - rect.Height() / 1.33);
789 			tri3.Set(rect.right + 1, rect.bottom);
790 			break;
791 		case B_DOWN_ARROW:
792 		default:
793 			tri1.Set(rect.left, rect.top + 1);
794 			tri2.Set((rect.left + rect.right + 1) / 2,
795 				rect.top + 1 + rect.Height() / 1.33);
796 			tri3.Set(rect.right + 1, rect.top + 1);
797 			break;
798 		case B_LEFT_UP_ARROW:
799 			tri1.Set(rect.left, rect.bottom);
800 			tri2.Set(rect.left, rect.top);
801 			tri3.Set(rect.right - 1, rect.top);
802 			break;
803 		case B_RIGHT_UP_ARROW:
804 			tri1.Set(rect.left + 1, rect.top);
805 			tri2.Set(rect.right, rect.top);
806 			tri3.Set(rect.right, rect.bottom);
807 			break;
808 		case B_RIGHT_DOWN_ARROW:
809 			tri1.Set(rect.right, rect.top);
810 			tri2.Set(rect.right, rect.bottom);
811 			tri3.Set(rect.left + 1, rect.bottom);
812 			break;
813 		case B_LEFT_DOWN_ARROW:
814 			tri1.Set(rect.right - 1, rect.bottom);
815 			tri2.Set(rect.left, rect.bottom);
816 			tri3.Set(rect.left, rect.top);
817 			break;
818 	}
819 
820 	BShape arrowShape;
821 	arrowShape.MoveTo(tri1);
822 	arrowShape.LineTo(tri2);
823 	arrowShape.LineTo(tri3);
824 
825 	if ((flags & B_DISABLED) != 0)
826 		tint = (tint + B_NO_TINT + B_NO_TINT) / 3;
827 
828 	view->SetHighColor(tint_color(base, tint));
829 
830 	float penSize = view->PenSize();
831 	drawing_mode mode = view->DrawingMode();
832 
833 	view->MovePenTo(BPoint(0, 0));
834 
835 	view->SetPenSize(ceilf(hInset / 2.0));
836 	view->SetDrawingMode(B_OP_OVER);
837 	view->StrokeShape(&arrowShape);
838 
839 	view->SetPenSize(penSize);
840 	view->SetDrawingMode(mode);
841 }
842 
843 
844 rgb_color
845 BControlLook::SliderBarColor(const rgb_color& base)
846 {
847 	return tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT);
848 }
849 
850 
851 void
852 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect,
853 	const rgb_color& base, rgb_color leftFillColor, rgb_color rightFillColor,
854 	float sliderScale, uint32 flags, orientation orientation)
855 {
856 	if (!rect.IsValid() || !rect.Intersects(updateRect))
857 		return;
858 
859 	// save the clipping constraints of the view
860 	view->PushState();
861 
862 	// separate the bar in two sides
863 	float sliderPosition;
864 	BRect leftBarSide = rect;
865 	BRect rightBarSide = rect;
866 
867 	if (orientation == B_HORIZONTAL) {
868 		sliderPosition = floorf(rect.left + 2 + (rect.Width() - 2)
869 			* sliderScale);
870 		leftBarSide.right = sliderPosition - 1;
871 		rightBarSide.left = sliderPosition;
872 	} else {
873 		// NOTE: position is reverse of coords
874 		sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2)
875 			* (1.0 - sliderScale));
876 		leftBarSide.top = sliderPosition;
877 		rightBarSide.bottom = sliderPosition - 1;
878 	}
879 
880 	// fill the background for the corners, exclude the middle bar for now
881 	BRegion region(rect);
882 	region.Exclude(rightBarSide);
883 	view->ConstrainClippingRegion(&region);
884 
885 	view->PushState();
886 
887 	DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags,
888 		orientation);
889 
890 	view->PopState();
891 
892 	region.Set(rect);
893 	region.Exclude(leftBarSide);
894 	view->ConstrainClippingRegion(&region);
895 
896 	view->PushState();
897 
898 	DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags,
899 		orientation);
900 
901 	view->PopState();
902 
903 	// restore the clipping constraints of the view
904 	view->PopState();
905 }
906 
907 
908 void
909 BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect,
910 	const rgb_color& base, rgb_color fillColor, uint32 flags,
911 	orientation orientation)
912 {
913 	if (!rect.IsValid() || !rect.Intersects(updateRect))
914 		return;
915 
916 	// separate the rect into corners
917 	BRect leftCorner(rect);
918 	BRect rightCorner(rect);
919 	BRect barRect(rect);
920 
921 	if (orientation == B_HORIZONTAL) {
922 		leftCorner.right = leftCorner.left + leftCorner.Height();
923 		rightCorner.left = rightCorner.right - rightCorner.Height();
924 		barRect.left += ceilf(barRect.Height() / 2);
925 		barRect.right -= ceilf(barRect.Height() / 2);
926 	} else {
927 		leftCorner.bottom = leftCorner.top + leftCorner.Width();
928 		rightCorner.top = rightCorner.bottom - rightCorner.Width();
929 		barRect.top += ceilf(barRect.Width() / 2);
930 		barRect.bottom -= ceilf(barRect.Width() / 2);
931 	}
932 
933 	// fill the background for the corners, exclude the middle bar for now
934 	BRegion region(rect);
935 	region.Exclude(barRect);
936 	view->ConstrainClippingRegion(&region);
937 
938 	if ((flags & B_BLEND_FRAME) == 0) {
939 		view->SetHighColor(base);
940 		view->FillRect(rect);
941 	}
942 
943 	// figure out the tints to be used
944 	float edgeLightTint;
945 	float edgeShadowTint;
946 	float frameLightTint;
947 	float frameShadowTint;
948 	float fillLightTint;
949 	float fillShadowTint;
950 	uint8 edgeLightAlpha;
951 	uint8 edgeShadowAlpha;
952 	uint8 frameLightAlpha;
953 	uint8 frameShadowAlpha;
954 
955 	if ((flags & B_DISABLED) != 0) {
956 		edgeLightTint = 1.0;
957 		edgeShadowTint = 1.0;
958 		frameLightTint = 1.20;
959 		frameShadowTint = 1.25;
960 		fillLightTint = 0.9;
961 		fillShadowTint = 1.05;
962 		edgeLightAlpha = 12;
963 		edgeShadowAlpha = 12;
964 		frameLightAlpha = 40;
965 		frameShadowAlpha = 45;
966 
967 		fillColor.red = uint8(fillColor.red * 0.4 + base.red * 0.6);
968 		fillColor.green = uint8(fillColor.green * 0.4 + base.green * 0.6);
969 		fillColor.blue = uint8(fillColor.blue * 0.4 + base.blue * 0.6);
970 	} else {
971 		edgeLightTint = 0.65;
972 		edgeShadowTint = 1.07;
973 		frameLightTint = 1.40;
974 		frameShadowTint = 1.50;
975 		fillLightTint = 0.8;
976 		fillShadowTint = 1.1;
977 		edgeLightAlpha = 15;
978 		edgeShadowAlpha = 15;
979 		frameLightAlpha = 92;
980 		frameShadowAlpha = 107;
981 	}
982 
983 	rgb_color edgeLightColor;
984 	rgb_color edgeShadowColor;
985 	rgb_color frameLightColor;
986 	rgb_color frameShadowColor;
987 	rgb_color fillLightColor = tint_color(fillColor, fillLightTint);
988 	rgb_color fillShadowColor = tint_color(fillColor, fillShadowTint);
989 
990 	drawing_mode oldMode = view->DrawingMode();
991 
992 	if ((flags & B_BLEND_FRAME) != 0) {
993 		edgeLightColor = (rgb_color){ 255, 255, 255, edgeLightAlpha };
994 		edgeShadowColor = (rgb_color){ 0, 0, 0, edgeShadowAlpha };
995 		frameLightColor = (rgb_color){ 0, 0, 0, frameLightAlpha };
996 		frameShadowColor = (rgb_color){ 0, 0, 0, frameShadowAlpha };
997 
998 		view->SetDrawingMode(B_OP_ALPHA);
999 	} else {
1000 		edgeLightColor = tint_color(base, edgeLightTint);
1001 		edgeShadowColor = tint_color(base, edgeShadowTint);
1002 		frameLightColor = tint_color(fillColor, frameLightTint);
1003 		frameShadowColor = tint_color(fillColor, frameShadowTint);
1004 	}
1005 
1006 	if (orientation == B_HORIZONTAL) {
1007 		_DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor,
1008 			edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor,
1009 			fillShadowColor, 1.0, 1.0, 0.0, -1.0, orientation);
1010 
1011 		_DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor,
1012 			edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor,
1013 			fillShadowColor, 0.0, 1.0, -1.0, -1.0, orientation);
1014 	} else {
1015 		_DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor,
1016 			edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor,
1017 			fillShadowColor, 1.0, 1.0, -1.0, 0.0, orientation);
1018 
1019 		_DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor,
1020 			edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor,
1021 			fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation);
1022 	}
1023 
1024 	view->ConstrainClippingRegion(NULL);
1025 
1026 	view->BeginLineArray(4);
1027 	if (orientation == B_HORIZONTAL) {
1028 		view->AddLine(barRect.LeftTop(), barRect.RightTop(), edgeShadowColor);
1029 		view->AddLine(barRect.LeftBottom(), barRect.RightBottom(),
1030 			edgeLightColor);
1031 		barRect.InsetBy(0, 1);
1032 		view->AddLine(barRect.LeftTop(), barRect.RightTop(), frameShadowColor);
1033 		view->AddLine(barRect.LeftBottom(), barRect.RightBottom(),
1034 			frameLightColor);
1035 		barRect.InsetBy(0, 1);
1036 	} else {
1037 		view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), edgeShadowColor);
1038 		view->AddLine(barRect.RightTop(), barRect.RightBottom(),
1039 			edgeLightColor);
1040 		barRect.InsetBy(1, 0);
1041 		view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), frameShadowColor);
1042 		view->AddLine(barRect.RightTop(), barRect.RightBottom(),
1043 			frameLightColor);
1044 		barRect.InsetBy(1, 0);
1045 	}
1046 	view->EndLineArray();
1047 
1048 	view->SetDrawingMode(oldMode);
1049 
1050 	_FillGradient(view, barRect, fillColor, fillShadowTint, fillLightTint,
1051 		orientation);
1052 }
1053 
1054 
1055 void
1056 BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect,
1057 	const rgb_color& base, uint32 flags, orientation orientation)
1058 {
1059 	if (!rect.IsValid() || !rect.Intersects(updateRect))
1060 		return;
1061 
1062 	// figure out frame color
1063 	rgb_color frameLightColor;
1064 	rgb_color frameShadowColor;
1065 	rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 };
1066 
1067 	if ((flags & B_FOCUSED) != 0) {
1068 		// focused
1069 		frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
1070 		frameShadowColor = frameLightColor;
1071 	} else {
1072 		// figure out the tints to be used
1073 		float frameLightTint;
1074 		float frameShadowTint;
1075 
1076 		if ((flags & B_DISABLED) != 0) {
1077 			frameLightTint = 1.30;
1078 			frameShadowTint = 1.35;
1079 			shadowColor.alpha = 30;
1080 		} else {
1081 			frameLightTint = 1.6;
1082 			frameShadowTint = 1.65;
1083 		}
1084 
1085 		frameLightColor = tint_color(base, frameLightTint);
1086 		frameShadowColor = tint_color(base, frameShadowTint);
1087 	}
1088 
1089 	BRect originalRect(rect);
1090 	rect.right--;
1091 	rect.bottom--;
1092 
1093 	_DrawFrame(view, rect, frameLightColor, frameLightColor,
1094 		frameShadowColor, frameShadowColor);
1095 
1096 	flags &= ~B_ACTIVATED;
1097 	DrawButtonBackground(view, rect, updateRect, base, flags);
1098 
1099 	// thumb shadow
1100 	view->SetDrawingMode(B_OP_ALPHA);
1101 	view->SetHighColor(shadowColor);
1102 	originalRect.left++;
1103 	originalRect.top++;
1104 	view->StrokeLine(originalRect.LeftBottom(), originalRect.RightBottom());
1105 	originalRect.bottom--;
1106 	view->StrokeLine(originalRect.RightTop(), originalRect.RightBottom());
1107 
1108 	// thumb edge
1109 	if (orientation == B_HORIZONTAL) {
1110 		rect.InsetBy(0, floorf(rect.Height() / 4));
1111 		rect.left = floorf((rect.left + rect.right) / 2);
1112 		rect.right = rect.left + 1;
1113 		shadowColor = tint_color(base, B_DARKEN_2_TINT);
1114 		shadowColor.alpha = 128;
1115 		view->SetHighColor(shadowColor);
1116 		view->StrokeLine(rect.LeftTop(), rect.LeftBottom());
1117 		rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT);
1118 		lightColor.alpha = 128;
1119 		view->SetHighColor(lightColor);
1120 		view->StrokeLine(rect.RightTop(), rect.RightBottom());
1121 	} else {
1122 		rect.InsetBy(floorf(rect.Width() / 4), 0);
1123 		rect.top = floorf((rect.top + rect.bottom) / 2);
1124 		rect.bottom = rect.top + 1;
1125 		shadowColor = tint_color(base, B_DARKEN_2_TINT);
1126 		shadowColor.alpha = 128;
1127 		view->SetHighColor(shadowColor);
1128 		view->StrokeLine(rect.LeftTop(), rect.RightTop());
1129 		rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT);
1130 		lightColor.alpha = 128;
1131 		view->SetHighColor(lightColor);
1132 		view->StrokeLine(rect.LeftBottom(), rect.RightBottom());
1133 	}
1134 
1135 	view->SetDrawingMode(B_OP_COPY);
1136 }
1137 
1138 
1139 void
1140 BControlLook::DrawSliderTriangle(BView* view, BRect& rect,
1141 	const BRect& updateRect, const rgb_color& base, uint32 flags,
1142 	orientation orientation)
1143 {
1144 	DrawSliderTriangle(view, rect, updateRect, base, base, flags, orientation);
1145 }
1146 
1147 
1148 void
1149 BControlLook::DrawSliderTriangle(BView* view, BRect& rect,
1150 	const BRect& updateRect, const rgb_color& base, const rgb_color& fill,
1151 	uint32 flags, orientation orientation)
1152 {
1153 	if (!rect.IsValid() || !rect.Intersects(updateRect))
1154 		return;
1155 
1156 	// figure out frame color
1157 	rgb_color frameLightColor;
1158 	rgb_color frameShadowColor;
1159 	rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 };
1160 
1161 	float topTint = 0.49;
1162 	float middleTint1 = 0.62;
1163 	float middleTint2 = 0.76;
1164 	float bottomTint = 0.90;
1165 
1166 	if ((flags & B_DISABLED) != 0) {
1167 		topTint = (topTint + B_NO_TINT) / 2;
1168 		middleTint1 = (middleTint1 + B_NO_TINT) / 2;
1169 		middleTint2 = (middleTint2 + B_NO_TINT) / 2;
1170 		bottomTint = (bottomTint + B_NO_TINT) / 2;
1171 	} else if ((flags & B_HOVER) != 0) {
1172 		topTint *= kHoverTintFactor;
1173 		middleTint1 *= kHoverTintFactor;
1174 		middleTint2 *= kHoverTintFactor;
1175 		bottomTint *= kHoverTintFactor;
1176 	}
1177 
1178 	if ((flags & B_FOCUSED) != 0) {
1179 		// focused
1180 		frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
1181 		frameShadowColor = frameLightColor;
1182 	} else {
1183 		// figure out the tints to be used
1184 		float frameLightTint;
1185 		float frameShadowTint;
1186 
1187 		if ((flags & B_DISABLED) != 0) {
1188 			frameLightTint = 1.30;
1189 			frameShadowTint = 1.35;
1190 			shadowColor.alpha = 30;
1191 		} else {
1192 			frameLightTint = 1.6;
1193 			frameShadowTint = 1.65;
1194 		}
1195 
1196 		frameLightColor = tint_color(base, frameLightTint);
1197 		frameShadowColor = tint_color(base, frameShadowTint);
1198 	}
1199 
1200 	// make room for the shadow
1201 	rect.right--;
1202 	rect.bottom--;
1203 
1204 	uint32 viewFlags = view->Flags();
1205 	view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE);
1206 	view->SetLineMode(B_ROUND_CAP, B_ROUND_JOIN);
1207 
1208 	float centerh = (rect.left + rect.right) / 2;
1209 	float centerv = (rect.top + rect.bottom) / 2;
1210 
1211 	BShape shape;
1212 	if (orientation == B_HORIZONTAL) {
1213 		shape.MoveTo(BPoint(rect.left + 0.5, rect.bottom + 0.5));
1214 		shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5));
1215 		shape.LineTo(BPoint(rect.right + 0.5, rect.bottom - 1 + 0.5));
1216 		shape.LineTo(BPoint(centerh + 0.5, rect.top + 0.5));
1217 		shape.LineTo(BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5));
1218 	} else {
1219 		shape.MoveTo(BPoint(rect.right + 0.5, rect.top + 0.5));
1220 		shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5));
1221 		shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.bottom + 0.5));
1222 		shape.LineTo(BPoint(rect.left + 0.5, centerv + 0.5));
1223 		shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.top + 0.5));
1224 	}
1225 	shape.Close();
1226 
1227 	view->MovePenTo(BPoint(1, 1));
1228 
1229 	view->SetDrawingMode(B_OP_ALPHA);
1230 	view->SetHighColor(shadowColor);
1231 	view->StrokeShape(&shape);
1232 
1233 	view->MovePenTo(B_ORIGIN);
1234 
1235 	view->SetDrawingMode(B_OP_COPY);
1236 	view->SetHighColor(frameLightColor);
1237 	view->StrokeShape(&shape);
1238 
1239 	rect.InsetBy(1, 1);
1240 	shape.Clear();
1241 	if (orientation == B_HORIZONTAL) {
1242 		shape.MoveTo(BPoint(rect.left, rect.bottom + 1));
1243 		shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1));
1244 		shape.LineTo(BPoint(centerh + 0.5, rect.top));
1245 	} else {
1246 		shape.MoveTo(BPoint(rect.right + 1, rect.top));
1247 		shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1));
1248 		shape.LineTo(BPoint(rect.left, centerv + 0.5));
1249 	}
1250 	shape.Close();
1251 
1252 	BGradientLinear gradient;
1253 	if ((flags & B_DISABLED) != 0) {
1254 		_MakeGradient(gradient, rect, fill, topTint, bottomTint);
1255 	} else {
1256 		_MakeGlossyGradient(gradient, rect, fill, topTint, middleTint1,
1257 			middleTint2, bottomTint);
1258 	}
1259 
1260 	view->FillShape(&shape, gradient);
1261 
1262 	view->SetFlags(viewFlags);
1263 }
1264 
1265 
1266 void
1267 BControlLook::DrawSliderHashMarks(BView* view, BRect& rect,
1268 	const BRect& updateRect, const rgb_color& base, int32 count,
1269 	hash_mark_location location, uint32 flags, orientation orientation)
1270 {
1271 	if (!rect.IsValid() || !rect.Intersects(updateRect))
1272 		return;
1273 
1274 	rgb_color lightColor;
1275 	rgb_color darkColor;
1276 
1277 	if ((flags & B_DISABLED) != 0) {
1278 		lightColor = tint_color(base, 0.9);
1279 		darkColor = tint_color(base, 1.07);
1280 	} else {
1281 		lightColor = tint_color(base, 0.8);
1282 		darkColor = tint_color(base, 1.14);
1283 	}
1284 
1285 	int32 hashMarkCount = std::max(count, (int32)2);
1286 		// draw at least two hashmarks at min/max if
1287 		// fHashMarks != B_HASH_MARKS_NONE
1288 	float factor;
1289 	float startPos;
1290 	if (orientation == B_HORIZONTAL) {
1291 		factor = (rect.Width() - 2) / (hashMarkCount - 1);
1292 		startPos = rect.left + 1;
1293 	} else {
1294 		factor = (rect.Height() - 2) / (hashMarkCount - 1);
1295 		startPos = rect.top + 1;
1296 	}
1297 
1298 	if (location & B_HASH_MARKS_TOP) {
1299 		view->BeginLineArray(hashMarkCount * 2);
1300 
1301 		if (orientation == B_HORIZONTAL) {
1302 			float pos = startPos;
1303 			for (int32 i = 0; i < hashMarkCount; i++) {
1304 				view->AddLine(BPoint(pos, rect.top),
1305 							  BPoint(pos, rect.top + 4), darkColor);
1306 				view->AddLine(BPoint(pos + 1, rect.top),
1307 							  BPoint(pos + 1, rect.top + 4), lightColor);
1308 
1309 				pos += factor;
1310 			}
1311 		} else {
1312 			float pos = startPos;
1313 			for (int32 i = 0; i < hashMarkCount; i++) {
1314 				view->AddLine(BPoint(rect.left, pos),
1315 							  BPoint(rect.left + 4, pos), darkColor);
1316 				view->AddLine(BPoint(rect.left, pos + 1),
1317 							  BPoint(rect.left + 4, pos + 1), lightColor);
1318 
1319 				pos += factor;
1320 			}
1321 		}
1322 
1323 		view->EndLineArray();
1324 	}
1325 
1326 	if ((location & B_HASH_MARKS_BOTTOM) != 0) {
1327 		view->BeginLineArray(hashMarkCount * 2);
1328 
1329 		if (orientation == B_HORIZONTAL) {
1330 			float pos = startPos;
1331 			for (int32 i = 0; i < hashMarkCount; i++) {
1332 				view->AddLine(BPoint(pos, rect.bottom - 4),
1333 							  BPoint(pos, rect.bottom), darkColor);
1334 				view->AddLine(BPoint(pos + 1, rect.bottom - 4),
1335 							  BPoint(pos + 1, rect.bottom), lightColor);
1336 
1337 				pos += factor;
1338 			}
1339 		} else {
1340 			float pos = startPos;
1341 			for (int32 i = 0; i < hashMarkCount; i++) {
1342 				view->AddLine(BPoint(rect.right - 4, pos),
1343 							  BPoint(rect.right, pos), darkColor);
1344 				view->AddLine(BPoint(rect.right - 4, pos + 1),
1345 							  BPoint(rect.right, pos + 1), lightColor);
1346 
1347 				pos += factor;
1348 			}
1349 		}
1350 
1351 		view->EndLineArray();
1352 	}
1353 }
1354 
1355 
1356 void
1357 BControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect,
1358 	const rgb_color& base, uint32 flags, uint32 borders)
1359 {
1360 	if (!rect.IsValid() || !rect.Intersects(updateRect))
1361 		return;
1362 
1363 	// Snap the rectangle to pixels to avoid rounding errors.
1364 	rect.left = floorf(rect.left);
1365 	rect.right = floorf(rect.right);
1366 	rect.top = floorf(rect.top);
1367 	rect.bottom = floorf(rect.bottom);
1368 
1369 	// save the clipping constraints of the view
1370 	view->PushState();
1371 
1372 	// set clipping constraints to updateRect
1373 	BRegion clipping(updateRect);
1374 	view->ConstrainClippingRegion(&clipping);
1375 
1376 	rgb_color edgeShadowColor;
1377 	rgb_color edgeLightColor;
1378 	rgb_color frameShadowColor;
1379 	rgb_color frameLightColor;
1380 	rgb_color bevelShadowColor;
1381 	rgb_color bevelLightColor;
1382 	BGradientLinear fillGradient;
1383 	fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3));
1384 	fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3));
1385 
1386 	if ((flags & B_DISABLED) != 0) {
1387 		edgeLightColor = base;
1388 		edgeShadowColor = base;
1389 		frameLightColor = tint_color(base, 1.25);
1390 		frameShadowColor = tint_color(base, 1.30);
1391 		bevelLightColor = tint_color(base, 0.8);
1392 		bevelShadowColor = tint_color(base, 1.07);
1393 		fillGradient.AddColor(tint_color(base, 0.85), 0);
1394 		fillGradient.AddColor(base, 255);
1395 	} else {
1396 		edgeLightColor = tint_color(base, 0.80);
1397 		edgeShadowColor = tint_color(base, 1.03);
1398 		frameLightColor = tint_color(base, 1.30);
1399 		frameShadowColor = tint_color(base, 1.30);
1400 		bevelLightColor = tint_color(base, 0.6);
1401 		bevelShadowColor = tint_color(base, 1.07);
1402 		fillGradient.AddColor(tint_color(base, 0.75), 0);
1403 		fillGradient.AddColor(tint_color(base, 1.03), 255);
1404 	}
1405 
1406 	static const float kRoundCornerRadius = 4.0f;
1407 
1408 	// left top corner dimensions
1409 	BRect leftTopCorner(rect);
1410 	leftTopCorner.right = floorf(leftTopCorner.left + kRoundCornerRadius);
1411 	leftTopCorner.bottom = floorf(rect.top + kRoundCornerRadius);
1412 	clipping.Exclude(leftTopCorner);
1413 
1414 	// draw the left top corner
1415 	_DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base,
1416 		edgeShadowColor, frameLightColor, bevelLightColor,
1417 		fillGradient);
1418 
1419 	// right top corner dimensions
1420 	BRect rightTopCorner(rect);
1421 	rightTopCorner.right = floorf(rect.right);
1422 	rightTopCorner.left = floorf(rightTopCorner.right - kRoundCornerRadius);
1423 	rightTopCorner.bottom = floorf(rect.top + kRoundCornerRadius);
1424 	clipping.Exclude(rightTopCorner);
1425 
1426 	// draw the right top corner
1427 	_DrawRoundCornerRightTop(view, rightTopCorner, updateRect, base,
1428 		edgeShadowColor, edgeLightColor, frameLightColor,
1429 		frameShadowColor, bevelLightColor, bevelShadowColor,
1430 		fillGradient);
1431 
1432 	// clip out the corners
1433 	view->ConstrainClippingRegion(&clipping);
1434 
1435 	// draw the rest of frame and fill
1436 	_DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor,
1437 		edgeLightColor,
1438 		borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER));
1439 	if ((borders & B_LEFT_BORDER) == 0)
1440 		rect.left++;
1441 	if ((borders & B_RIGHT_BORDER) == 0)
1442 		rect.right--;
1443 
1444 	_DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor,
1445 		frameShadowColor, B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER);
1446 
1447 	_DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor,
1448 		bevelShadowColor);
1449 
1450 	view->FillRect(rect, fillGradient);
1451 
1452 	// restore the clipping constraints of the view
1453 	view->PopState();
1454 }
1455 
1456 
1457 void
1458 BControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect,
1459 	const rgb_color& base, uint32 flags, uint32 borders)
1460 {
1461 	if (!rect.IsValid() || !rect.Intersects(updateRect))
1462 		return;
1463 
1464 	rgb_color edgeShadowColor;
1465 	rgb_color edgeLightColor;
1466 	rgb_color frameShadowColor;
1467 	rgb_color frameLightColor;
1468 	rgb_color bevelShadowColor;
1469 	rgb_color bevelLightColor;
1470 	BGradientLinear fillGradient;
1471 	fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3));
1472 	fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3));
1473 
1474 	if ((flags & B_DISABLED) != 0) {
1475 		edgeLightColor = base;
1476 		edgeShadowColor = base;
1477 		frameLightColor = tint_color(base, 1.25);
1478 		frameShadowColor = tint_color(base, 1.30);
1479 		bevelLightColor = tint_color(base, 0.8);
1480 		bevelShadowColor = tint_color(base, 1.07);
1481 		fillGradient.AddColor(tint_color(base, 0.85), 0);
1482 		fillGradient.AddColor(base, 255);
1483 	} else {
1484 		edgeLightColor = tint_color(base, 0.80);
1485 		edgeShadowColor = tint_color(base, 1.03);
1486 		frameLightColor = tint_color(base, 1.30);
1487 		frameShadowColor = tint_color(base, 1.30);
1488 		bevelLightColor = tint_color(base, 1.10);
1489 		bevelShadowColor = tint_color(base, 1.17);
1490 		fillGradient.AddColor(tint_color(base, 1.12), 0);
1491 		fillGradient.AddColor(tint_color(base, 1.08), 255);
1492 	}
1493 
1494 	// active tabs stand out at the top, but this is an inactive tab
1495 	view->SetHighColor(base);
1496 	view->FillRect(BRect(rect.left, rect.top, rect.right, rect.top + 4));
1497 	rect.top += 4;
1498 
1499 	// frame and fill
1500 	_DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor,
1501 		edgeLightColor,
1502 		borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER));
1503 
1504 	_DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor,
1505 		frameShadowColor,
1506 		borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER));
1507 
1508 	if (rect.IsValid()) {
1509 		_DrawFrame(view, rect, bevelShadowColor, bevelShadowColor,
1510 			bevelLightColor, bevelLightColor, B_LEFT_BORDER & ~borders);
1511 	} else {
1512 		if ((B_LEFT_BORDER & ~borders) != 0)
1513 			rect.left++;
1514 	}
1515 
1516 	view->FillRect(rect, fillGradient);
1517 }
1518 
1519 
1520 void
1521 BControlLook::DrawSplitter(BView* view, BRect& rect, const BRect& updateRect,
1522 	const rgb_color& base, orientation orientation, uint32 flags,
1523 	uint32 borders)
1524 {
1525 	if (!rect.IsValid() || !rect.Intersects(updateRect))
1526 		return;
1527 
1528 	rgb_color background;
1529 	if ((flags & (B_CLICKED | B_ACTIVATED)) != 0)
1530 		background = tint_color(base, B_DARKEN_1_TINT);
1531 	else
1532 		background = base;
1533 
1534 	rgb_color light = tint_color(background, 0.6);
1535 	rgb_color shadow = tint_color(background, 1.21);
1536 
1537 	// frame
1538 	if (borders != 0 && rect.Width() > 3 && rect.Height() > 3)
1539 		DrawRaisedBorder(view, rect, updateRect, background, flags, borders);
1540 
1541 	// dots and rest of background
1542 	if (orientation == B_HORIZONTAL) {
1543 		if (rect.Width() > 2) {
1544 			// background on left/right
1545 			BRegion region(rect);
1546 			rect.left = floorf((rect.left + rect.right) / 2.0 - 0.5);
1547 			rect.right = rect.left + 1;
1548 			region.Exclude(rect);
1549 			view->SetHighColor(background);
1550 			view->FillRegion(&region);
1551 		}
1552 
1553 		BPoint dot = rect.LeftTop();
1554 		BPoint stop = rect.LeftBottom();
1555 		int32 num = 1;
1556 		while (dot.y <= stop.y) {
1557 			rgb_color col1;
1558 			rgb_color col2;
1559 			switch (num) {
1560 				case 1:
1561 					col1 = background;
1562 					col2 = background;
1563 					break;
1564 				case 2:
1565 					col1 = shadow;
1566 					col2 = background;
1567 					break;
1568 				case 3:
1569 				default:
1570 					col1 = background;
1571 					col2 = light;
1572 					num = 0;
1573 					break;
1574 			}
1575 			view->SetHighColor(col1);
1576 			view->StrokeLine(dot, dot, B_SOLID_HIGH);
1577 			view->SetHighColor(col2);
1578 			dot.x++;
1579 			view->StrokeLine(dot, dot, B_SOLID_HIGH);
1580 			dot.x -= 1.0;
1581 			// next pixel
1582 			num++;
1583 			dot.y++;
1584 		}
1585 	} else {
1586 		if (rect.Height() > 2) {
1587 			// background on left/right
1588 			BRegion region(rect);
1589 			rect.top = floorf((rect.top + rect.bottom) / 2.0 - 0.5);
1590 			rect.bottom = rect.top + 1;
1591 			region.Exclude(rect);
1592 			view->SetHighColor(background);
1593 			view->FillRegion(&region);
1594 		}
1595 
1596 		BPoint dot = rect.LeftTop();
1597 		BPoint stop = rect.RightTop();
1598 		int32 num = 1;
1599 		while (dot.x <= stop.x) {
1600 			rgb_color col1;
1601 			rgb_color col2;
1602 			switch (num) {
1603 				case 1:
1604 					col1 = background;
1605 					col2 = background;
1606 					break;
1607 				case 2:
1608 					col1 = shadow;
1609 					col2 = background;
1610 					break;
1611 				case 3:
1612 				default:
1613 					col1 = background;
1614 					col2 = light;
1615 					num = 0;
1616 					break;
1617 			}
1618 			view->SetHighColor(col1);
1619 			view->StrokeLine(dot, dot, B_SOLID_HIGH);
1620 			view->SetHighColor(col2);
1621 			dot.y++;
1622 			view->StrokeLine(dot, dot, B_SOLID_HIGH);
1623 			dot.y -= 1.0;
1624 			// next pixel
1625 			num++;
1626 			dot.x++;
1627 		}
1628 	}
1629 }
1630 
1631 
1632 // #pragma mark -
1633 
1634 
1635 void
1636 BControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect,
1637 	const rgb_color& base, border_style border, uint32 flags, uint32 borders)
1638 {
1639 	if (border == B_NO_BORDER)
1640 		return;
1641 
1642 	rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT);
1643 	if ((flags & B_FOCUSED) != 0)
1644 		scrollbarFrameColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
1645 
1646 	if (border == B_FANCY_BORDER)
1647 		_DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders);
1648 
1649 	_DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor,
1650 		scrollbarFrameColor, scrollbarFrameColor, borders);
1651 }
1652 
1653 
1654 void
1655 BControlLook::DrawRaisedBorder(BView* view, BRect& rect,
1656 	const BRect& updateRect, const rgb_color& base, uint32 flags,
1657 	uint32 borders)
1658 {
1659 	rgb_color lightColor;
1660 	rgb_color shadowColor;
1661 
1662 	if ((flags & B_DISABLED) != 0) {
1663 		lightColor = base;
1664 		shadowColor = base;
1665 	} else {
1666 		lightColor = tint_color(base, 0.85);
1667 		shadowColor = tint_color(base, 1.07);
1668 	}
1669 
1670 	_DrawFrame(view, rect, lightColor, lightColor, shadowColor, shadowColor,
1671 		borders);
1672 }
1673 
1674 
1675 void
1676 BControlLook::DrawTextControlBorder(BView* view, BRect& rect,
1677 	const BRect& updateRect, const rgb_color& base, uint32 flags,
1678 	uint32 borders)
1679 {
1680 	if (!rect.Intersects(updateRect))
1681 		return;
1682 
1683 	rgb_color dark1BorderColor;
1684 	rgb_color dark2BorderColor;
1685 	rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
1686 	rgb_color invalidColor = ui_color(B_FAILURE_COLOR);
1687 
1688 	if ((flags & B_DISABLED) != 0) {
1689 		_DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags, borders);
1690 
1691 		if ((flags & B_BLEND_FRAME) != 0)
1692 			dark1BorderColor = (rgb_color){ 0, 0, 0, 40 };
1693 		else
1694 			dark1BorderColor = tint_color(base, 1.15);
1695 		dark2BorderColor = dark1BorderColor;
1696 	} else if ((flags & B_CLICKED) != 0) {
1697 		dark1BorderColor = tint_color(base, 1.50);
1698 		dark2BorderColor = tint_color(base, 1.49);
1699 
1700 		// BCheckBox uses this to indicate the clicked state...
1701 		_DrawFrame(view, rect,
1702 			dark1BorderColor, dark1BorderColor,
1703 			dark2BorderColor, dark2BorderColor);
1704 
1705 		dark2BorderColor = dark1BorderColor;
1706 	} else {
1707 		_DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags, borders);
1708 
1709 		if ((flags & B_BLEND_FRAME) != 0) {
1710 			dark1BorderColor = (rgb_color){ 0, 0, 0, 102 };
1711 			dark2BorderColor = (rgb_color){ 0, 0, 0, 97 };
1712 		} else {
1713 			dark1BorderColor = tint_color(base, 1.40);
1714 			dark2BorderColor = tint_color(base, 1.38);
1715 		}
1716 	}
1717 
1718 	if ((flags & B_DISABLED) == 0 && (flags & B_FOCUSED) != 0) {
1719 		dark1BorderColor = navigationColor;
1720 		dark2BorderColor = navigationColor;
1721 	}
1722 
1723 	if ((flags & B_DISABLED) == 0 && (flags & B_INVALID) != 0) {
1724 		dark1BorderColor = invalidColor;
1725 		dark2BorderColor = invalidColor;
1726 	}
1727 
1728 	if ((flags & B_BLEND_FRAME) != 0) {
1729 		drawing_mode oldMode = view->DrawingMode();
1730 		view->SetDrawingMode(B_OP_ALPHA);
1731 
1732 		_DrawFrame(view, rect,
1733 			dark1BorderColor, dark1BorderColor,
1734 			dark2BorderColor, dark2BorderColor, borders);
1735 
1736 		view->SetDrawingMode(oldMode);
1737 	} else {
1738 		_DrawFrame(view, rect,
1739 			dark1BorderColor, dark1BorderColor,
1740 			dark2BorderColor, dark2BorderColor, borders);
1741 	}
1742 }
1743 
1744 
1745 void
1746 BControlLook::DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect,
1747 	const rgb_color& base, uint32 borders)
1748 {
1749 	rgb_color frameColor = tint_color(base, 1.30);
1750 	rgb_color bevelLight = tint_color(base, 0.8);
1751 	rgb_color bevelShadow = tint_color(base, 1.03);
1752 
1753 	_DrawFrame(view, rect, bevelShadow, bevelShadow, bevelLight, bevelLight,
1754 		borders);
1755 
1756 	_DrawFrame(view, rect, frameColor, frameColor, frameColor, frameColor,
1757 		borders);
1758 
1759 	_DrawFrame(view, rect, bevelLight, bevelLight, bevelShadow, bevelShadow,
1760 		borders);
1761 }
1762 
1763 
1764 void
1765 BControlLook::DrawLabel(BView* view, const char* label, BRect rect,
1766 	const BRect& updateRect, const rgb_color& base, uint32 flags,
1767 	const rgb_color* textColor)
1768 {
1769 	DrawLabel(view, label, NULL, rect, updateRect, base, flags,
1770 		DefaultLabelAlignment(), textColor);
1771 }
1772 
1773 
1774 void
1775 BControlLook::DrawLabel(BView* view, const char* label, BRect rect,
1776 	const BRect& updateRect, const rgb_color& base, uint32 flags,
1777 	const BAlignment& alignment, const rgb_color* textColor)
1778 {
1779 	DrawLabel(view, label, NULL, rect, updateRect, base, flags, alignment,
1780 			textColor);
1781 }
1782 
1783 
1784 void
1785 BControlLook::DrawLabel(BView* view, const char* label, const rgb_color& base,
1786 	uint32 flags, const BPoint& where, const rgb_color* textColor)
1787 {
1788 	// setup the text color
1789 
1790 	BWindow* window = view->Window();
1791 	bool isDesktop = window
1792 		&& window->Feel() == kPrivateDesktopWindowFeel
1793 		&& window->Look() == kPrivateDesktopWindowLook
1794 		&& view->Parent()
1795 		&& view->Parent()->Parent() == NULL
1796 		&& (flags & B_IGNORE_OUTLINE) == 0;
1797 
1798 	rgb_color	low;
1799 	rgb_color	color;
1800 	rgb_color	glowColor;
1801 
1802 	if (textColor != NULL)
1803 		glowColor = *textColor;
1804 	else if ((flags & B_IS_CONTROL) != 0)
1805 		glowColor = ui_color(B_CONTROL_TEXT_COLOR);
1806 	else
1807 		glowColor = ui_color(B_PANEL_TEXT_COLOR);
1808 
1809 	color = glowColor;
1810 
1811 	if (isDesktop)
1812 		low = view->Parent()->ViewColor();
1813 	else
1814 		low = base;
1815 
1816 	if ((flags & B_DISABLED) != 0) {
1817 		color.red = (uint8)(((int32)low.red + color.red + 1) / 2);
1818 		color.green = (uint8)(((int32)low.green + color.green + 1) / 2);
1819 		color.blue = (uint8)(((int32)low.blue + color.blue + 1) / 2);
1820 	}
1821 
1822 	drawing_mode oldMode = view->DrawingMode();
1823 
1824 	if (isDesktop) {
1825 		// Enforce proper use of desktop label colors.
1826 		if(low.Brightness() < 100) {
1827 			if (textColor == NULL)
1828 				color = make_color(255, 255, 255);
1829 			glowColor = make_color(0, 0, 0);
1830 		} else {
1831 			if (textColor == NULL)
1832 				color = make_color(0, 0, 0);
1833 			glowColor = make_color(255, 255, 255);
1834 		}
1835 
1836 		// drawing occurs on the desktop
1837 		if (fCachedWorkspace != current_workspace()) {
1838 			int8 indice = 0;
1839 			int32 mask;
1840 			bool tmpOutline;
1841 			while (fBackgroundInfo.FindInt32("be:bgndimginfoworkspaces",
1842 					indice, &mask) == B_OK
1843 				&& fBackgroundInfo.FindBool("be:bgndimginfoerasetext",
1844 					indice, &tmpOutline) == B_OK) {
1845 
1846 				if (((1 << current_workspace()) & mask) != 0) {
1847 					fCachedOutline = tmpOutline;
1848 					fCachedWorkspace = current_workspace();
1849 					break;
1850 				}
1851 				indice++;
1852 			}
1853 		}
1854 
1855 		if (fCachedOutline) {
1856 			BFont font;
1857 			view->GetFont(&font);
1858 
1859 			view->SetDrawingMode(B_OP_ALPHA);
1860 			view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
1861 			// Draw glow or outline
1862 			if (glowColor.Brightness() > 128) {
1863 				font.SetFalseBoldWidth(2.0);
1864 				view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH);
1865 
1866 				glowColor.alpha = 30;
1867 				view->SetHighColor(glowColor);
1868 				view->DrawString(label, where);
1869 
1870 				font.SetFalseBoldWidth(1.0);
1871 				view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH);
1872 
1873 				glowColor.alpha = 65;
1874 				view->SetHighColor(glowColor);
1875 				view->DrawString(label, where);
1876 
1877 				font.SetFalseBoldWidth(0.0);
1878 				view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH);
1879 			} else {
1880 				font.SetFalseBoldWidth(1.0);
1881 				view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH);
1882 
1883 				glowColor.alpha = 30;
1884 				view->SetHighColor(glowColor);
1885 				view->DrawString(label, where);
1886 
1887 				font.SetFalseBoldWidth(0.0);
1888 				view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH);
1889 
1890 				glowColor.alpha = 200;
1891 				view->SetHighColor(glowColor);
1892 				view->DrawString(label, BPoint(where.x + 1, where.y + 1));
1893 			}
1894 		}
1895 	}
1896 
1897 	view->SetHighColor(color);
1898 	view->SetDrawingMode(B_OP_OVER);
1899 	view->DrawString(label, where);
1900 	view->SetDrawingMode(oldMode);
1901 }
1902 
1903 
1904 void
1905 BControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon,
1906 	BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags,
1907 	const rgb_color* textColor)
1908 {
1909 	DrawLabel(view, label, icon, rect, updateRect, base, flags,
1910 		DefaultLabelAlignment(), textColor);
1911 }
1912 
1913 
1914 void
1915 BControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon,
1916 	BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags,
1917 	const BAlignment& alignment, const rgb_color* textColor)
1918 {
1919 	if (!rect.Intersects(updateRect))
1920 		return;
1921 
1922 	if (label == NULL && icon == NULL)
1923 		return;
1924 
1925 	if (label == NULL) {
1926 		// icon only
1927 		BRect alignedRect = BLayoutUtils::AlignInFrame(rect,
1928 			icon->Bounds().Size(), alignment);
1929 		drawing_mode oldMode = view->DrawingMode();
1930 		view->SetDrawingMode(B_OP_OVER);
1931 		view->DrawBitmap(icon, alignedRect.LeftTop());
1932 		view->SetDrawingMode(oldMode);
1933 		return;
1934 	}
1935 
1936 	// label, possibly with icon
1937 	float availableWidth = rect.Width() + 1;
1938 	float width = 0;
1939 	float textOffset = 0;
1940 	float height = 0;
1941 
1942 	if (icon != NULL) {
1943 		width = icon->Bounds().Width() + DefaultLabelSpacing() + 1;
1944 		height = icon->Bounds().Height() + 1;
1945 		textOffset = width;
1946 		availableWidth -= textOffset;
1947 	}
1948 
1949 	// truncate the label if necessary and get the width and height
1950 	BString truncatedLabel(label);
1951 
1952 	BFont font;
1953 	view->GetFont(&font);
1954 
1955 	font.TruncateString(&truncatedLabel, B_TRUNCATE_END, availableWidth);
1956 	width += ceilf(font.StringWidth(truncatedLabel.String()));
1957 
1958 	font_height fontHeight;
1959 	font.GetHeight(&fontHeight);
1960 	float textHeight = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent);
1961 	height = std::max(height, textHeight);
1962 
1963 	// handle alignment
1964 	BRect alignedRect(BLayoutUtils::AlignOnRect(rect,
1965 		BSize(width - 1, height - 1), alignment));
1966 
1967 	if (icon != NULL) {
1968 		BPoint location(alignedRect.LeftTop());
1969 		if (icon->Bounds().Height() + 1 < height)
1970 			location.y += ceilf((height - icon->Bounds().Height() - 1) / 2);
1971 
1972 		drawing_mode oldMode = view->DrawingMode();
1973 		view->SetDrawingMode(B_OP_OVER);
1974 		view->DrawBitmap(icon, location);
1975 		view->SetDrawingMode(oldMode);
1976 	}
1977 
1978 	BPoint location(alignedRect.left + textOffset,
1979 		alignedRect.top + ceilf(fontHeight.ascent));
1980 	if (textHeight < height)
1981 		location.y += ceilf((height - textHeight) / 2);
1982 
1983 	DrawLabel(view, truncatedLabel.String(), base, flags, location, textColor);
1984 }
1985 
1986 
1987 void
1988 BControlLook::GetFrameInsets(frame_type frameType, uint32 flags, float& _left,
1989 	float& _top, float& _right, float& _bottom)
1990 {
1991 	// All frames have the same inset on each side.
1992 	float inset = 0;
1993 
1994 	switch (frameType) {
1995 		case B_BUTTON_FRAME:
1996 			inset = (flags & B_DEFAULT_BUTTON) != 0 ? 5 : 2;
1997 			break;
1998 		case B_GROUP_FRAME:
1999 		case B_MENU_FIELD_FRAME:
2000 			inset = 3;
2001 			break;
2002 		case B_SCROLL_VIEW_FRAME:
2003 		case B_TEXT_CONTROL_FRAME:
2004 			inset = 2;
2005 			break;
2006 	}
2007 
2008 	_left = inset;
2009 	_top = inset;
2010 	_right = inset;
2011 	_bottom = inset;
2012 }
2013 
2014 
2015 void
2016 BControlLook::GetBackgroundInsets(background_type backgroundType,
2017 	uint32 flags, float& _left, float& _top, float& _right, float& _bottom)
2018 {
2019 	// Most backgrounds have the same inset on each side.
2020 	float inset = 0;
2021 
2022 	switch (backgroundType) {
2023 		case B_BUTTON_BACKGROUND:
2024 		case B_MENU_BACKGROUND:
2025 		case B_MENU_BAR_BACKGROUND:
2026 		case B_MENU_FIELD_BACKGROUND:
2027 		case B_MENU_ITEM_BACKGROUND:
2028 			inset = 1;
2029 			break;
2030 		case B_BUTTON_WITH_POP_UP_BACKGROUND:
2031 			_left = 1;
2032 			_top = 1;
2033 			_right = 1 + kButtonPopUpIndicatorWidth;
2034 			_bottom = 1;
2035 			return;
2036 		case B_HORIZONTAL_SCROLL_BAR_BACKGROUND:
2037 			_left = 2;
2038 			_top = 0;
2039 			_right = 1;
2040 			_bottom = 0;
2041 			return;
2042 		case B_VERTICAL_SCROLL_BAR_BACKGROUND:
2043 			_left = 0;
2044 			_top = 2;
2045 			_right = 0;
2046 			_bottom = 1;
2047 			return;
2048 	}
2049 
2050 	_left = inset;
2051 	_top = inset;
2052 	_right = inset;
2053 	_bottom = inset;
2054 }
2055 
2056 
2057 void
2058 BControlLook::GetInsets(frame_type frameType, background_type backgroundType,
2059 	uint32 flags, float& _left, float& _top, float& _right, float& _bottom)
2060 {
2061 	GetFrameInsets(frameType, flags, _left, _top, _right, _bottom);
2062 
2063 	float left, top, right, bottom;
2064 	GetBackgroundInsets(backgroundType, flags, left, top, right, bottom);
2065 
2066 	_left += left;
2067 	_top += top;
2068 	_right += right;
2069 	_bottom += bottom;
2070 }
2071 
2072 
2073 void
2074 BControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect,
2075 	const BRect& updateRect, const rgb_color& base, uint32 flags,
2076 	uint32 borders, orientation orientation)
2077 {
2078 	_DrawButtonBackground(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f,
2079 		base, true, flags, borders, orientation);
2080 }
2081 
2082 
2083 void
2084 BControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect,
2085 	const BRect& updateRect, float radius, const rgb_color& base, uint32 flags,
2086 	uint32 borders, orientation orientation)
2087 {
2088 	_DrawButtonBackground(view, rect, updateRect, radius, radius, radius,
2089 		radius, base, true, flags, borders, orientation);
2090 }
2091 
2092 
2093 void
2094 BControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect,
2095 	const BRect& updateRect, float leftTopRadius, float rightTopRadius,
2096 	float leftBottomRadius, float rightBottomRadius, const rgb_color& base,
2097 	uint32 flags, uint32 borders, orientation orientation)
2098 {
2099 	_DrawButtonBackground(view, rect, updateRect, leftTopRadius,
2100 		rightTopRadius, leftBottomRadius, rightBottomRadius, base, true, flags,
2101 		borders, orientation);
2102 }
2103 
2104 
2105 void
2106 BControlLook::SetBackgroundInfo(const BMessage& backgroundInfo)
2107 {
2108 	fBackgroundInfo = backgroundInfo;
2109 	fCachedWorkspace = -1;
2110 }
2111 
2112 
2113 // #pragma mark -
2114 
2115 
2116 void
2117 BControlLook::_DrawButtonFrame(BView* view, BRect& rect,
2118 	const BRect& updateRect, float leftTopRadius, float rightTopRadius,
2119 	float leftBottomRadius, float rightBottomRadius, const rgb_color& base,
2120 	const rgb_color& background, float contrast, float brightness,
2121 	uint32 flags, uint32 borders)
2122 {
2123 	if (!rect.IsValid() || !rect.Intersects(updateRect))
2124 		return;
2125 
2126 	// save the clipping constraints of the view
2127 	view->PushState();
2128 
2129 	// set clipping constraints to updateRect
2130 	BRegion clipping(updateRect);
2131 	view->ConstrainClippingRegion(&clipping);
2132 
2133 	// If the button is flat and neither activated nor otherwise highlighted
2134 	// (mouse hovering or focussed), draw it flat.
2135 	if ((flags & B_FLAT) != 0
2136 		&& (flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED)) == 0
2137 		&& ((flags & (B_HOVER | B_FOCUSED)) == 0
2138 			|| (flags & B_DISABLED) != 0)) {
2139 		_DrawFrame(view, rect, background, background, background,
2140 			background, borders);
2141 		_DrawFrame(view, rect, background, background, background,
2142 			background, borders);
2143 		view->PopState();
2144 		return;
2145 	}
2146 
2147 	// outer edge colors
2148 	rgb_color edgeLightColor;
2149 	rgb_color edgeShadowColor;
2150 
2151 	// default button frame color
2152 	rgb_color defaultIndicatorColor = ui_color(B_CONTROL_BORDER_COLOR);
2153 	rgb_color cornerBgColor;
2154 
2155 	if ((flags & B_DISABLED) != 0) {
2156 		defaultIndicatorColor = disable_color(defaultIndicatorColor,
2157 			background);
2158 	}
2159 
2160 	drawing_mode oldMode = view->DrawingMode();
2161 
2162 	if ((flags & B_DEFAULT_BUTTON) != 0) {
2163 		cornerBgColor = defaultIndicatorColor;
2164 		edgeLightColor = _EdgeLightColor(defaultIndicatorColor,
2165 			contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8),
2166 			brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags);
2167 		edgeShadowColor = _EdgeShadowColor(defaultIndicatorColor,
2168 			contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8),
2169 			brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags);
2170 
2171 		// draw default button indicator
2172 		// Allow a 1-pixel border of the background to come through.
2173 		rect.InsetBy(1, 1);
2174 
2175 		view->SetHighColor(defaultIndicatorColor);
2176 		view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius);
2177 		rect.InsetBy(1, 1);
2178 
2179 		view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius);
2180 		rect.InsetBy(1, 1);
2181 	} else {
2182 		cornerBgColor = background;
2183 		if ((flags & B_BLEND_FRAME) != 0) {
2184 			// set the background color to transparent for the case
2185 			// that we are on the desktop
2186 			cornerBgColor.alpha = 0;
2187 			view->SetDrawingMode(B_OP_ALPHA);
2188 		}
2189 
2190 		edgeLightColor = _EdgeLightColor(background,
2191 			contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0),
2192 			brightness * 1.0, flags);
2193 		edgeShadowColor = _EdgeShadowColor(background,
2194 			contrast * (flags & B_DISABLED) != 0 ? 0.0 : 1.0,
2195 			brightness * 1.0, flags);
2196 	}
2197 
2198 	// frame colors
2199 	rgb_color frameLightColor  = _FrameLightColor(base, flags);
2200 	rgb_color frameShadowColor = _FrameShadowColor(base, flags);
2201 
2202 	// rounded corners
2203 
2204 	if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0
2205 		&& leftTopRadius > 0) {
2206 		// draw left top rounded corner
2207 		BRect leftTopCorner(floorf(rect.left), floorf(rect.top),
2208 			floorf(rect.left + leftTopRadius),
2209 			floorf(rect.top + leftTopRadius));
2210 		clipping.Exclude(leftTopCorner);
2211 		_DrawRoundCornerFrameLeftTop(view, leftTopCorner, updateRect,
2212 			cornerBgColor, edgeShadowColor, frameLightColor);
2213 	}
2214 
2215 	if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0
2216 		&& rightTopRadius > 0) {
2217 		// draw right top rounded corner
2218 		BRect rightTopCorner(floorf(rect.right - rightTopRadius),
2219 			floorf(rect.top), floorf(rect.right),
2220 			floorf(rect.top + rightTopRadius));
2221 		clipping.Exclude(rightTopCorner);
2222 		_DrawRoundCornerFrameRightTop(view, rightTopCorner, updateRect,
2223 			cornerBgColor, edgeShadowColor, edgeLightColor,
2224 			frameLightColor, frameShadowColor);
2225 	}
2226 
2227 	if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0
2228 		&& leftBottomRadius > 0) {
2229 		// draw left bottom rounded corner
2230 		BRect leftBottomCorner(floorf(rect.left),
2231 			floorf(rect.bottom - leftBottomRadius),
2232 			floorf(rect.left + leftBottomRadius), floorf(rect.bottom));
2233 		clipping.Exclude(leftBottomCorner);
2234 		_DrawRoundCornerFrameLeftBottom(view, leftBottomCorner, updateRect,
2235 			cornerBgColor, edgeShadowColor, edgeLightColor,
2236 			frameLightColor, frameShadowColor);
2237 	}
2238 
2239 	if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0
2240 		&& rightBottomRadius > 0) {
2241 		// draw right bottom rounded corner
2242 		BRect rightBottomCorner(floorf(rect.right - rightBottomRadius),
2243 			floorf(rect.bottom - rightBottomRadius), floorf(rect.right),
2244 			floorf(rect.bottom));
2245 		clipping.Exclude(rightBottomCorner);
2246 		_DrawRoundCornerFrameRightBottom(view, rightBottomCorner,
2247 			updateRect, cornerBgColor, edgeLightColor, frameShadowColor);
2248 	}
2249 
2250 	// clip out the corners
2251 	view->ConstrainClippingRegion(&clipping);
2252 
2253 	// draw outer edge
2254 	if ((flags & B_DEFAULT_BUTTON) != 0) {
2255 		_DrawOuterResessedFrame(view, rect, defaultIndicatorColor,
2256 			contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8),
2257 			brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9),
2258 			flags, borders);
2259 	} else {
2260 		_DrawOuterResessedFrame(view, rect, background,
2261 			contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0),
2262 			brightness * 1.0, flags, borders);
2263 	}
2264 
2265 	view->SetDrawingMode(oldMode);
2266 
2267 	// draw frame
2268 	if ((flags & B_BLEND_FRAME) != 0) {
2269 		drawing_mode oldDrawingMode = view->DrawingMode();
2270 		view->SetDrawingMode(B_OP_ALPHA);
2271 
2272 		_DrawFrame(view, rect, frameLightColor, frameLightColor,
2273 			frameShadowColor, frameShadowColor, borders);
2274 
2275 		view->SetDrawingMode(oldDrawingMode);
2276 	} else {
2277 		_DrawFrame(view, rect, frameLightColor, frameLightColor,
2278 			frameShadowColor, frameShadowColor, borders);
2279 	}
2280 
2281 	// restore the clipping constraints of the view
2282 	view->PopState();
2283 }
2284 
2285 
2286 void
2287 BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect,
2288 	const rgb_color& base, float contrast, float brightness, uint32 flags,
2289 	uint32 borders)
2290 {
2291 	rgb_color edgeLightColor = _EdgeLightColor(base, contrast,
2292 		brightness, flags);
2293 	rgb_color edgeShadowColor = _EdgeShadowColor(base, contrast,
2294 		brightness, flags);
2295 
2296 	if ((flags & B_BLEND_FRAME) != 0) {
2297 		// assumes the background has already been painted
2298 		drawing_mode oldDrawingMode = view->DrawingMode();
2299 		view->SetDrawingMode(B_OP_ALPHA);
2300 
2301 		_DrawFrame(view, rect, edgeShadowColor, edgeShadowColor,
2302 			edgeLightColor, edgeLightColor, borders);
2303 
2304 		view->SetDrawingMode(oldDrawingMode);
2305 	} else {
2306 		_DrawFrame(view, rect, edgeShadowColor, edgeShadowColor,
2307 			edgeLightColor, edgeLightColor, borders);
2308 	}
2309 }
2310 
2311 
2312 void
2313 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left,
2314 	const rgb_color& top, const rgb_color& right, const rgb_color& bottom,
2315 	uint32 borders)
2316 {
2317 	view->BeginLineArray(4);
2318 
2319 	if (borders & B_LEFT_BORDER) {
2320 		view->AddLine(
2321 			BPoint(rect.left, rect.bottom),
2322 			BPoint(rect.left, rect.top), left);
2323 		rect.left++;
2324 	}
2325 	if (borders & B_TOP_BORDER) {
2326 		view->AddLine(
2327 			BPoint(rect.left, rect.top),
2328 			BPoint(rect.right, rect.top), top);
2329 		rect.top++;
2330 	}
2331 	if (borders & B_RIGHT_BORDER) {
2332 		view->AddLine(
2333 			BPoint(rect.right, rect.top),
2334 			BPoint(rect.right, rect.bottom), right);
2335 		rect.right--;
2336 	}
2337 	if (borders & B_BOTTOM_BORDER) {
2338 		view->AddLine(
2339 			BPoint(rect.left, rect.bottom),
2340 			BPoint(rect.right, rect.bottom), bottom);
2341 		rect.bottom--;
2342 	}
2343 
2344 	view->EndLineArray();
2345 }
2346 
2347 
2348 void
2349 BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left,
2350 	const rgb_color& top, const rgb_color& right, const rgb_color& bottom,
2351 	const rgb_color& rightTop, const rgb_color& leftBottom, uint32 borders)
2352 {
2353 	view->BeginLineArray(6);
2354 
2355 	if (borders & B_TOP_BORDER) {
2356 		if (borders & B_RIGHT_BORDER) {
2357 			view->AddLine(
2358 				BPoint(rect.left, rect.top),
2359 				BPoint(rect.right - 1, rect.top), top);
2360 			view->AddLine(
2361 				BPoint(rect.right, rect.top),
2362 				BPoint(rect.right, rect.top), rightTop);
2363 		} else {
2364 			view->AddLine(
2365 				BPoint(rect.left, rect.top),
2366 				BPoint(rect.right, rect.top), top);
2367 		}
2368 		rect.top++;
2369 	}
2370 
2371 	if (borders & B_LEFT_BORDER) {
2372 		view->AddLine(
2373 			BPoint(rect.left, rect.top),
2374 			BPoint(rect.left, rect.bottom - 1), left);
2375 		view->AddLine(
2376 			BPoint(rect.left, rect.bottom),
2377 			BPoint(rect.left, rect.bottom), leftBottom);
2378 		rect.left++;
2379 	}
2380 
2381 	if (borders & B_BOTTOM_BORDER) {
2382 		view->AddLine(
2383 			BPoint(rect.left, rect.bottom),
2384 			BPoint(rect.right, rect.bottom), bottom);
2385 		rect.bottom--;
2386 	}
2387 
2388 	if (borders & B_RIGHT_BORDER) {
2389 		view->AddLine(
2390 			BPoint(rect.right, rect.bottom),
2391 			BPoint(rect.right, rect.top), right);
2392 		rect.right--;
2393 	}
2394 
2395 	view->EndLineArray();
2396 }
2397 
2398 
2399 void
2400 BControlLook::_DrawButtonBackground(BView* view, BRect& rect,
2401 	const BRect& updateRect, float leftTopRadius, float rightTopRadius,
2402 	float leftBottomRadius, float rightBottomRadius, const rgb_color& base,
2403 	bool popupIndicator, uint32 flags, uint32 borders, orientation orientation)
2404 {
2405 	if (!rect.IsValid() || !rect.Intersects(updateRect))
2406 		return;
2407 
2408 	// save the clipping constraints of the view
2409 	view->PushState();
2410 
2411 	// set clipping constraints to updateRect
2412 	BRegion clipping(updateRect);
2413 	view->ConstrainClippingRegion(&clipping);
2414 
2415 	// If the button is flat and neither activated nor otherwise highlighted
2416 	// (mouse hovering or focussed), draw it flat.
2417 	if ((flags & B_FLAT) != 0
2418 		&& (flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED)) == 0
2419 		&& ((flags & (B_HOVER | B_FOCUSED)) == 0
2420 			|| (flags & B_DISABLED) != 0)) {
2421 		_DrawFlatButtonBackground(view, rect, updateRect, base, popupIndicator,
2422 			flags, borders, orientation);
2423 	} else {
2424 		_DrawNonFlatButtonBackground(view, rect, updateRect, clipping,
2425 			leftTopRadius, rightTopRadius, leftBottomRadius, rightBottomRadius,
2426 			base, popupIndicator, flags, borders, orientation);
2427 	}
2428 
2429 	// restore the clipping constraints of the view
2430 	view->PopState();
2431 }
2432 
2433 
2434 void
2435 BControlLook::_DrawFlatButtonBackground(BView* view, BRect& rect,
2436 	const BRect& updateRect, const rgb_color& base, bool popupIndicator,
2437 	uint32 flags, uint32 borders, orientation orientation)
2438 {
2439 	_DrawFrame(view, rect, base, base, base, base, borders);
2440 		// Not an actual frame, but the method insets our rect as needed.
2441 
2442 	view->SetHighColor(base);
2443 	view->FillRect(rect);
2444 
2445 	if (popupIndicator) {
2446 		BRect indicatorRect(rect);
2447 		rect.right -= kButtonPopUpIndicatorWidth;
2448 		indicatorRect.left = rect.right + 3;
2449 			// 2 pixels for the separator
2450 
2451 		view->SetHighColor(base);
2452 		view->FillRect(indicatorRect);
2453 
2454 		_DrawPopUpMarker(view, indicatorRect, base, flags);
2455 	}
2456 }
2457 
2458 
2459 void
2460 BControlLook::_DrawNonFlatButtonBackground(BView* view, BRect& rect,
2461 	const BRect& updateRect, BRegion& clipping, float leftTopRadius,
2462 	float rightTopRadius, float leftBottomRadius, float rightBottomRadius,
2463 	const rgb_color& base, bool popupIndicator, uint32 flags, uint32 borders,
2464 	orientation orientation)
2465 {
2466 	// inner bevel colors
2467 	rgb_color bevelLightColor  = _BevelLightColor(base, flags);
2468 	rgb_color bevelShadowColor = _BevelShadowColor(base, flags);
2469 
2470 	// button background color
2471 	rgb_color buttonBgColor;
2472 	if ((flags & B_DISABLED) != 0)
2473 		buttonBgColor = tint_color(base, 0.7);
2474 	else
2475 		buttonBgColor = tint_color(base, B_LIGHTEN_1_TINT);
2476 
2477 	// surface top gradient
2478 	BGradientLinear fillGradient;
2479 	_MakeButtonGradient(fillGradient, rect, base, flags, orientation);
2480 
2481 	// rounded corners
2482 
2483 	if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0
2484 		&& leftTopRadius > 0) {
2485 		// draw left top rounded corner
2486 		BRect leftTopCorner(floorf(rect.left), floorf(rect.top),
2487 			floorf(rect.left + leftTopRadius - 2.0),
2488 			floorf(rect.top + leftTopRadius - 2.0));
2489 		clipping.Exclude(leftTopCorner);
2490 		_DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect,
2491 			bevelLightColor, fillGradient);
2492 	}
2493 
2494 	if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0
2495 		&& rightTopRadius > 0) {
2496 		// draw right top rounded corner
2497 		BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0),
2498 			floorf(rect.top), floorf(rect.right),
2499 			floorf(rect.top + rightTopRadius - 2.0));
2500 		clipping.Exclude(rightTopCorner);
2501 		_DrawRoundCornerBackgroundRightTop(view, rightTopCorner,
2502 			updateRect, bevelLightColor, bevelShadowColor, fillGradient);
2503 	}
2504 
2505 	if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0
2506 		&& leftBottomRadius > 0) {
2507 		// draw left bottom rounded corner
2508 		BRect leftBottomCorner(floorf(rect.left),
2509 			floorf(rect.bottom - leftBottomRadius + 2.0),
2510 			floorf(rect.left + leftBottomRadius - 2.0),
2511 			floorf(rect.bottom));
2512 		clipping.Exclude(leftBottomCorner);
2513 		_DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner,
2514 			updateRect, bevelLightColor, bevelShadowColor, fillGradient);
2515 	}
2516 
2517 	if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0
2518 		&& rightBottomRadius > 0) {
2519 		// draw right bottom rounded corner
2520 		BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0),
2521 			floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right),
2522 			floorf(rect.bottom));
2523 		clipping.Exclude(rightBottomCorner);
2524 		_DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner,
2525 			updateRect, bevelShadowColor, fillGradient);
2526 	}
2527 
2528 	// clip out the corners
2529 	view->ConstrainClippingRegion(&clipping);
2530 
2531 	// draw inner bevel
2532 
2533 	if ((flags & B_ACTIVATED) != 0) {
2534 		view->BeginLineArray(4);
2535 
2536 		// shadow along left/top borders
2537 		if (borders & B_LEFT_BORDER) {
2538 			view->AddLine(BPoint(rect.left, rect.top),
2539 				BPoint(rect.left, rect.bottom), bevelLightColor);
2540 			rect.left++;
2541 		}
2542 		if (borders & B_TOP_BORDER) {
2543 			view->AddLine(BPoint(rect.left, rect.top),
2544 				BPoint(rect.right, rect.top), bevelLightColor);
2545 			rect.top++;
2546 		}
2547 
2548 		// softer shadow along left/top borders
2549 		if (borders & B_LEFT_BORDER) {
2550 			view->AddLine(BPoint(rect.left, rect.top),
2551 				BPoint(rect.left, rect.bottom), bevelShadowColor);
2552 			rect.left++;
2553 		}
2554 		if (borders & B_TOP_BORDER) {
2555 			view->AddLine(BPoint(rect.left, rect.top),
2556 				BPoint(rect.right, rect.top), bevelShadowColor);
2557 			rect.top++;
2558 		}
2559 
2560 		view->EndLineArray();
2561 	} else {
2562 		_DrawFrame(view, rect,
2563 			bevelLightColor, bevelLightColor,
2564 			bevelShadowColor, bevelShadowColor,
2565 			buttonBgColor, buttonBgColor, borders);
2566 	}
2567 
2568 	if (popupIndicator) {
2569 		BRect indicatorRect(rect);
2570 		rect.right -= kButtonPopUpIndicatorWidth;
2571 		indicatorRect.left = rect.right + 3;
2572 			// 2 pixels for the separator
2573 
2574 		// Even when depressed we want the pop-up indicator background and
2575 		// separator to cover the area up to the top.
2576 		if ((flags & B_ACTIVATED) != 0)
2577 			indicatorRect.top--;
2578 
2579 		// draw the separator
2580 		rgb_color separatorBaseColor = base;
2581 		if ((flags & B_ACTIVATED) != 0)
2582 			separatorBaseColor = tint_color(base, B_DARKEN_1_TINT);
2583 
2584 		rgb_color separatorLightColor = _EdgeLightColor(separatorBaseColor,
2585 			(flags & B_DISABLED) != 0 ? 0.7 : 1.0, 1.0, flags);
2586 		rgb_color separatorShadowColor = _EdgeShadowColor(separatorBaseColor,
2587 			(flags & B_DISABLED) != 0 ? 0.7 : 1.0, 1.0, flags);
2588 
2589 		view->BeginLineArray(2);
2590 
2591 		view->AddLine(BPoint(indicatorRect.left - 2, indicatorRect.top),
2592 			BPoint(indicatorRect.left - 2, indicatorRect.bottom),
2593 			separatorShadowColor);
2594 		view->AddLine(BPoint(indicatorRect.left - 1, indicatorRect.top),
2595 			BPoint(indicatorRect.left - 1, indicatorRect.bottom),
2596 			separatorLightColor);
2597 
2598 		view->EndLineArray();
2599 
2600 		// draw background and pop-up marker
2601 		_DrawMenuFieldBackgroundInside(view, indicatorRect, updateRect,
2602 			0.0f, rightTopRadius, 0.0f, rightBottomRadius, base, flags, 0);
2603 
2604 		if ((flags & B_ACTIVATED) != 0)
2605 			indicatorRect.top++;
2606 
2607 		_DrawPopUpMarker(view, indicatorRect, base, flags);
2608 	}
2609 
2610 	// fill in the background
2611 	view->FillRect(rect, fillGradient);
2612 }
2613 
2614 
2615 void
2616 BControlLook::_DrawPopUpMarker(BView* view, const BRect& rect,
2617 	const rgb_color& base, uint32 flags)
2618 {
2619 	BPoint center(roundf((rect.left + rect.right) / 2.0),
2620 		roundf((rect.top + rect.bottom) / 2.0));
2621 	BPoint triangle[3];
2622 	triangle[0] = center + BPoint(-2.5, -0.5);
2623 	triangle[1] = center + BPoint(2.5, -0.5);
2624 	triangle[2] = center + BPoint(0.0, 2.0);
2625 
2626 	uint32 viewFlags = view->Flags();
2627 	view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE);
2628 
2629 	rgb_color markColor;
2630 	if ((flags & B_DISABLED) != 0)
2631 		markColor = tint_color(base, 1.35);
2632 	else
2633 		markColor = tint_color(base, 1.65);
2634 
2635 	view->SetHighColor(markColor);
2636 	view->FillTriangle(triangle[0], triangle[1], triangle[2]);
2637 
2638 	view->SetFlags(viewFlags);
2639 }
2640 
2641 
2642 void
2643 BControlLook::_DrawMenuFieldBackgroundOutside(BView* view, BRect& rect,
2644 	const BRect& updateRect, float leftTopRadius, float rightTopRadius,
2645 	float leftBottomRadius, float rightBottomRadius, const rgb_color& base,
2646 	bool popupIndicator, uint32 flags)
2647 {
2648 	if (!rect.IsValid() || !rect.Intersects(updateRect))
2649 		return;
2650 
2651 	if (popupIndicator) {
2652 		BRect leftRect(rect);
2653 		leftRect.right -= 10;
2654 
2655 		BRect rightRect(rect);
2656 		rightRect.left = rightRect.right - 9;
2657 
2658 		_DrawMenuFieldBackgroundInside(view, leftRect, updateRect,
2659 			leftTopRadius, 0.0f, leftBottomRadius, 0.0f, base, flags,
2660 			B_LEFT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER);
2661 
2662 		_DrawMenuFieldBackgroundInside(view, rightRect, updateRect,
2663 			0.0f, rightTopRadius, 0.0f, rightBottomRadius, base, flags,
2664 			B_TOP_BORDER | B_RIGHT_BORDER | B_BOTTOM_BORDER);
2665 
2666 		_DrawPopUpMarker(view, rightRect, base, flags);
2667 
2668 		// draw a line on the left of the popup frame
2669 		rgb_color bevelShadowColor = _BevelShadowColor(base, flags);
2670 		view->SetHighColor(bevelShadowColor);
2671 		BPoint leftTopCorner(floorf(rightRect.left - 1.0),
2672 			floorf(rightRect.top - 1.0));
2673 		BPoint leftBottomCorner(floorf(rightRect.left - 1.0),
2674 			floorf(rightRect.bottom + 1.0));
2675 		view->StrokeLine(leftTopCorner, leftBottomCorner);
2676 
2677 		rect = leftRect;
2678 	} else {
2679 		_DrawMenuFieldBackgroundInside(view, rect, updateRect, leftTopRadius,
2680 			rightTopRadius, leftBottomRadius, rightBottomRadius, base, flags);
2681 	}
2682 }
2683 
2684 
2685 void
2686 BControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect,
2687 	const BRect& updateRect, float leftTopRadius, float rightTopRadius,
2688 	float leftBottomRadius, float rightBottomRadius, const rgb_color& base,
2689 	uint32 flags, uint32 borders)
2690 {
2691 	if (!rect.IsValid() || !rect.Intersects(updateRect))
2692 		return;
2693 
2694 	// save the clipping constraints of the view
2695 	view->PushState();
2696 
2697 	// set clipping constraints to updateRect
2698 	BRegion clipping(updateRect);
2699 	view->ConstrainClippingRegion(&clipping);
2700 
2701 	// frame colors
2702 	rgb_color frameLightColor  = _FrameLightColor(base, flags);
2703 	rgb_color frameShadowColor = _FrameShadowColor(base, flags);
2704 
2705 	// indicator background color
2706 	rgb_color indicatorBase;
2707 	if ((borders & B_LEFT_BORDER) != 0)
2708 		indicatorBase = base;
2709 	else {
2710 		if ((flags & B_DISABLED) != 0)
2711 			indicatorBase = tint_color(base, 1.05);
2712 		else
2713 			indicatorBase = tint_color(base, 1.12);
2714 	}
2715 
2716 	// bevel colors
2717 	rgb_color cornerColor = tint_color(indicatorBase, 0.85);
2718 	rgb_color bevelColor1 = tint_color(indicatorBase, 0.3);
2719 	rgb_color bevelColor2 = tint_color(indicatorBase, 0.5);
2720 	rgb_color bevelColor3 = tint_color(indicatorBase, 1.03);
2721 
2722 	if ((flags & B_DISABLED) != 0) {
2723 		cornerColor = tint_color(indicatorBase, 0.8);
2724 		bevelColor1 = tint_color(indicatorBase, 0.7);
2725 		bevelColor2 = tint_color(indicatorBase, 0.8);
2726 		bevelColor3 = tint_color(indicatorBase, 1.01);
2727 	} else {
2728 		cornerColor = tint_color(indicatorBase, 0.85);
2729 		bevelColor1 = tint_color(indicatorBase, 0.3);
2730 		bevelColor2 = tint_color(indicatorBase, 0.5);
2731 		bevelColor3 = tint_color(indicatorBase, 1.03);
2732 	}
2733 
2734 	// surface top gradient
2735 	BGradientLinear fillGradient;
2736 	_MakeButtonGradient(fillGradient, rect, indicatorBase, flags);
2737 
2738 	// rounded corners
2739 
2740 	if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0
2741 		&& leftTopRadius > 0) {
2742 		// draw left top rounded corner
2743 		BRect leftTopCorner(floorf(rect.left), floorf(rect.top),
2744 			floorf(rect.left + leftTopRadius - 2.0),
2745 			floorf(rect.top + leftTopRadius - 2.0));
2746 		clipping.Exclude(leftTopCorner);
2747 
2748 		BRegion cornerClipping(leftTopCorner);
2749 		view->ConstrainClippingRegion(&cornerClipping);
2750 
2751 		BRect ellipseRect(leftTopCorner);
2752 		ellipseRect.InsetBy(-1.0, -1.0);
2753 		ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2;
2754 		ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2;
2755 
2756 		// draw the frame (again)
2757 		view->SetHighColor(frameLightColor);
2758 		view->FillEllipse(ellipseRect);
2759 
2760 		// draw the bevel and background
2761 		_DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect,
2762 			bevelColor1, fillGradient);
2763 	}
2764 
2765 	if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0
2766 		&& rightTopRadius > 0) {
2767 		// draw right top rounded corner
2768 		BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0),
2769 			floorf(rect.top), floorf(rect.right),
2770 			floorf(rect.top + rightTopRadius - 2.0));
2771 		clipping.Exclude(rightTopCorner);
2772 
2773 		BRegion cornerClipping(rightTopCorner);
2774 		view->ConstrainClippingRegion(&cornerClipping);
2775 
2776 		BRect ellipseRect(rightTopCorner);
2777 		ellipseRect.InsetBy(-1.0, -1.0);
2778 		ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2;
2779 		ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2;
2780 
2781 		// draw the frame (again)
2782 		if (frameLightColor == frameShadowColor) {
2783 			view->SetHighColor(frameLightColor);
2784 			view->FillEllipse(ellipseRect);
2785 		} else {
2786 			BGradientLinear gradient;
2787 			gradient.AddColor(frameLightColor, 0);
2788 			gradient.AddColor(frameShadowColor, 255);
2789 			gradient.SetStart(rightTopCorner.LeftTop());
2790 			gradient.SetEnd(rightTopCorner.RightBottom());
2791 			view->FillEllipse(ellipseRect, gradient);
2792 		}
2793 
2794 		// draw the bevel and background
2795 		_DrawRoundCornerBackgroundRightTop(view, rightTopCorner, updateRect,
2796 			bevelColor1, bevelColor3, fillGradient);
2797 	}
2798 
2799 	if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0
2800 		&& leftBottomRadius > 0) {
2801 		// draw left bottom rounded corner
2802 		BRect leftBottomCorner(floorf(rect.left),
2803 			floorf(rect.bottom - leftBottomRadius + 2.0),
2804 			floorf(rect.left + leftBottomRadius - 2.0),
2805 			floorf(rect.bottom));
2806 		clipping.Exclude(leftBottomCorner);
2807 
2808 		BRegion cornerClipping(leftBottomCorner);
2809 		view->ConstrainClippingRegion(&cornerClipping);
2810 
2811 		BRect ellipseRect(leftBottomCorner);
2812 		ellipseRect.InsetBy(-1.0, -1.0);
2813 		ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2;
2814 		ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2;
2815 
2816 		// draw the frame (again)
2817 		if (frameLightColor == frameShadowColor) {
2818 			view->SetHighColor(frameLightColor);
2819 			view->FillEllipse(ellipseRect);
2820 		} else {
2821 			BGradientLinear gradient;
2822 			gradient.AddColor(frameLightColor, 0);
2823 			gradient.AddColor(frameShadowColor, 255);
2824 			gradient.SetStart(leftBottomCorner.LeftTop());
2825 			gradient.SetEnd(leftBottomCorner.RightBottom());
2826 			view->FillEllipse(ellipseRect, gradient);
2827 		}
2828 
2829 		// draw the bevel and background
2830 		_DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner,
2831 			updateRect, bevelColor2, bevelColor3, fillGradient);
2832 	}
2833 
2834 	if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0
2835 		&& rightBottomRadius > 0) {
2836 		// draw right bottom rounded corner
2837 		BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0),
2838 			floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right),
2839 			floorf(rect.bottom));
2840 		clipping.Exclude(rightBottomCorner);
2841 
2842 		BRegion cornerClipping(rightBottomCorner);
2843 		view->ConstrainClippingRegion(&cornerClipping);
2844 
2845 		BRect ellipseRect(rightBottomCorner);
2846 		ellipseRect.InsetBy(-1.0, -1.0);
2847 		ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2;
2848 		ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2;
2849 
2850 		// draw the frame (again)
2851 		view->SetHighColor(frameShadowColor);
2852 		view->FillEllipse(ellipseRect);
2853 
2854 		// draw the bevel and background
2855 		_DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner,
2856 			updateRect, bevelColor3, fillGradient);
2857 	}
2858 
2859 	// clip out the corners
2860 	view->ConstrainClippingRegion(&clipping);
2861 
2862 	// draw the bevel
2863 	_DrawFrame(view, rect,
2864 		bevelColor2, bevelColor1,
2865 		bevelColor3, bevelColor3,
2866 		cornerColor, cornerColor,
2867 		borders);
2868 
2869 	// fill in the background
2870 	view->FillRect(rect, fillGradient);
2871 
2872 	// restore the clipping constraints of the view
2873 	view->PopState();
2874 }
2875 
2876 
2877 void
2878 BControlLook::_DrawRoundCornerLeftTop(BView* view, BRect& cornerRect,
2879 	const BRect& updateRect, const rgb_color& background,
2880 	const rgb_color& edgeColor, const rgb_color& frameColor,
2881 	const rgb_color& bevelColor, const BGradientLinear& fillGradient)
2882 {
2883 	_DrawRoundCornerFrameLeftTop(view, cornerRect, updateRect,
2884 		background, edgeColor, frameColor);
2885 	_DrawRoundCornerBackgroundLeftTop(view, cornerRect, updateRect,
2886 		bevelColor, fillGradient);
2887 }
2888 
2889 
2890 void
2891 BControlLook::_DrawRoundCornerFrameLeftTop(BView* view, BRect& cornerRect,
2892 	const BRect& updateRect, const rgb_color& background,
2893 	const rgb_color& edgeColor, const rgb_color& frameColor)
2894 {
2895 	// constrain clipping region to corner
2896 	BRegion clipping(cornerRect);
2897 	view->ConstrainClippingRegion(&clipping);
2898 
2899 	// background
2900 	view->SetHighColor(background);
2901 	view->FillRect(cornerRect);
2902 
2903 	// outer edge
2904 	BRect ellipseRect(cornerRect);
2905 	ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2;
2906 	ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2;
2907 
2908 	view->SetHighColor(edgeColor);
2909 	view->FillEllipse(ellipseRect);
2910 
2911 	// frame
2912 	ellipseRect.InsetBy(1, 1);
2913 	cornerRect.left++;
2914 	cornerRect.top++;
2915 	view->SetHighColor(frameColor);
2916 	view->FillEllipse(ellipseRect);
2917 
2918 	// prepare for bevel
2919 	cornerRect.left++;
2920 	cornerRect.top++;
2921 }
2922 
2923 
2924 void
2925 BControlLook::_DrawRoundCornerBackgroundLeftTop(BView* view, BRect& cornerRect,
2926 	const BRect& updateRect, const rgb_color& bevelColor,
2927 	const BGradientLinear& fillGradient)
2928 {
2929 	// constrain clipping region to corner
2930 	BRegion clipping(cornerRect);
2931 	view->ConstrainClippingRegion(&clipping);
2932 
2933 	BRect ellipseRect(cornerRect);
2934 	ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2;
2935 	ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2;
2936 
2937 	// bevel
2938 	view->SetHighColor(bevelColor);
2939 	view->FillEllipse(ellipseRect);
2940 
2941 	// gradient
2942 	ellipseRect.InsetBy(1, 1);
2943 	view->FillEllipse(ellipseRect, fillGradient);
2944 }
2945 
2946 
2947 void
2948 BControlLook::_DrawRoundCornerRightTop(BView* view, BRect& cornerRect,
2949 	const BRect& updateRect, const rgb_color& background,
2950 	const rgb_color& edgeTopColor, const rgb_color& edgeRightColor,
2951 	const rgb_color& frameTopColor, const rgb_color& frameRightColor,
2952 	const rgb_color& bevelTopColor, const rgb_color& bevelRightColor,
2953 	const BGradientLinear& fillGradient)
2954 {
2955 	_DrawRoundCornerFrameRightTop(view, cornerRect, updateRect,
2956 		background, edgeTopColor, edgeRightColor, frameTopColor,
2957 		frameRightColor);
2958 	_DrawRoundCornerBackgroundRightTop(view, cornerRect, updateRect,
2959 		bevelTopColor, bevelRightColor, fillGradient);
2960 }
2961 
2962 
2963 void
2964 BControlLook::_DrawRoundCornerFrameRightTop(BView* view, BRect& cornerRect,
2965 	const BRect& updateRect, const rgb_color& background,
2966 	const rgb_color& edgeTopColor, const rgb_color& edgeRightColor,
2967 	const rgb_color& frameTopColor, const rgb_color& frameRightColor)
2968 {
2969 	// constrain clipping region to corner
2970 	BRegion clipping(cornerRect);
2971 	view->ConstrainClippingRegion(&clipping);
2972 
2973 	// background
2974 	view->SetHighColor(background);
2975 	view->FillRect(cornerRect);
2976 
2977 	// outer edge
2978 	BRect ellipseRect(cornerRect);
2979 	ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2;
2980 	ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2;
2981 
2982 	BGradientLinear gradient;
2983 	gradient.AddColor(edgeTopColor, 0);
2984 	gradient.AddColor(edgeRightColor, 255);
2985 	gradient.SetStart(cornerRect.LeftTop());
2986 	gradient.SetEnd(cornerRect.RightBottom());
2987 	view->FillEllipse(ellipseRect, gradient);
2988 
2989 	// frame
2990 	ellipseRect.InsetBy(1, 1);
2991 	cornerRect.right--;
2992 	cornerRect.top++;
2993 	if (frameTopColor == frameRightColor) {
2994 		view->SetHighColor(frameTopColor);
2995 		view->FillEllipse(ellipseRect);
2996 	} else {
2997 		gradient.SetColor(0, frameTopColor);
2998 		gradient.SetColor(1, frameRightColor);
2999 		gradient.SetStart(cornerRect.LeftTop());
3000 		gradient.SetEnd(cornerRect.RightBottom());
3001 		view->FillEllipse(ellipseRect, gradient);
3002 	}
3003 
3004 	// prepare for bevel
3005 	cornerRect.right--;
3006 	cornerRect.top++;
3007 }
3008 
3009 
3010 void
3011 BControlLook::_DrawRoundCornerBackgroundRightTop(BView* view, BRect& cornerRect,
3012 	const BRect& updateRect, const rgb_color& bevelTopColor,
3013 	const rgb_color& bevelRightColor, const BGradientLinear& fillGradient)
3014 {
3015 	// constrain clipping region to corner
3016 	BRegion clipping(cornerRect);
3017 	view->ConstrainClippingRegion(&clipping);
3018 
3019 	BRect ellipseRect(cornerRect);
3020 	ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2;
3021 	ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2;
3022 
3023 	// bevel
3024 	BGradientLinear gradient;
3025 	gradient.AddColor(bevelTopColor, 0);
3026 	gradient.AddColor(bevelRightColor, 255);
3027 	gradient.SetStart(cornerRect.LeftTop());
3028 	gradient.SetEnd(cornerRect.RightBottom());
3029 	view->FillEllipse(ellipseRect, gradient);
3030 
3031 	// gradient
3032 	ellipseRect.InsetBy(1, 1);
3033 	view->FillEllipse(ellipseRect, fillGradient);
3034 }
3035 
3036 
3037 void
3038 BControlLook::_DrawRoundCornerLeftBottom(BView* view, BRect& cornerRect,
3039 	const BRect& updateRect, const rgb_color& background,
3040 	const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor,
3041 	const rgb_color& frameLeftColor, const rgb_color& frameBottomColor,
3042 	const rgb_color& bevelLeftColor, const rgb_color& bevelBottomColor,
3043 	const BGradientLinear& fillGradient)
3044 {
3045 	_DrawRoundCornerFrameLeftBottom(view, cornerRect, updateRect,
3046 		background, edgeLeftColor, edgeBottomColor, frameLeftColor,
3047 		frameBottomColor);
3048 	_DrawRoundCornerBackgroundLeftBottom(view, cornerRect, updateRect,
3049 		bevelLeftColor, bevelBottomColor, fillGradient);
3050 }
3051 
3052 
3053 void
3054 BControlLook::_DrawRoundCornerFrameLeftBottom(BView* view, BRect& cornerRect,
3055 	const BRect& updateRect, const rgb_color& background,
3056 	const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor,
3057 	const rgb_color& frameLeftColor, const rgb_color& frameBottomColor)
3058 {
3059 	// constrain clipping region to corner
3060 	BRegion clipping(cornerRect);
3061 	view->ConstrainClippingRegion(&clipping);
3062 
3063 	// background
3064 	view->SetHighColor(background);
3065 	view->FillRect(cornerRect);
3066 
3067 	// outer edge
3068 	BRect ellipseRect(cornerRect);
3069 	ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2;
3070 	ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2;
3071 
3072 	BGradientLinear gradient;
3073 	gradient.AddColor(edgeLeftColor, 0);
3074 	gradient.AddColor(edgeBottomColor, 255);
3075 	gradient.SetStart(cornerRect.LeftTop());
3076 	gradient.SetEnd(cornerRect.RightBottom());
3077 	view->FillEllipse(ellipseRect, gradient);
3078 
3079 	// frame
3080 	ellipseRect.InsetBy(1, 1);
3081 	cornerRect.left++;
3082 	cornerRect.bottom--;
3083 	if (frameLeftColor == frameBottomColor) {
3084 		view->SetHighColor(frameLeftColor);
3085 		view->FillEllipse(ellipseRect);
3086 	} else {
3087 		gradient.SetColor(0, frameLeftColor);
3088 		gradient.SetColor(1, frameBottomColor);
3089 		gradient.SetStart(cornerRect.LeftTop());
3090 		gradient.SetEnd(cornerRect.RightBottom());
3091 		view->FillEllipse(ellipseRect, gradient);
3092 	}
3093 
3094 	// prepare for bevel
3095 	cornerRect.left++;
3096 	cornerRect.bottom--;
3097 }
3098 
3099 
3100 void
3101 BControlLook::_DrawRoundCornerBackgroundLeftBottom(BView* view, BRect& cornerRect,
3102 	const BRect& updateRect, const rgb_color& bevelLeftColor,
3103 	const rgb_color& bevelBottomColor, const BGradientLinear& fillGradient)
3104 {
3105 	// constrain clipping region to corner
3106 	BRegion clipping(cornerRect);
3107 	view->ConstrainClippingRegion(&clipping);
3108 
3109 	BRect ellipseRect(cornerRect);
3110 	ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2;
3111 	ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2;
3112 
3113 	// bevel
3114 	BGradientLinear gradient;
3115 	gradient.AddColor(bevelLeftColor, 0);
3116 	gradient.AddColor(bevelBottomColor, 255);
3117 	gradient.SetStart(cornerRect.LeftTop());
3118 	gradient.SetEnd(cornerRect.RightBottom());
3119 	view->FillEllipse(ellipseRect, gradient);
3120 
3121 	// gradient
3122 	ellipseRect.InsetBy(1, 1);
3123 	view->FillEllipse(ellipseRect, fillGradient);
3124 }
3125 
3126 
3127 void
3128 BControlLook::_DrawRoundCornerRightBottom(BView* view, BRect& cornerRect,
3129 	const BRect& updateRect, const rgb_color& background,
3130 	const rgb_color& edgeColor, const rgb_color& frameColor,
3131 	const rgb_color& bevelColor, const BGradientLinear& fillGradient)
3132 {
3133 	_DrawRoundCornerFrameRightBottom(view, cornerRect, updateRect,
3134 		background, edgeColor, frameColor);
3135 	_DrawRoundCornerBackgroundRightBottom(view, cornerRect, updateRect,
3136 		bevelColor, fillGradient);
3137 }
3138 
3139 
3140 void
3141 BControlLook::_DrawRoundCornerFrameRightBottom(BView* view, BRect& cornerRect,
3142 	const BRect& updateRect, const rgb_color& background,
3143 	const rgb_color& edgeColor, const rgb_color& frameColor)
3144 {
3145 	// constrain clipping region to corner
3146 	BRegion clipping(cornerRect);
3147 	view->ConstrainClippingRegion(&clipping);
3148 
3149 	// background
3150 	view->SetHighColor(background);
3151 	view->FillRect(cornerRect);
3152 
3153 	// outer edge
3154 	BRect ellipseRect(cornerRect);
3155 	ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2;
3156 	ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2;
3157 
3158 	view->SetHighColor(edgeColor);
3159 	view->FillEllipse(ellipseRect);
3160 
3161 	// frame
3162 	ellipseRect.InsetBy(1, 1);
3163 	cornerRect.right--;
3164 	cornerRect.bottom++;
3165 	view->SetHighColor(frameColor);
3166 	view->FillEllipse(ellipseRect);
3167 
3168 	// prepare for bevel
3169 	cornerRect.left++;
3170 	cornerRect.bottom--;
3171 }
3172 
3173 
3174 void
3175 BControlLook::_DrawRoundCornerBackgroundRightBottom(BView* view,
3176 	BRect& cornerRect, const BRect& updateRect, const rgb_color& bevelColor,
3177 	const BGradientLinear& fillGradient)
3178 {
3179 	// constrain clipping region to corner
3180 	BRegion clipping(cornerRect);
3181 	view->ConstrainClippingRegion(&clipping);
3182 
3183 	BRect ellipseRect(cornerRect);
3184 	ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2;
3185 	ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2;
3186 
3187 	// bevel
3188 	view->SetHighColor(bevelColor);
3189 	view->FillEllipse(ellipseRect);
3190 
3191 	// gradient
3192 	ellipseRect.InsetBy(1, 1);
3193 	view->FillEllipse(ellipseRect, fillGradient);
3194 }
3195 
3196 
3197 void
3198 BControlLook::_DrawRoundBarCorner(BView* view, BRect& rect,
3199 	const BRect& updateRect,
3200 	const rgb_color& edgeLightColor, const rgb_color& edgeShadowColor,
3201 	const rgb_color& frameLightColor, const rgb_color& frameShadowColor,
3202 	const rgb_color& fillLightColor, const rgb_color& fillShadowColor,
3203 	float leftInset, float topInset, float rightInset, float bottomInset,
3204 	orientation orientation)
3205 {
3206 	if (!rect.IsValid() || !rect.Intersects(updateRect))
3207 		return;
3208 
3209 	BGradientLinear gradient;
3210 	gradient.AddColor(edgeShadowColor, 0);
3211 	gradient.AddColor(edgeLightColor, 255);
3212 	gradient.SetStart(rect.LeftTop());
3213 	if (orientation == B_HORIZONTAL)
3214 		gradient.SetEnd(rect.LeftBottom());
3215 	else
3216 		gradient.SetEnd(rect.RightTop());
3217 
3218 	view->FillEllipse(rect, gradient);
3219 
3220 	rect.left += leftInset;
3221 	rect.top += topInset;
3222 	rect.right += rightInset;
3223 	rect.bottom += bottomInset;
3224 
3225 	gradient.MakeEmpty();
3226 	gradient.AddColor(frameShadowColor, 0);
3227 	gradient.AddColor(frameLightColor, 255);
3228 	gradient.SetStart(rect.LeftTop());
3229 	if (orientation == B_HORIZONTAL)
3230 		gradient.SetEnd(rect.LeftBottom());
3231 	else
3232 		gradient.SetEnd(rect.RightTop());
3233 
3234 	view->FillEllipse(rect, gradient);
3235 
3236 	rect.left += leftInset;
3237 	rect.top += topInset;
3238 	rect.right += rightInset;
3239 	rect.bottom += bottomInset;
3240 
3241 	gradient.MakeEmpty();
3242 	gradient.AddColor(fillShadowColor, 0);
3243 	gradient.AddColor(fillLightColor, 255);
3244 	gradient.SetStart(rect.LeftTop());
3245 	if (orientation == B_HORIZONTAL)
3246 		gradient.SetEnd(rect.LeftBottom());
3247 	else
3248 		gradient.SetEnd(rect.RightTop());
3249 
3250 	view->FillEllipse(rect, gradient);
3251 }
3252 
3253 
3254 rgb_color
3255 BControlLook::_EdgeLightColor(const rgb_color& base, float contrast,
3256 	float brightness, uint32 flags)
3257 {
3258 	rgb_color edgeLightColor;
3259 
3260 	if ((flags & B_BLEND_FRAME) != 0) {
3261 		uint8 alpha = uint8(20 * contrast);
3262 		uint8 white = uint8(255 * brightness);
3263 
3264 		edgeLightColor = (rgb_color){ white, white, white, alpha };
3265 	} else {
3266 		// colors
3267 		float tintLight = kEdgeBevelLightTint;
3268 
3269 		if (contrast == 0.0)
3270 			tintLight = B_NO_TINT;
3271 		else if (contrast != 1.0)
3272 			tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast;
3273 
3274 		edgeLightColor = tint_color(base, tintLight);
3275 
3276 		if (brightness < 1.0) {
3277 			edgeLightColor.red = uint8(edgeLightColor.red * brightness);
3278 			edgeLightColor.green = uint8(edgeLightColor.green * brightness);
3279 			edgeLightColor.blue = uint8(edgeLightColor.blue * brightness);
3280 		}
3281 	}
3282 
3283 	return edgeLightColor;
3284 }
3285 
3286 
3287 rgb_color
3288 BControlLook::_EdgeShadowColor(const rgb_color& base, float contrast,
3289 	float brightness, uint32 flags)
3290 {
3291 	rgb_color edgeShadowColor;
3292 
3293 	if ((flags & B_BLEND_FRAME) != 0) {
3294 		uint8 alpha = uint8(20 * contrast);
3295 		edgeShadowColor = (rgb_color){ 0, 0, 0, alpha };
3296 	} else {
3297 		float tintShadow = kEdgeBevelShadowTint;
3298 
3299 		if (contrast == 0.0)
3300 			tintShadow = B_NO_TINT;
3301 		else if (contrast != 1.0)
3302 			tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast;
3303 
3304 		edgeShadowColor = tint_color(base, tintShadow);
3305 
3306 		if (brightness < 1.0) {
3307 			edgeShadowColor.red = uint8(edgeShadowColor.red * brightness);
3308 			edgeShadowColor.green = uint8(edgeShadowColor.green * brightness);
3309 			edgeShadowColor.blue = uint8(edgeShadowColor.blue * brightness);
3310 		}
3311 	}
3312 
3313 	return edgeShadowColor;
3314 }
3315 
3316 
3317 rgb_color
3318 BControlLook::_FrameLightColor(const rgb_color& base, uint32 flags)
3319 {
3320 	if ((flags & B_FOCUSED) != 0)
3321 		return ui_color(B_KEYBOARD_NAVIGATION_COLOR);
3322 
3323 	if ((flags & B_ACTIVATED) != 0)
3324 		return _FrameShadowColor(base, flags & ~B_ACTIVATED);
3325 
3326 	rgb_color frameLightColor;
3327 
3328 	if ((flags & B_DISABLED) != 0) {
3329 		// TODO: B_BLEND_FRAME
3330 		frameLightColor = tint_color(base, 1.145);
3331 
3332 		if ((flags & B_DEFAULT_BUTTON) != 0)
3333 			frameLightColor = tint_color(frameLightColor, 1.14);
3334 	} else {
3335 		if ((flags & B_BLEND_FRAME) != 0)
3336 			frameLightColor = (rgb_color){ 0, 0, 0, 75 };
3337 		else
3338 			frameLightColor = tint_color(base, 1.33);
3339 
3340 		if ((flags & B_DEFAULT_BUTTON) != 0)
3341 			frameLightColor = tint_color(frameLightColor, 1.35);
3342 	}
3343 
3344 	return frameLightColor;
3345 }
3346 
3347 
3348 rgb_color
3349 BControlLook::_FrameShadowColor(const rgb_color& base, uint32 flags)
3350 {
3351 	if ((flags & B_FOCUSED) != 0)
3352 		return ui_color(B_KEYBOARD_NAVIGATION_COLOR);
3353 
3354 	if ((flags & B_ACTIVATED) != 0)
3355 		return _FrameLightColor(base, flags & ~B_ACTIVATED);
3356 
3357 	rgb_color frameShadowColor;
3358 
3359 	if ((flags & B_DISABLED) != 0) {
3360 		// TODO: B_BLEND_FRAME
3361 		frameShadowColor = tint_color(base, 1.24);
3362 
3363 		if ((flags & B_DEFAULT_BUTTON) != 0) {
3364 			frameShadowColor = tint_color(base, 1.145);
3365 			frameShadowColor = tint_color(frameShadowColor, 1.12);
3366 		}
3367 	} else {
3368 		if ((flags & B_DEFAULT_BUTTON) != 0) {
3369 			if ((flags & B_BLEND_FRAME) != 0)
3370 				frameShadowColor = (rgb_color){ 0, 0, 0, 75 };
3371 			else
3372 				frameShadowColor = tint_color(base, 1.33);
3373 
3374 			frameShadowColor = tint_color(frameShadowColor, 1.5);
3375 		} else {
3376 			if ((flags & B_BLEND_FRAME) != 0)
3377 				frameShadowColor = (rgb_color){ 0, 0, 0, 95 };
3378 			else
3379 				frameShadowColor = tint_color(base, 1.47);
3380 		}
3381 	}
3382 
3383 	return frameShadowColor;
3384 }
3385 
3386 
3387 rgb_color
3388 BControlLook::_BevelLightColor(const rgb_color& base, uint32 flags)
3389 {
3390 	rgb_color bevelLightColor = tint_color(base, 0.2);
3391 
3392 	if ((flags & B_DISABLED) != 0)
3393 		bevelLightColor = tint_color(base, B_LIGHTEN_1_TINT);
3394 
3395 	if ((flags & B_ACTIVATED) != 0)
3396 		bevelLightColor = tint_color(base, B_DARKEN_1_TINT);
3397 
3398 	return bevelLightColor;
3399 }
3400 
3401 
3402 rgb_color
3403 BControlLook::_BevelShadowColor(const rgb_color& base, uint32 flags)
3404 {
3405 	rgb_color bevelShadowColor = tint_color(base, 1.08);
3406 
3407 	if ((flags & B_DISABLED) != 0)
3408 		bevelShadowColor = base;
3409 
3410 	if ((flags & B_ACTIVATED) != 0)
3411 		bevelShadowColor = tint_color(base, B_DARKEN_1_TINT);
3412 
3413 	return bevelShadowColor;
3414 }
3415 
3416 
3417 void
3418 BControlLook::_FillGradient(BView* view, const BRect& rect,
3419 	const rgb_color& base, float topTint, float bottomTint,
3420 	orientation orientation)
3421 {
3422 	BGradientLinear gradient;
3423 	_MakeGradient(gradient, rect, base, topTint, bottomTint, orientation);
3424 	view->FillRect(rect, gradient);
3425 }
3426 
3427 
3428 void
3429 BControlLook::_FillGlossyGradient(BView* view, const BRect& rect,
3430 	const rgb_color& base, float topTint, float middle1Tint,
3431 	float middle2Tint, float bottomTint, orientation orientation)
3432 {
3433 	BGradientLinear gradient;
3434 	_MakeGlossyGradient(gradient, rect, base, topTint, middle1Tint,
3435 		middle2Tint, bottomTint, orientation);
3436 	view->FillRect(rect, gradient);
3437 }
3438 
3439 
3440 void
3441 BControlLook::_MakeGradient(BGradientLinear& gradient, const BRect& rect,
3442 	const rgb_color& base, float topTint, float bottomTint,
3443 	orientation orientation) const
3444 {
3445 	gradient.AddColor(tint_color(base, topTint), 0);
3446 	gradient.AddColor(tint_color(base, bottomTint), 255);
3447 	gradient.SetStart(rect.LeftTop());
3448 	if (orientation == B_HORIZONTAL)
3449 		gradient.SetEnd(rect.LeftBottom());
3450 	else
3451 		gradient.SetEnd(rect.RightTop());
3452 }
3453 
3454 
3455 void
3456 BControlLook::_MakeGlossyGradient(BGradientLinear& gradient, const BRect& rect,
3457 	const rgb_color& base, float topTint, float middle1Tint,
3458 	float middle2Tint, float bottomTint,
3459 	orientation orientation) const
3460 {
3461 	gradient.AddColor(tint_color(base, topTint), 0);
3462 	gradient.AddColor(tint_color(base, middle1Tint), 132);
3463 	gradient.AddColor(tint_color(base, middle2Tint), 136);
3464 	gradient.AddColor(tint_color(base, bottomTint), 255);
3465 	gradient.SetStart(rect.LeftTop());
3466 	if (orientation == B_HORIZONTAL)
3467 		gradient.SetEnd(rect.LeftBottom());
3468 	else
3469 		gradient.SetEnd(rect.RightTop());
3470 }
3471 
3472 
3473 void
3474 BControlLook::_MakeButtonGradient(BGradientLinear& gradient, BRect& rect,
3475 	const rgb_color& base, uint32 flags, orientation orientation) const
3476 {
3477 	float topTint = 0.49;
3478 	float middleTint1 = 0.62;
3479 	float middleTint2 = 0.76;
3480 	float bottomTint = 0.90;
3481 
3482 	if ((flags & B_ACTIVATED) != 0) {
3483 		topTint = 1.11;
3484 		bottomTint = 1.08;
3485 	}
3486 
3487 	if ((flags & B_DISABLED) != 0) {
3488 		topTint = (topTint + B_NO_TINT) / 2;
3489 		middleTint1 = (middleTint1 + B_NO_TINT) / 2;
3490 		middleTint2 = (middleTint2 + B_NO_TINT) / 2;
3491 		bottomTint = (bottomTint + B_NO_TINT) / 2;
3492 	} else if ((flags & B_HOVER) != 0) {
3493 		topTint *= kHoverTintFactor;
3494 		middleTint1 *= kHoverTintFactor;
3495 		middleTint2 *= kHoverTintFactor;
3496 		bottomTint *= kHoverTintFactor;
3497 	}
3498 
3499 	if ((flags & B_ACTIVATED) != 0) {
3500 		_MakeGradient(gradient, rect, base, topTint, bottomTint, orientation);
3501 	} else {
3502 		_MakeGlossyGradient(gradient, rect, base, topTint, middleTint1,
3503 			middleTint2, bottomTint, orientation);
3504 	}
3505 }
3506 
3507 
3508 
3509 bool
3510 BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base,
3511 	rgb_color& color, uint32 flags) const
3512 {
3513 	if ((flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED | B_CLICKED)) == 0) {
3514 		// no mark to be drawn at all
3515 		return false;
3516 	}
3517 
3518 	color = ui_color(B_CONTROL_MARK_COLOR);
3519 
3520 	float mix = 1.0;
3521 
3522 	if ((flags & B_DISABLED) != 0) {
3523 		// activated, but disabled
3524 		mix = 0.4;
3525 	} else if ((flags & B_CLICKED) != 0) {
3526 		if ((flags & B_ACTIVATED) != 0) {
3527 			// losing activation
3528 			mix = 0.7;
3529 		} else {
3530 			// becoming activated (or losing partial activation)
3531 			mix = 0.3;
3532 		}
3533 	} else if ((flags & B_PARTIALLY_ACTIVATED) != 0) {
3534 		// partially activated
3535 		mix = 0.5;
3536 	} else {
3537 		// simply activated
3538 	}
3539 
3540 	color.red = uint8(color.red * mix + base.red * (1.0 - mix));
3541 	color.green = uint8(color.green * mix + base.green * (1.0 - mix));
3542 	color.blue = uint8(color.blue * mix + base.blue * (1.0 - mix));
3543 
3544 	return true;
3545 }
3546 
3547 
3548 // NOTE: May come from a add-on in the future. Initialized in
3549 // InterfaceDefs.cpp
3550 BControlLook* be_control_look = NULL;
3551 
3552 
3553 } // namespace BPrivate
3554