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