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