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