xref: /haiku/src/kits/interface/CheckBox.cpp (revision 7120e97489acbf17d86d3f33e3b2e68974fd4b23)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		CheckBox.cpp
23 //	Author:			Marc Flerackers (mflerackers@androme.be)
24 //	Description:	BCheckBox displays an on/off control.
25 //------------------------------------------------------------------------------
26 
27 // Standard Includes -----------------------------------------------------------
28 
29 // System Includes -------------------------------------------------------------
30 #include <CheckBox.h>
31 #include <Errors.h>
32 
33 // Project Includes ------------------------------------------------------------
34 
35 // Local Includes --------------------------------------------------------------
36 
37 // Local Defines ---------------------------------------------------------------
38 
39 // Globals ---------------------------------------------------------------------
40 
41 //------------------------------------------------------------------------------
42 BCheckBox::BCheckBox(BRect frame, const char *name, const char *label,
43 					 BMessage *message, uint32 resizingMode, uint32 flags)
44 	:	BControl(frame, name, label, message, resizingMode, flags)
45 {
46 	fOutlined = false;
47 
48 	if (Bounds().Height() < 18.0f)
49 		ResizeTo(Bounds().Width(), 18.0f);
50 }
51 //------------------------------------------------------------------------------
52 BCheckBox::~BCheckBox()
53 {
54 
55 }
56 //------------------------------------------------------------------------------
57 BCheckBox::BCheckBox(BMessage *archive)
58 	:	BControl(archive)
59 {
60 	fOutlined = false;
61 }
62 //------------------------------------------------------------------------------
63 BArchivable *BCheckBox::Instantiate(BMessage *archive)
64 {
65 	if (validate_instantiation(archive, "BCheckBox"))
66 		return new BCheckBox(archive);
67 	else
68 		return NULL;
69 }
70 //------------------------------------------------------------------------------
71 status_t BCheckBox::Archive(BMessage *archive, bool deep) const
72 {
73 	return BControl::Archive(archive,deep);
74 }
75 //------------------------------------------------------------------------------
76 void BCheckBox::Draw(BRect updateRect)
77 {
78 	rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR),
79 	lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT),
80 	lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT),
81 	darken1 = tint_color(no_tint, B_DARKEN_1_TINT),
82 	darken2 = tint_color(no_tint, B_DARKEN_2_TINT),
83 	darken3 = tint_color(no_tint, B_DARKEN_3_TINT),
84 	darken4 = tint_color(no_tint, B_DARKEN_4_TINT),
85 	darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT);
86 
87 	BRect rect(1.0, 3.0, 13.0, 15.0);
88 
89 	if (IsEnabled())
90 	{
91 		// Filling
92 		SetHighColor(lightenmax);
93 		FillRect(rect);
94 
95 		// Box
96 		if (fOutlined)
97 		{
98 			SetHighColor(darken3);
99 			StrokeRect(rect);
100 
101 			rect.InsetBy(1,1);
102 
103 			BeginLineArray(6);
104 
105 			AddLine(BPoint(rect.left, rect.bottom),
106 					BPoint(rect.left, rect.top), darken2);
107 			AddLine(BPoint(rect.left, rect.top),
108 					BPoint(rect.right, rect.top), darken2);
109 			AddLine(BPoint(rect.left, rect.bottom),
110 					BPoint(rect.right, rect.bottom), darken4);
111 			AddLine(BPoint(rect.right, rect.bottom),
112 					BPoint(rect.right, rect.top), darken4);
113 
114 			EndLineArray();
115 		}
116 		else
117 		{
118 			BeginLineArray(6);
119 
120 			AddLine(BPoint(rect.left, rect.bottom),
121 					BPoint(rect.left, rect.top), darken1);
122 			AddLine(BPoint(rect.left, rect.top),
123 					BPoint(rect.right, rect.top), darken1);
124 			rect.InsetBy(1,1);
125 			AddLine(BPoint(rect.left, rect.bottom),
126 					BPoint(rect.left, rect.top), darken4);
127 			AddLine(BPoint(rect.left, rect.top),
128 					BPoint(rect.right, rect.top), darken4);
129 			AddLine(BPoint(rect.left + 1.0f, rect.bottom),
130 					BPoint(rect.right, rect.bottom), no_tint);
131 			AddLine(BPoint(rect.right, rect.bottom),
132 					BPoint(rect.right, rect.top + 1.0f), no_tint);
133 
134 			EndLineArray();
135 		}
136 
137 		// Checkmark
138 		if (Value() == B_CONTROL_ON)
139 		{
140 			rect.InsetBy(2,2);
141 
142 			SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
143 			SetPenSize(2);
144 			StrokeLine(BPoint(rect.left, rect.top),
145 					   BPoint(rect.right, rect.bottom));
146 			StrokeLine(BPoint(rect.left, rect.bottom),
147 					   BPoint(rect.right, rect.top));
148 			SetPenSize(1);
149 		}
150 
151 		// Label
152 		BFont font;
153 		GetFont(&font);
154 		font_height fh;
155 		font.GetHeight(&fh);
156 
157 		SetHighColor(darkenmax);
158 		DrawString(Label(), BPoint(20.0f, 8.0f + (float)ceil(fh.ascent / 2.0f)));
159 
160 		// Focus
161 		if (IsFocus())
162 		{
163 			float h = 8.0f + (float)ceil(fh.ascent / 2.0f) + 2.0f;
164 
165 			SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
166 			StrokeLine(BPoint(20.0f, h), BPoint(20.0f + StringWidth(Label()), h));
167 		}
168 	}
169 	else
170 	{
171 		// Filling
172 		SetHighColor(lighten1);
173 		FillRect(rect);
174 
175 		// Box
176 		BeginLineArray(6);
177 
178 		AddLine(BPoint(rect.left, rect.bottom),
179 				BPoint(rect.left, rect.top), no_tint);
180 		AddLine(BPoint(rect.left, rect.top),
181 				BPoint(rect.right, rect.top), no_tint);
182 		rect.InsetBy(1,1);
183 		AddLine(BPoint(rect.left, rect.bottom),
184 				BPoint(rect.left, rect.top), darken2);
185 		AddLine(BPoint(rect.left, rect.top),
186 				BPoint(rect.right, rect.top), darken2);
187 		AddLine(BPoint(rect.left + 1.0f, rect.bottom),
188 				BPoint(rect.right, rect.bottom), darken1);
189 		AddLine(BPoint(rect.right, rect.bottom),
190 				BPoint(rect.right, rect.top + 1.0f), darken1);
191 
192 		EndLineArray();
193 
194 		// Checkmark
195 		if (Value() == B_CONTROL_ON)
196 		{
197 			rect.InsetBy(2, 2);
198 
199 			SetHighColor(tint_color(ui_color(B_KEYBOARD_NAVIGATION_COLOR),
200 				B_DISABLED_MARK_TINT));
201 			SetPenSize(2);
202 			StrokeLine(BPoint(rect.left, rect.top),
203 					   BPoint(rect.right, rect.bottom));
204 			StrokeLine(BPoint(rect.left, rect.bottom),
205 					   BPoint(rect.right, rect.top));
206 			SetPenSize(1);
207 		}
208 
209 		// Label
210 		BFont font;
211 		GetFont(&font);
212 		font_height fh;
213 		font.GetHeight(&fh);
214 
215 		SetHighColor(tint_color(no_tint, B_DISABLED_LABEL_TINT));
216 		DrawString(Label(), BPoint(20.0f, 8.0f + (float)ceil(fh.ascent / 2.0f)));
217 	}
218 }
219 //------------------------------------------------------------------------------
220 void BCheckBox::AttachedToWindow()
221 {
222 	BControl::AttachedToWindow();
223 }
224 //------------------------------------------------------------------------------
225 void BCheckBox::MouseDown(BPoint point)
226 {
227 	if (!IsEnabled())
228 	{
229 		BControl::MouseDown(point);
230 		return;
231 	}
232 
233 	SetMouseEventMask(B_POINTER_EVENTS,	B_NO_POINTER_HISTORY |
234 					  B_SUSPEND_VIEW_FOCUS);
235 
236 	fOutlined = true;
237 	SetTracking(true);
238 	Invalidate();
239 }
240 //------------------------------------------------------------------------------
241 void BCheckBox::MessageReceived(BMessage *message)
242 {
243 	BControl::MessageReceived(message);
244 }
245 //------------------------------------------------------------------------------
246 void BCheckBox::WindowActivated(bool active)
247 {
248 	BControl::WindowActivated(active);
249 }
250 //------------------------------------------------------------------------------
251 void BCheckBox::KeyDown(const char *bytes, int32 numBytes)
252 {
253 //	if (*((int*)bytes) == VK_RETURN || *((int*)bytes) == VK_SPACE)
254 //		SetValue(Value() ? 0 : 1);
255 //	else
256 //	{
257 //		SetValue(0);
258 		BControl::KeyDown(bytes, numBytes);
259 //	}
260 }
261 //------------------------------------------------------------------------------
262 void BCheckBox::MouseUp(BPoint point)
263 {
264 	if (IsEnabled() && IsTracking())
265 	{
266 		fOutlined = false;
267 
268 		if (Bounds().Contains(point))
269 		{
270 			if (Value() == B_CONTROL_OFF)
271 				SetValue(B_CONTROL_ON);
272 			else
273 				SetValue(B_CONTROL_OFF);
274 
275 			BControl::Invoke();
276 		}
277 		SetTracking(false);
278 	}
279 	else
280 	{
281 		BControl::MouseUp(point);
282 		return;
283 	}
284 }
285 //------------------------------------------------------------------------------
286 void BCheckBox::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
287 {
288 	if (IsEnabled() && IsTracking())
289 	{
290 		if (transit == B_EXITED_VIEW)
291 			fOutlined = false;
292 		else if (transit == B_ENTERED_VIEW)
293 			fOutlined = true;
294 
295 		Invalidate();
296 	}
297 	else
298 		BControl::MouseMoved(point, transit, message);
299 }
300 //------------------------------------------------------------------------------
301 void BCheckBox::DetachedFromWindow()
302 {
303 	BControl::DetachedFromWindow();
304 }
305 //------------------------------------------------------------------------------
306 void BCheckBox::SetValue(int32 value)
307 {
308 	BControl::SetValue(value);
309 }
310 //------------------------------------------------------------------------------
311 void BCheckBox::GetPreferredSize(float *width, float *height)
312 {
313 	font_height fh;
314 	GetFontHeight(&fh);
315 
316 	*height = (float)ceil(fh.ascent + fh.descent + fh.leading) + 6.0f;
317 	*width = 22.0f + (float)ceil(StringWidth(Label()));
318 }
319 //------------------------------------------------------------------------------
320 void BCheckBox::ResizeToPreferred()
321 {
322 	float widht, height;
323 	GetPreferredSize(&widht, &height);
324 	BView::ResizeTo(widht,height);
325 }
326 //------------------------------------------------------------------------------
327 status_t BCheckBox::Invoke(BMessage *message)
328 {
329 	return BControl::Invoke(message);
330 }
331 //------------------------------------------------------------------------------
332 void BCheckBox::FrameMoved(BPoint newLocation)
333 {
334 	BControl::FrameMoved(newLocation);
335 }
336 //------------------------------------------------------------------------------
337 void BCheckBox::FrameResized(float width, float height)
338 {
339 	BControl::FrameResized(width, height);
340 }
341 //------------------------------------------------------------------------------
342 BHandler *BCheckBox::ResolveSpecifier(BMessage *message, int32 index,
343 									  BMessage *specifier, int32 what,
344 									  const char *property)
345 {
346 	return BControl::ResolveSpecifier(message, index, specifier, what, property);
347 }
348 //------------------------------------------------------------------------------
349 status_t BCheckBox::GetSupportedSuites(BMessage *message)
350 {
351 	return BControl::GetSupportedSuites(message);
352 }
353 //------------------------------------------------------------------------------
354 void BCheckBox::MakeFocus(bool focused)
355 {
356 	BControl::MakeFocus(focused);
357 }
358 //------------------------------------------------------------------------------
359 void BCheckBox::AllAttached()
360 {
361 	BControl::AllAttached();
362 }
363 //------------------------------------------------------------------------------
364 void BCheckBox::AllDetached()
365 {
366 	BControl::AllDetached();
367 }
368 //------------------------------------------------------------------------------
369 status_t BCheckBox::Perform(perform_code d, void *arg)
370 {
371 	return B_ERROR;
372 }
373 //------------------------------------------------------------------------------
374 void BCheckBox::_ReservedCheckBox1() {}
375 void BCheckBox::_ReservedCheckBox2() {}
376 void BCheckBox::_ReservedCheckBox3() {}
377 //------------------------------------------------------------------------------
378 BCheckBox &BCheckBox::operator=(const BCheckBox &)
379 {
380 	return *this;
381 }
382 //------------------------------------------------------------------------------
383 
384 /*
385  * $Log $
386  *
387  * $Id  $
388  *
389  */
390