xref: /haiku/src/kits/tracker/DialogPane.cpp (revision 20f2ebae4b5ae0f52ac776a214bf0a9b0a9af98f)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 
35 
36 #include "DialogPane.h"
37 
38 #include <ControlLook.h>
39 #include <LayoutUtils.h>
40 
41 #include "Utilities.h"
42 #include "Window.h"
43 
44 
45 const rgb_color kNormalColor = {150, 150, 150, 255};
46 const rgb_color kHighlightColor = {100, 100, 0, 255};
47 
48 
49 //	#pragma mark - PaneSwitch
50 
51 
PaneSwitch(BRect frame,const char * name,bool leftAligned,uint32 resizeMask,uint32 flags)52 PaneSwitch::PaneSwitch(BRect frame, const char* name, bool leftAligned,
53 		uint32 resizeMask, uint32 flags)
54 	:
55 	BControl(frame, name, "", 0, resizeMask, flags),
56 	fLeftAligned(leftAligned),
57 	fPressing(false),
58 	fLabelOn(NULL),
59 	fLabelOff(NULL)
60 {
61 }
62 
63 
PaneSwitch(const char * name,bool leftAligned,uint32 flags)64 PaneSwitch::PaneSwitch(const char* name, bool leftAligned, uint32 flags)
65 	:
66 	BControl(name, "", 0, flags),
67 	fLeftAligned(leftAligned),
68 	fPressing(false),
69 	fLabelOn(NULL),
70 	fLabelOff(NULL)
71 {
72 }
73 
74 
~PaneSwitch()75 PaneSwitch::~PaneSwitch()
76 {
77 	free(fLabelOn);
78 	free(fLabelOff);
79 }
80 
81 
82 void
Draw(BRect)83 PaneSwitch::Draw(BRect)
84 {
85 	BRect bounds(Bounds());
86 
87 	// Draw the label, if any
88 	const char* label = fLabelOff;
89 	if (fLabelOn != NULL && Value() == B_CONTROL_ON)
90 		label = fLabelOn;
91 
92 	if (label != NULL) {
93 		BPoint point;
94 		float latchSize = be_plain_font->Size();
95 		float labelDist = latchSize + ceilf(latchSize / 2.0);
96 		if (fLeftAligned)
97 			point.x = labelDist;
98 		else
99 			point.x = bounds.right - labelDist - StringWidth(label);
100 
101 		SetHighUIColor(B_PANEL_TEXT_COLOR);
102 		font_height fontHeight;
103 		GetFontHeight(&fontHeight);
104 		point.y = (bounds.top + bounds.bottom
105 			- ceilf(fontHeight.ascent) - ceilf(fontHeight.descent)) / 2
106 			+ ceilf(fontHeight.ascent);
107 
108 		DrawString(label, point);
109 	}
110 
111 	// draw the latch
112 	if (fPressing)
113 		DrawInState(kPressed);
114 	else if (Value())
115 		DrawInState(kExpanded);
116 	else
117 		DrawInState(kCollapsed);
118 
119 	// ...and the focus indication
120 	if (!IsFocus() || !Window()->IsActive())
121 		return;
122 
123 	rgb_color markColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR);
124 
125 	BeginLineArray(2);
126 	AddLine(BPoint(bounds.left + 2, bounds.bottom - 1),
127 		BPoint(bounds.right - 2, bounds.bottom - 1), markColor);
128 	AddLine(BPoint(bounds.left + 2, bounds.bottom),
129 		BPoint(bounds.right - 2, bounds.bottom), kWhite);
130 	EndLineArray();
131 }
132 
133 
134 void
MouseDown(BPoint)135 PaneSwitch::MouseDown(BPoint)
136 {
137 	if (!IsEnabled())
138 		return;
139 
140 	fPressing = true;
141 	SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
142 	Invalidate();
143 }
144 
145 
146 void
MouseMoved(BPoint point,uint32 code,const BMessage * message)147 PaneSwitch::MouseMoved(BPoint point, uint32 code, const BMessage* message)
148 {
149 	int32 buttons;
150 	BMessage* currentMessage = Window()->CurrentMessage();
151 	if (currentMessage == NULL
152 		|| currentMessage->FindInt32("buttons", &buttons) != B_OK) {
153 		buttons = 0;
154 	}
155 
156 	if (buttons != 0) {
157 		BRect bounds(Bounds());
158 		bounds.InsetBy(-3, -3);
159 
160 		bool newPressing = bounds.Contains(point);
161 		if (newPressing != fPressing) {
162 			fPressing = newPressing;
163 			Invalidate();
164 		}
165 	}
166 
167 	BControl::MouseMoved(point, code, message);
168 }
169 
170 
171 void
MouseUp(BPoint point)172 PaneSwitch::MouseUp(BPoint point)
173 {
174 	BRect bounds(Bounds());
175 	bounds.InsetBy(-3, -3);
176 
177 	fPressing = false;
178 	Invalidate();
179 	if (bounds.Contains(point)) {
180 		SetValue(!Value());
181 		Invoke();
182 	}
183 
184 	BControl::MouseUp(point);
185 }
186 
187 
188 void
GetPreferredSize(float * _width,float * _height)189 PaneSwitch::GetPreferredSize(float* _width, float* _height)
190 {
191 	BSize size = MinSize();
192 	if (_width != NULL)
193 		*_width = size.width;
194 
195 	if (_height != NULL)
196 		*_height = size.height;
197 }
198 
199 
200 BSize
MinSize()201 PaneSwitch::MinSize()
202 {
203 	BSize size;
204 	float onLabelWidth = StringWidth(fLabelOn);
205 	float offLabelWidth = StringWidth(fLabelOff);
206 	float labelWidth = max_c(onLabelWidth, offLabelWidth);
207 	float latchSize = be_plain_font->Size();
208 	size.width = latchSize;
209 	if (labelWidth > 0.0)
210 		size.width += ceilf(latchSize / 2.0) + labelWidth;
211 
212 	font_height fontHeight;
213 	GetFontHeight(&fontHeight);
214 	size.height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent);
215 	size.height = max_c(size.height, latchSize);
216 
217 	return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
218 }
219 
220 
221 BSize
MaxSize()222 PaneSwitch::MaxSize()
223 {
224 	return BLayoutUtils::ComposeSize(ExplicitMaxSize(), MinSize());
225 }
226 
227 
228 BSize
PreferredSize()229 PaneSwitch::PreferredSize()
230 {
231 	return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize());
232 }
233 
234 
235 void
SetLabels(const char * labelOn,const char * labelOff)236 PaneSwitch::SetLabels(const char* labelOn, const char* labelOff)
237 {
238 	free(fLabelOn);
239 	free(fLabelOff);
240 
241 	if (labelOn != NULL)
242 		fLabelOn = strdup(labelOn);
243 	else
244 		fLabelOn = NULL;
245 
246 	if (labelOff != NULL)
247 		fLabelOff = strdup(labelOff);
248 	else
249 		fLabelOff = NULL;
250 
251 	Invalidate();
252 	InvalidateLayout();
253 }
254 
255 
256 void
DrawInState(PaneSwitch::State state)257 PaneSwitch::DrawInState(PaneSwitch::State state)
258 {
259 	BRect rect(0, 0, be_plain_font->Size(), be_plain_font->Size());
260 	rect.OffsetBy(1, 1);
261 
262 	rgb_color arrowColor = state == kPressed ? kHighlightColor : kNormalColor;
263 	int32 arrowDirection = BControlLook::B_RIGHT_ARROW;
264 	float tint = IsEnabled() && Window()->IsActive() ? B_DARKEN_3_TINT
265 		: B_DARKEN_1_TINT;
266 
267 	switch (state) {
268 		case kCollapsed:
269 			arrowDirection = BControlLook::B_RIGHT_ARROW;
270 			break;
271 
272 		case kPressed:
273 			arrowDirection = BControlLook::B_RIGHT_DOWN_ARROW;
274 			break;
275 
276 		case kExpanded:
277 			arrowDirection = BControlLook::B_DOWN_ARROW;
278 			break;
279 	}
280 
281 	SetDrawingMode(B_OP_COPY);
282 	be_control_look->DrawArrowShape(this, rect, rect, arrowColor,
283 		arrowDirection, 0, tint);
284 }
285