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 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 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 60 BPictureButton::~BPictureButton() 61 { 62 delete fEnabledOn; 63 delete fEnabledOff; 64 delete fDisabledOn; 65 delete fDisabledOff; 66 } 67 68 69 BArchivable* 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 80 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 122 BPictureButton::AttachedToWindow() 123 { 124 BControl::AttachedToWindow(); 125 } 126 127 128 void 129 BPictureButton::DetachedFromWindow() 130 { 131 BControl::DetachedFromWindow(); 132 } 133 134 135 void 136 BPictureButton::AllAttached() 137 { 138 BControl::AllAttached(); 139 } 140 141 142 void 143 BPictureButton::AllDetached() 144 { 145 BControl::AllDetached(); 146 } 147 148 149 void 150 BPictureButton::ResizeToPreferred() 151 { 152 BControl::ResizeToPreferred(); 153 } 154 155 156 void 157 BPictureButton::GetPreferredSize(float* _width, float* _height) 158 { 159 BControl::GetPreferredSize(_width, _height); 160 } 161 162 163 void 164 BPictureButton::FrameMoved(BPoint newPosition) 165 { 166 BControl::FrameMoved(newPosition); 167 } 168 169 170 void 171 BPictureButton::FrameResized(float newWidth, float newHeight) 172 { 173 BControl::FrameResized(newWidth, newHeight); 174 } 175 176 177 void 178 BPictureButton::WindowActivated(bool active) 179 { 180 BControl::WindowActivated(active); 181 } 182 183 184 void 185 BPictureButton::MakeFocus(bool focus) 186 { 187 BControl::MakeFocus(focus); 188 } 189 190 191 void 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 219 BPictureButton::MessageReceived(BMessage* message) 220 { 221 BControl::MessageReceived(message); 222 } 223 224 225 void 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 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 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 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 311 BPictureButton::SetEnabledOn(BPicture* picture) 312 { 313 delete fEnabledOn; 314 fEnabledOn = new (std::nothrow) BPicture(*picture); 315 } 316 317 318 void 319 BPictureButton::SetEnabledOff(BPicture* picture) 320 { 321 delete fEnabledOff; 322 fEnabledOff = new (std::nothrow) BPicture(*picture); 323 } 324 325 326 void 327 BPictureButton::SetDisabledOn(BPicture* picture) 328 { 329 delete fDisabledOn; 330 fDisabledOn = new (std::nothrow) BPicture(*picture); 331 } 332 333 334 void 335 BPictureButton::SetDisabledOff(BPicture* picture) 336 { 337 delete fDisabledOff; 338 fDisabledOff = new (std::nothrow) BPicture(*picture); 339 } 340 341 342 BPicture* 343 BPictureButton::EnabledOn() const 344 { 345 return fEnabledOn; 346 } 347 348 349 BPicture* 350 BPictureButton::EnabledOff() const 351 { 352 return fEnabledOff; 353 } 354 355 356 BPicture* 357 BPictureButton::DisabledOn() const 358 { 359 return fDisabledOn; 360 } 361 362 363 BPicture* 364 BPictureButton::DisabledOff() const 365 { 366 return fDisabledOff; 367 } 368 369 370 void 371 BPictureButton::SetBehavior(uint32 behavior) 372 { 373 fBehavior = behavior; 374 } 375 376 377 uint32 378 BPictureButton::Behavior() const 379 { 380 return fBehavior; 381 } 382 383 384 void 385 BPictureButton::SetValue(int32 value) 386 { 387 BControl::SetValue(value); 388 } 389 390 391 status_t 392 BPictureButton::Invoke(BMessage* message) 393 { 394 return BControl::Invoke(message); 395 } 396 397 398 BHandler* 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 408 BPictureButton::GetSupportedSuites(BMessage* data) 409 { 410 return BControl::GetSupportedSuites(data); 411 } 412 413 414 status_t 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 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 485 void BPictureButton::_ReservedPictureButton1() {} 486 void BPictureButton::_ReservedPictureButton2() {} 487 void BPictureButton::_ReservedPictureButton3() {} 488 489 490 BPictureButton& 491 BPictureButton::operator=(const BPictureButton &button) 492 { 493 return *this; 494 } 495 496