1 /* 2 * Copyright 2001-2005, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Graham MacDonald (macdonag@btopenworld.com) 7 */ 8 9 /** BPictureButton displays and controls a picture button in a window. */ 10 11 12 #include <PictureButton.h> 13 14 15 BPictureButton::BPictureButton(BRect frame, const char* name, 16 BPicture *off, BPicture *on, BMessage *message, 17 uint32 behavior, uint32 resizeMask, uint32 flags) 18 : BControl(frame, name, "", message, resizeMask, flags), 19 fOutlined(false), 20 fBehavior(behavior) 21 { 22 fEnabledOff = new BPicture(*off); 23 fEnabledOn = new BPicture(*on); 24 fDisabledOff = NULL; 25 fDisabledOn = NULL; 26 } 27 28 29 BPictureButton::BPictureButton(BMessage *data) 30 : BControl(data) 31 { 32 BMessage pictureArchive; 33 34 // Default to 1 state button if not here - is this valid? 35 if (data->FindInt32 ("_behave", (int32 *)&fBehavior) != B_OK) 36 fBehavior = B_ONE_STATE_BUTTON; 37 38 // Now expand the pictures: 39 if (data->FindMessage("_e_on", &pictureArchive) == B_OK) 40 fEnabledOn = new BPicture(&pictureArchive); 41 42 if (data->FindMessage("_e_off", &pictureArchive) == B_OK) 43 fEnabledOff = new BPicture(&pictureArchive); 44 45 if (fBehavior == B_TWO_STATE_BUTTON) { 46 if (data->FindMessage("_d_on", &pictureArchive) == B_OK) 47 fDisabledOn = new BPicture(&pictureArchive); 48 49 if (data->FindMessage("_d_off", &pictureArchive) == B_OK) 50 fDisabledOff = new BPicture(&pictureArchive); 51 } else 52 fDisabledOn = fDisabledOff = NULL; 53 } 54 55 56 BPictureButton::~BPictureButton() 57 { 58 delete fEnabledOn; 59 delete fEnabledOff; 60 delete fDisabledOn; 61 delete fDisabledOff; 62 } 63 64 65 BArchivable * 66 BPictureButton::Instantiate(BMessage *data) 67 { 68 if ( validate_instantiation(data, "BPictureButton")) 69 return new BPictureButton(data); 70 71 return NULL; 72 } 73 74 75 status_t 76 BPictureButton::Archive(BMessage *data, bool deep) const 77 { 78 status_t err = BControl::Archive(data, deep); 79 if (err != B_OK) 80 return err; 81 82 // Fill out message, depending on whether a deep copy is required or not. 83 if (deep) { 84 BMessage pictureArchive; 85 86 if (fEnabledOn->Archive(&pictureArchive, deep) == B_OK) { 87 err = data->AddMessage("_e_on", &pictureArchive); 88 if (err != B_OK) 89 return err; 90 } 91 92 if (fEnabledOff->Archive(&pictureArchive, deep) == B_OK) { 93 err = data->AddMessage("_e_off", &pictureArchive); 94 if (err != B_OK) 95 return err; 96 } 97 98 // Do we add messages for pictures that don't exist? 99 if (fBehavior == B_TWO_STATE_BUTTON) { 100 if (fDisabledOn->Archive(&pictureArchive, deep) == B_OK) { 101 err = data->AddMessage("_d_on", &pictureArchive); 102 if (err != B_OK) 103 return err; 104 } 105 106 if (fDisabledOff->Archive(&pictureArchive, deep) == B_OK) { 107 err = data->AddMessage("_d_off", &pictureArchive); 108 if (err != B_OK) 109 return err; 110 } 111 } 112 } 113 114 return data->AddInt32("_behave", fBehavior); 115 } 116 117 118 void 119 BPictureButton::Draw(BRect updateRect) 120 { 121 BRect rect = Bounds(); 122 123 // Need to check if TWO_STATE, if setEnabled=false, and if diabled picture is null 124 // If so, and in debug, bring up an Alert, if so, and not in debug, output to stdout 125 126 // We should request the view's base color which normaly is (216,216,216) 127 rgb_color color = ui_color(B_PANEL_BACKGROUND_COLOR); 128 129 if (fBehavior == B_ONE_STATE_BUTTON) { 130 if (Value() == B_CONTROL_ON) 131 DrawPicture(fEnabledOn); 132 else 133 DrawPicture(fEnabledOff); 134 } else { 135 // B_TWO_STATE_BUTTON 136 137 if (IsEnabled()) { 138 if (Value() == B_CONTROL_ON) 139 DrawPicture(fEnabledOn); 140 else 141 DrawPicture(fEnabledOff); 142 } else { 143 // disabled 144 if (Value() == B_CONTROL_ON) { 145 if (fDisabledOn == NULL) 146 debugger("Need to set the 'disabled' pictures for this BPictureButton "); 147 148 DrawPicture(fDisabledOn); 149 } else { 150 if (fDisabledOn == NULL) 151 debugger("Need to set the 'disabled' pictures for this BPictureButton "); 152 153 DrawPicture(fDisabledOff); 154 } 155 } 156 } 157 158 if (IsFocus()) { 159 SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 160 StrokeRect(rect, B_SOLID_HIGH); 161 } 162 } 163 164 165 void 166 BPictureButton::MouseDown(BPoint point) 167 { 168 if (!IsEnabled()) { 169 BControl::MouseDown(point); 170 return; 171 } 172 173 SetMouseEventMask(B_POINTER_EVENTS, 174 B_NO_POINTER_HISTORY | B_SUSPEND_VIEW_FOCUS); 175 176 if (fBehavior == B_ONE_STATE_BUTTON) { 177 SetValue(B_CONTROL_ON); 178 } else { 179 if (Value() == B_CONTROL_ON) 180 SetValue(B_CONTROL_OFF); 181 else 182 SetValue(B_CONTROL_ON); 183 } 184 SetTracking(true); 185 } 186 187 188 void 189 BPictureButton::MouseUp(BPoint point) 190 { 191 if (IsEnabled() && IsTracking()) { 192 if (Bounds().Contains(point)) { 193 if (fBehavior == B_ONE_STATE_BUTTON) { 194 if (Value() == B_CONTROL_ON) { 195 snooze(75000); 196 SetValue(B_CONTROL_OFF); 197 } 198 } 199 Invoke(); 200 } 201 202 SetTracking(false); 203 } 204 } 205 206 207 void 208 BPictureButton::MouseMoved(BPoint point, uint32 transit, const BMessage *msg) 209 { 210 if (IsEnabled() && IsTracking()) { 211 if (transit == B_EXITED_VIEW) 212 SetValue(B_CONTROL_OFF); 213 else if (transit == B_ENTERED_VIEW) 214 SetValue(B_CONTROL_ON); 215 } else 216 BControl::MouseMoved(point, transit, msg); 217 } 218 219 220 void 221 BPictureButton::KeyDown(const char *bytes, int32 numBytes) 222 { 223 if (numBytes == 1) { 224 switch (bytes[0]) { 225 case B_ENTER: 226 case B_SPACE: 227 if (fBehavior == B_ONE_STATE_BUTTON) { 228 SetValue(B_CONTROL_ON); 229 snooze(50000); 230 SetValue(B_CONTROL_OFF); 231 } else { 232 if (Value() == B_CONTROL_ON) 233 SetValue(B_CONTROL_OFF); 234 else 235 SetValue(B_CONTROL_ON); 236 } 237 Invoke(); 238 return; 239 } 240 } 241 242 BControl::KeyDown(bytes, numBytes); 243 } 244 245 246 void 247 BPictureButton::SetEnabledOn(BPicture *on) 248 { 249 delete fEnabledOn; 250 fEnabledOn = new BPicture(*on); 251 } 252 253 254 void 255 BPictureButton::SetEnabledOff(BPicture *off) 256 { 257 delete fEnabledOff; 258 fEnabledOff = new BPicture(*off); 259 } 260 261 262 void 263 BPictureButton::SetDisabledOn(BPicture *on) 264 { 265 delete fDisabledOn; 266 fDisabledOn = new BPicture(*on); 267 } 268 269 270 void 271 BPictureButton::SetDisabledOff(BPicture *off) 272 { 273 delete fDisabledOff; 274 fDisabledOff = new BPicture(*off); 275 } 276 277 278 BPicture * 279 BPictureButton::EnabledOn() const 280 { 281 return fEnabledOn; 282 } 283 284 285 BPicture * 286 BPictureButton::EnabledOff() const 287 { 288 return fEnabledOff; 289 } 290 291 292 BPicture * 293 BPictureButton::DisabledOn() const 294 { 295 return fDisabledOn; 296 } 297 298 299 BPicture * 300 BPictureButton::DisabledOff() const 301 { 302 return fDisabledOff; 303 } 304 305 306 void 307 BPictureButton::SetBehavior(uint32 behavior) 308 { 309 fBehavior = behavior; 310 } 311 312 313 uint32 314 BPictureButton::Behavior() const 315 { 316 return fBehavior; 317 } 318 319 320 void 321 BPictureButton::MessageReceived(BMessage *msg) 322 { 323 BControl::MessageReceived(msg); 324 } 325 326 327 void 328 BPictureButton::WindowActivated(bool state) 329 { 330 BControl::WindowActivated(state); 331 } 332 333 334 void 335 BPictureButton::AttachedToWindow() 336 { 337 BControl::AttachedToWindow(); 338 } 339 340 341 void 342 BPictureButton::DetachedFromWindow() 343 { 344 BControl::DetachedFromWindow(); 345 } 346 347 348 void 349 BPictureButton::SetValue(int32 value) 350 { 351 BControl::SetValue(value); 352 } 353 354 355 status_t 356 BPictureButton::Invoke(BMessage *msg) 357 { 358 return BControl::Invoke(msg); 359 } 360 361 362 void 363 BPictureButton::FrameMoved(BPoint newPosition) 364 { 365 BControl::FrameMoved(newPosition); 366 } 367 368 369 void 370 BPictureButton::FrameResized(float newWidth, float newHeight) 371 { 372 BControl::FrameResized(newWidth, newHeight); 373 } 374 375 376 BHandler * 377 BPictureButton::ResolveSpecifier(BMessage *msg, int32 index, 378 BMessage *specifier, int32 form, const char *property) 379 { 380 return BControl::ResolveSpecifier(msg, index, specifier, form, property); 381 } 382 383 384 status_t 385 BPictureButton::GetSupportedSuites(BMessage *data) 386 { 387 return BControl::GetSupportedSuites(data); 388 } 389 390 391 void 392 BPictureButton::ResizeToPreferred() 393 { 394 float width, height; 395 GetPreferredSize(&width, &height); 396 BControl::ResizeTo(width, height); 397 } 398 399 400 void 401 BPictureButton::GetPreferredSize(float* _width, float* _height) 402 { 403 // Need to do some test to see what the Be method returns... 404 BControl::GetPreferredSize(_width, _height); 405 } 406 407 408 void 409 BPictureButton::MakeFocus(bool state) 410 { 411 BControl::MakeFocus(state); 412 } 413 414 415 void 416 BPictureButton::AllAttached() 417 { 418 BControl::AllAttached(); 419 } 420 421 422 void 423 BPictureButton::AllDetached() 424 { 425 BControl::AllDetached(); 426 } 427 428 429 status_t 430 BPictureButton::Perform (perform_code d, void *arg) 431 { 432 // Really clutching at straws here.... 433 return B_ERROR; 434 } 435 436 437 void BPictureButton::_ReservedPictureButton1() {} 438 void BPictureButton::_ReservedPictureButton2() {} 439 void BPictureButton::_ReservedPictureButton3() {} 440 441 442 BPictureButton & 443 BPictureButton::operator=(const BPictureButton &button) 444 { 445 return *this; 446 } 447 448 449 void 450 BPictureButton::Redraw() 451 { 452 } 453 454 455 void 456 BPictureButton::InitData() 457 { 458 } 459 460