xref: /haiku/src/kits/interface/PictureButton.cpp (revision 0562493379cd52eb7103531f895f10bb8e77c085)
1 /*
2  * Copyright 2001-2009, Haiku, Inc.
3  * Distributed under the terms of the MIT license.
4  *
5  * Authors:
6  *		Graham MacDonald (macdonag@btopenworld.com)
7  */
8 
9 #include <PictureButton.h>
10 
11 #include <binary_compatibility/Interface.h>
12 
13 #include <new>
14 
15 
16 BPictureButton::BPictureButton(BRect frame, const char* name,
17 		BPicture* off, BPicture* on, BMessage* message,
18 		uint32 behavior, uint32 resizeMask, uint32 flags)
19 	: BControl(frame, name, "", message, resizeMask, flags),
20 	  fDisabledOff(NULL),
21 	  fDisabledOn(NULL),
22 	  fBehavior(behavior)
23 {
24 	fEnabledOff = new (std::nothrow)BPicture(*off);
25 	fEnabledOn = new (std::nothrow) BPicture(*on);
26 }
27 
28 
29 BPictureButton::BPictureButton(BMessage* data)
30 	: BControl(data),
31 	fEnabledOff(NULL),
32 	fEnabledOn(NULL),
33 	fDisabledOff(NULL),
34 	fDisabledOn(NULL)
35 {
36 	BMessage pictureArchive;
37 
38 	// Default to 1 state button if not here - is this valid?
39 	if (data->FindInt32 ("_behave", (int32* )&fBehavior) != B_OK)
40 		fBehavior = B_ONE_STATE_BUTTON;
41 
42 	// Now expand the pictures:
43 	if (data->FindMessage("_e_on", &pictureArchive) == B_OK)
44 		fEnabledOn = new (std::nothrow) BPicture(&pictureArchive);
45 
46 	if (data->FindMessage("_e_off", &pictureArchive) == B_OK)
47 		fEnabledOff = new (std::nothrow) BPicture(&pictureArchive);
48 
49 	if (data->FindMessage("_d_on", &pictureArchive) == B_OK)
50 		fDisabledOn = new (std::nothrow) BPicture(&pictureArchive);
51 
52 	if (data->FindMessage("_d_off", &pictureArchive) == B_OK)
53 		fDisabledOff = new (std::nothrow) BPicture(&pictureArchive);
54 }
55 
56 
57 BPictureButton::~BPictureButton()
58 {
59 	delete fEnabledOn;
60 	delete fEnabledOff;
61 	delete fDisabledOn;
62 	delete fDisabledOff;
63 }
64 
65 
66 BArchivable*
67 BPictureButton::Instantiate(BMessage* data)
68 {
69 	if ( validate_instantiation(data, "BPictureButton"))
70 		return new (std::nothrow) BPictureButton(data);
71 
72 	return NULL;
73 }
74 
75 
76 status_t
77 BPictureButton::Archive(BMessage* data, bool deep) const
78 {
79 	status_t err = BControl::Archive(data, deep);
80 	if (err != B_OK)
81 		return err;
82 
83 	// Fill out message, depending on whether a deep copy is required or not.
84 	if (deep) {
85 		BMessage pictureArchive;
86 
87 		if (fEnabledOn->Archive(&pictureArchive, deep) == B_OK) {
88 			err = data->AddMessage("_e_on", &pictureArchive);
89 			if (err != B_OK)
90 				return err;
91 		}
92 
93 		if (fEnabledOff->Archive(&pictureArchive, deep) == B_OK) {
94 			err = data->AddMessage("_e_off", &pictureArchive);
95 			if (err != B_OK)
96 				return err;
97 		}
98 
99 		if (fDisabledOn && fDisabledOn->Archive(&pictureArchive, deep) == B_OK) {
100 			err = data->AddMessage("_d_on", &pictureArchive);
101 			if (err != B_OK)
102 				return err;
103 		}
104 
105 		if (fDisabledOff && fDisabledOff->Archive(&pictureArchive, deep) == B_OK) {
106 			err = data->AddMessage("_d_off", &pictureArchive);
107 			if (err != B_OK)
108 				return err;
109 		}
110 	}
111 
112 	return data->AddInt32("_behave", fBehavior);
113 }
114 
115 
116 void
117 BPictureButton::Draw(BRect updateRect)
118 {
119 	if (IsEnabled()) {
120 		if (Value() == B_CONTROL_ON)
121 			DrawPicture(fEnabledOn);
122 		else
123 			DrawPicture(fEnabledOff);
124 	} else {
125 
126 		if (fDisabledOff == NULL
127 			|| (fDisabledOn == NULL && fBehavior == B_TWO_STATE_BUTTON))
128 			debugger("Need to set the 'disabled' pictures for this BPictureButton ");
129 
130 		if (Value() == B_CONTROL_ON)
131 			DrawPicture(fDisabledOn);
132 		else
133 			DrawPicture(fDisabledOff);
134 	}
135 
136 	if (IsFocus()) {
137 		SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
138 		StrokeRect(Bounds(), B_SOLID_HIGH);
139 	}
140 }
141 
142 
143 void
144 BPictureButton::MouseDown(BPoint point)
145 {
146 	if (!IsEnabled()) {
147 		BControl::MouseDown(point);
148 		return;
149 	}
150 
151 	SetMouseEventMask(B_POINTER_EVENTS,
152 		B_NO_POINTER_HISTORY | B_SUSPEND_VIEW_FOCUS);
153 
154 	if (fBehavior == B_ONE_STATE_BUTTON) {
155 		SetValue(B_CONTROL_ON);
156 	} else {
157 		if (Value() == B_CONTROL_ON)
158 			SetValue(B_CONTROL_OFF);
159 		else
160 			SetValue(B_CONTROL_ON);
161 	}
162 	SetTracking(true);
163 }
164 
165 
166 void
167 BPictureButton::MouseUp(BPoint point)
168 {
169 	if (IsEnabled() && IsTracking()) {
170 		if (Bounds().Contains(point)) {
171 			if (fBehavior == B_ONE_STATE_BUTTON) {
172 				if (Value() == B_CONTROL_ON) {
173 					snooze(75000);
174 					SetValue(B_CONTROL_OFF);
175 				}
176 			}
177 			Invoke();
178 		}
179 
180 		SetTracking(false);
181 	}
182 }
183 
184 
185 void
186 BPictureButton::MouseMoved(BPoint point, uint32 transit, const BMessage* msg)
187 {
188 	if (IsEnabled() && IsTracking()) {
189 		if (transit == B_EXITED_VIEW)
190 			SetValue(B_CONTROL_OFF);
191 		else if (transit == B_ENTERED_VIEW)
192 			SetValue(B_CONTROL_ON);
193 	} else
194 		BControl::MouseMoved(point, transit, msg);
195 }
196 
197 
198 void
199 BPictureButton::KeyDown(const char* bytes, int32 numBytes)
200 {
201 	if (numBytes == 1) {
202 		switch (bytes[0]) {
203 			case B_ENTER:
204 			case B_SPACE:
205 				if (fBehavior == B_ONE_STATE_BUTTON) {
206 					SetValue(B_CONTROL_ON);
207 					snooze(50000);
208 					SetValue(B_CONTROL_OFF);
209 				} else {
210 					if (Value() == B_CONTROL_ON)
211 						SetValue(B_CONTROL_OFF);
212 					else
213 						SetValue(B_CONTROL_ON);
214 				}
215 				Invoke();
216 				return;
217 		}
218 	}
219 
220 	BControl::KeyDown(bytes, numBytes);
221 }
222 
223 
224 void
225 BPictureButton::SetEnabledOn(BPicture* on)
226 {
227 	delete fEnabledOn;
228 	fEnabledOn = new (std::nothrow) BPicture(*on);
229 }
230 
231 
232 void
233 BPictureButton::SetEnabledOff(BPicture* off)
234 {
235 	delete fEnabledOff;
236 	fEnabledOff = new (std::nothrow) BPicture(*off);
237 }
238 
239 
240 void
241 BPictureButton::SetDisabledOn(BPicture* on)
242 {
243 	delete fDisabledOn;
244 	fDisabledOn = new (std::nothrow) BPicture(*on);
245 }
246 
247 
248 void
249 BPictureButton::SetDisabledOff(BPicture* off)
250 {
251 	delete fDisabledOff;
252 	fDisabledOff = new (std::nothrow) BPicture(*off);
253 }
254 
255 
256 BPicture*
257 BPictureButton::EnabledOn() const
258 {
259 	return fEnabledOn;
260 }
261 
262 
263 BPicture*
264 BPictureButton::EnabledOff() const
265 {
266 	return fEnabledOff;
267 }
268 
269 
270 BPicture*
271 BPictureButton::DisabledOn() const
272 {
273 	return fDisabledOn;
274 }
275 
276 
277 BPicture*
278 BPictureButton::DisabledOff() const
279 {
280 	return fDisabledOff;
281 }
282 
283 
284 void
285 BPictureButton::SetBehavior(uint32 behavior)
286 {
287 	fBehavior = behavior;
288 }
289 
290 
291 uint32
292 BPictureButton::Behavior() const
293 {
294 	return fBehavior;
295 }
296 
297 
298 void
299 BPictureButton::MessageReceived(BMessage* msg)
300 {
301 	BControl::MessageReceived(msg);
302 }
303 
304 
305 void
306 BPictureButton::WindowActivated(bool state)
307 {
308 	BControl::WindowActivated(state);
309 }
310 
311 
312 void
313 BPictureButton::AttachedToWindow()
314 {
315 	BControl::AttachedToWindow();
316 }
317 
318 
319 void
320 BPictureButton::DetachedFromWindow()
321 {
322 	BControl::DetachedFromWindow();
323 }
324 
325 
326 void
327 BPictureButton::SetValue(int32 value)
328 {
329 	BControl::SetValue(value);
330 }
331 
332 
333 status_t
334 BPictureButton::Invoke(BMessage* msg)
335 {
336 	return BControl::Invoke(msg);
337 }
338 
339 
340 void
341 BPictureButton::FrameMoved(BPoint newPosition)
342 {
343 	BControl::FrameMoved(newPosition);
344 }
345 
346 
347 void
348 BPictureButton::FrameResized(float newWidth, float newHeight)
349 {
350 	BControl::FrameResized(newWidth, newHeight);
351 }
352 
353 
354 BHandler*
355 BPictureButton::ResolveSpecifier(BMessage* msg, int32 index,
356 	BMessage* specifier, int32 form, const char* property)
357 {
358 	return BControl::ResolveSpecifier(msg, index, specifier, form, property);
359 }
360 
361 
362 status_t
363 BPictureButton::GetSupportedSuites(BMessage* data)
364 {
365 	return BControl::GetSupportedSuites(data);
366 }
367 
368 
369 void
370 BPictureButton::ResizeToPreferred()
371 {
372 	BControl::ResizeToPreferred();
373 }
374 
375 
376 void
377 BPictureButton::GetPreferredSize(float* _width, float* _height)
378 {
379 	BControl::GetPreferredSize(_width, _height);
380 }
381 
382 
383 void
384 BPictureButton::MakeFocus(bool state)
385 {
386 	BControl::MakeFocus(state);
387 }
388 
389 
390 void
391 BPictureButton::AllAttached()
392 {
393 	BControl::AllAttached();
394 }
395 
396 
397 void
398 BPictureButton::AllDetached()
399 {
400 	BControl::AllDetached();
401 }
402 
403 
404 status_t
405 BPictureButton::Perform(perform_code code, void* _data)
406 {
407 	switch (code) {
408 		case PERFORM_CODE_MIN_SIZE:
409 			((perform_data_min_size*)_data)->return_value
410 				= BPictureButton::MinSize();
411 			return B_OK;
412 		case PERFORM_CODE_MAX_SIZE:
413 			((perform_data_max_size*)_data)->return_value
414 				= BPictureButton::MaxSize();
415 			return B_OK;
416 		case PERFORM_CODE_PREFERRED_SIZE:
417 			((perform_data_preferred_size*)_data)->return_value
418 				= BPictureButton::PreferredSize();
419 			return B_OK;
420 		case PERFORM_CODE_LAYOUT_ALIGNMENT:
421 			((perform_data_layout_alignment*)_data)->return_value
422 				= BPictureButton::LayoutAlignment();
423 			return B_OK;
424 		case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH:
425 			((perform_data_has_height_for_width*)_data)->return_value
426 				= BPictureButton::HasHeightForWidth();
427 			return B_OK;
428 		case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH:
429 		{
430 			perform_data_get_height_for_width* data
431 				= (perform_data_get_height_for_width*)_data;
432 			BPictureButton::GetHeightForWidth(data->width, &data->min, &data->max,
433 				&data->preferred);
434 			return B_OK;
435 }
436 		case PERFORM_CODE_SET_LAYOUT:
437 		{
438 			perform_data_set_layout* data = (perform_data_set_layout*)_data;
439 			BPictureButton::SetLayout(data->layout);
440 			return B_OK;
441 		}
442 		case PERFORM_CODE_INVALIDATE_LAYOUT:
443 		{
444 			perform_data_invalidate_layout* data
445 				= (perform_data_invalidate_layout*)_data;
446 			BPictureButton::InvalidateLayout(data->descendants);
447 			return B_OK;
448 		}
449 		case PERFORM_CODE_DO_LAYOUT:
450 		{
451 			BPictureButton::DoLayout();
452 			return B_OK;
453 		}
454 	}
455 
456 	return BControl::Perform(code, _data);
457 }
458 
459 
460 void BPictureButton::_ReservedPictureButton1() {}
461 void BPictureButton::_ReservedPictureButton2() {}
462 void BPictureButton::_ReservedPictureButton3() {}
463 
464 
465 BPictureButton&
466 BPictureButton::operator=(const BPictureButton &button)
467 {
468 	return *this;
469 }
470 
471 
472 void
473 BPictureButton::_Redraw()
474 {
475 }
476 
477 
478 void
479 BPictureButton::_InitData()
480 {
481 }
482 
483