vfs: check userland buffers before reading them.
[haiku.git] / src / kits / interface / PictureButton.cpp
blob060e20cf5bf7985b5abf8bcac77bef4a5bcb787f
1 /*
2 * Copyright 2001-2010, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
5 * Authors:
6 * Graham MacDonald (macdonag@btopenworld.com)
7 */
10 #include <PictureButton.h>
12 #include <new>
14 #include <binary_compatibility/Interface.h>
17 BPictureButton::BPictureButton(BRect frame, const char* name,
18 BPicture* off, BPicture* on, BMessage* message,
19 uint32 behavior, uint32 resizingMode, uint32 flags)
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)
31 BPictureButton::BPictureButton(BMessage* data)
33 BControl(data),
34 fEnabledOff(NULL),
35 fEnabledOn(NULL),
36 fDisabledOff(NULL),
37 fDisabledOn(NULL)
39 BMessage pictureArchive;
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;
45 // Now expand the pictures:
46 if (data->FindMessage("_e_on", &pictureArchive) == B_OK)
47 fEnabledOn = new(std::nothrow) BPicture(&pictureArchive);
49 if (data->FindMessage("_e_off", &pictureArchive) == B_OK)
50 fEnabledOff = new(std::nothrow) BPicture(&pictureArchive);
52 if (data->FindMessage("_d_on", &pictureArchive) == B_OK)
53 fDisabledOn = new(std::nothrow) BPicture(&pictureArchive);
55 if (data->FindMessage("_d_off", &pictureArchive) == B_OK)
56 fDisabledOff = new(std::nothrow) BPicture(&pictureArchive);
60 BPictureButton::~BPictureButton()
62 delete fEnabledOn;
63 delete fEnabledOff;
64 delete fDisabledOn;
65 delete fDisabledOff;
69 BArchivable*
70 BPictureButton::Instantiate(BMessage* data)
72 if (validate_instantiation(data, "BPictureButton"))
73 return new (std::nothrow) BPictureButton(data);
75 return NULL;
79 status_t
80 BPictureButton::Archive(BMessage* data, bool deep) const
82 status_t err = BControl::Archive(data, deep);
83 if (err != B_OK)
84 return err;
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;
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;
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;
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;
117 return data->AddInt32("_behave", fBehavior);
121 void
122 BPictureButton::AttachedToWindow()
124 BControl::AttachedToWindow();
128 void
129 BPictureButton::DetachedFromWindow()
131 BControl::DetachedFromWindow();
135 void
136 BPictureButton::AllAttached()
138 BControl::AllAttached();
142 void
143 BPictureButton::AllDetached()
145 BControl::AllDetached();
149 void
150 BPictureButton::ResizeToPreferred()
152 BControl::ResizeToPreferred();
156 void
157 BPictureButton::GetPreferredSize(float* _width, float* _height)
159 BControl::GetPreferredSize(_width, _height);
163 void
164 BPictureButton::FrameMoved(BPoint newPosition)
166 BControl::FrameMoved(newPosition);
170 void
171 BPictureButton::FrameResized(float newWidth, float newHeight)
173 BControl::FrameResized(newWidth, newHeight);
177 void
178 BPictureButton::WindowActivated(bool active)
180 BControl::WindowActivated(active);
184 void
185 BPictureButton::MakeFocus(bool focus)
187 BControl::MakeFocus(focus);
191 void
192 BPictureButton::Draw(BRect updateRect)
194 if (IsEnabled()) {
195 if (Value() == B_CONTROL_ON)
196 DrawPicture(fEnabledOn);
197 else
198 DrawPicture(fEnabledOff);
199 } else {
201 if (fDisabledOff == NULL
202 || (fDisabledOn == NULL && fBehavior == B_TWO_STATE_BUTTON))
203 debugger("Need to set the 'disabled' pictures for this BPictureButton ");
205 if (Value() == B_CONTROL_ON)
206 DrawPicture(fDisabledOn);
207 else
208 DrawPicture(fDisabledOff);
211 if (IsFocus()) {
212 SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
213 StrokeRect(Bounds(), B_SOLID_HIGH);
218 void
219 BPictureButton::MessageReceived(BMessage* message)
221 BControl::MessageReceived(message);
225 void
226 BPictureButton::KeyDown(const char* bytes, int32 numBytes)
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);
242 Invoke();
243 return;
247 BControl::KeyDown(bytes, numBytes);
251 void
252 BPictureButton::MouseDown(BPoint where)
254 if (!IsEnabled()) {
255 BControl::MouseDown(where);
256 return;
259 SetMouseEventMask(B_POINTER_EVENTS,
260 B_NO_POINTER_HISTORY | B_SUSPEND_VIEW_FOCUS);
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);
270 SetTracking(true);
274 void
275 BPictureButton::MouseUp(BPoint where)
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);
285 Invoke();
288 SetTracking(false);
293 void
294 BPictureButton::MouseMoved(BPoint where, uint32 code,
295 const BMessage* dragMessage)
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);
307 // #pragma mark -
310 void
311 BPictureButton::SetEnabledOn(BPicture* picture)
313 delete fEnabledOn;
314 fEnabledOn = new (std::nothrow) BPicture(*picture);
318 void
319 BPictureButton::SetEnabledOff(BPicture* picture)
321 delete fEnabledOff;
322 fEnabledOff = new (std::nothrow) BPicture(*picture);
326 void
327 BPictureButton::SetDisabledOn(BPicture* picture)
329 delete fDisabledOn;
330 fDisabledOn = new (std::nothrow) BPicture(*picture);
334 void
335 BPictureButton::SetDisabledOff(BPicture* picture)
337 delete fDisabledOff;
338 fDisabledOff = new (std::nothrow) BPicture(*picture);
342 BPicture*
343 BPictureButton::EnabledOn() const
345 return fEnabledOn;
349 BPicture*
350 BPictureButton::EnabledOff() const
352 return fEnabledOff;
356 BPicture*
357 BPictureButton::DisabledOn() const
359 return fDisabledOn;
363 BPicture*
364 BPictureButton::DisabledOff() const
366 return fDisabledOff;
370 void
371 BPictureButton::SetBehavior(uint32 behavior)
373 fBehavior = behavior;
377 uint32
378 BPictureButton::Behavior() const
380 return fBehavior;
384 void
385 BPictureButton::SetValue(int32 value)
387 BControl::SetValue(value);
391 status_t
392 BPictureButton::Invoke(BMessage* message)
394 return BControl::Invoke(message);
398 BHandler*
399 BPictureButton::ResolveSpecifier(BMessage* message, int32 index,
400 BMessage* specifier, int32 what, const char* property)
402 return BControl::ResolveSpecifier(message, index, specifier,
403 what, property);
407 status_t
408 BPictureButton::GetSupportedSuites(BMessage* data)
410 return BControl::GetSupportedSuites(data);
414 status_t
415 BPictureButton::Perform(perform_code code, void* _data)
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:
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;
446 case PERFORM_CODE_SET_LAYOUT:
448 perform_data_set_layout* data = (perform_data_set_layout*)_data;
449 BPictureButton::SetLayout(data->layout);
450 return B_OK;
452 case PERFORM_CODE_LAYOUT_INVALIDATED:
454 perform_data_layout_invalidated* data
455 = (perform_data_layout_invalidated*)_data;
456 BPictureButton::LayoutInvalidated(data->descendants);
457 return B_OK;
459 case PERFORM_CODE_DO_LAYOUT:
461 BPictureButton::DoLayout();
462 return B_OK;
464 case PERFORM_CODE_SET_ICON:
466 perform_data_set_icon* data = (perform_data_set_icon*)_data;
467 return BPictureButton::SetIcon(data->icon, data->flags);
471 return BControl::Perform(code, _data);
475 status_t
476 BPictureButton::SetIcon(const BBitmap* icon, uint32 flags)
478 return BControl::SetIcon(icon, flags);
482 // #pragma mark - BPictureButton private methods
485 void BPictureButton::_ReservedPictureButton1() {}
486 void BPictureButton::_ReservedPictureButton2() {}
487 void BPictureButton::_ReservedPictureButton3() {}
490 BPictureButton&
491 BPictureButton::operator=(const BPictureButton &button)
493 return *this;