1/*
2 * Copyright 2010, Stephan A��mus <superstippi@gmx.de>.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "SymbolButton.h"
8
9#include <GradientLinear.h>
10#include <LayoutUtils.h>
11#include <Shape.h>
12
13
14static const rgb_color kGreen = (rgb_color){ 116, 224, 0, 255 };
15
16
17// constructor
18SymbolButton::SymbolButton(const char* name, BShape* symbolShape,
19		BMessage* message, uint32 borders)
20	:
21	BButton(name, NULL, message),
22	fSymbol(symbolShape),
23	fBorders(borders)
24{
25}
26
27
28SymbolButton::~SymbolButton()
29{
30	delete fSymbol;
31}
32
33
34void
35SymbolButton::Draw(BRect updateRect)
36{
37	uint32 flags = be_control_look->Flags(this);
38	rgb_color base = LowColor();
39	BRect bounds(Bounds());
40
41	if (fBorders != 0) {
42		be_control_look->DrawButtonFrame(this, bounds, updateRect, base,
43			base, flags & ~BControlLook::B_DISABLED, fBorders);
44		be_control_look->DrawButtonBackground(this, bounds, updateRect, base,
45			flags);
46	}
47
48	if (fSymbol == NULL)
49		return;
50
51	if (IsEnabled()) {
52		if (Value() == B_CONTROL_ON)
53			base = tint_color(base, (B_DARKEN_4_TINT + B_DARKEN_MAX_TINT) / 2);
54		else
55			base = tint_color(base, B_DARKEN_4_TINT);
56	} else {
57		if (Value() == B_CONTROL_ON)
58			base = tint_color(base, B_DARKEN_2_TINT);
59		else
60			base = tint_color(base, B_DARKEN_1_TINT);
61	}
62
63	BPoint offset;
64	offset.x = (bounds.left + bounds.right) / 2;
65	offset.y = (bounds.top + bounds.bottom) / 2;
66	offset.x -= fSymbol->Bounds().Width() / 2;
67	offset.y -= fSymbol->Bounds().Height() / 2;
68	offset.x = floorf(offset.x - fSymbol->Bounds().left);
69	offset.y = ceilf(offset.y - fSymbol->Bounds().top);
70
71	MovePenTo(offset);
72	BGradientLinear gradient;
73	gradient.AddColor(tint_color(base, B_DARKEN_1_TINT), 0);
74	gradient.AddColor(base, 255);
75	gradient.SetStart(offset);
76	offset.y += fSymbol->Bounds().Height();
77	gradient.SetEnd(offset);
78	FillShape(fSymbol, gradient);
79}
80
81
82BSize
83SymbolButton::MinSize()
84{
85	if (fSymbol == NULL)
86		return BButton::MinSize();
87
88	float scale = fBorders != 0 ? 2.5f : 1.0f;
89
90	BSize size;
91	size.width = ceilf(fSymbol->Bounds().Width() * scale);
92	size.height = ceilf(fSymbol->Bounds().Height() * scale);
93	return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
94}
95
96
97BSize
98SymbolButton::MaxSize()
99{
100	BSize size(MinSize());
101	if (fBorders != 0)
102		size.width = ceilf(size.width * 1.5f);
103	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
104}
105
106
107void
108SymbolButton::SetSymbol(BShape* symbolShape)
109{
110	BSize oldSize = MinSize();
111
112	delete fSymbol;
113	fSymbol = symbolShape;
114
115	if (MinSize() != oldSize)
116		InvalidateLayout();
117
118	Invalidate();
119}
120
121