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 fDisabledOff(NULL), 20 fDisabledOn(NULL), 21 fOutlined(false), 22 fBehavior(behavior) 23 { 24 fEnabledOff = new BPicture(*off); 25 fEnabledOn = new 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 BPicture(&pictureArchive); 45 46 if (data->FindMessage("_e_off", &pictureArchive) == B_OK) 47 fEnabledOff = new BPicture(&pictureArchive); 48 49 if (data->FindMessage("_d_on", &pictureArchive) == B_OK) 50 fDisabledOn = new BPicture(&pictureArchive); 51 52 if (data->FindMessage("_d_off", &pictureArchive) == B_OK) 53 fDisabledOff = new 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 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 BRect rect = Bounds(); 120 121 // We should request the view's base color which normaly is (216,216,216) 122 rgb_color color = ui_color(B_PANEL_BACKGROUND_COLOR); 123 124 if (IsEnabled()) { 125 if (Value() == B_CONTROL_ON) 126 DrawPicture(fEnabledOn); 127 else 128 DrawPicture(fEnabledOff); 129 } else { 130 131 if (fDisabledOff == NULL 132 || (fDisabledOn == NULL && fBehavior == B_TWO_STATE_BUTTON)) 133 debugger("Need to set the 'disabled' pictures for this BPictureButton "); 134 135 if (Value() == B_CONTROL_ON) 136 DrawPicture(fDisabledOn); 137 else 138 DrawPicture(fDisabledOff); 139 } 140 141 if (IsFocus()) { 142 SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); 143 StrokeRect(rect, B_SOLID_HIGH); 144 } 145 } 146 147 148 void 149 BPictureButton::MouseDown(BPoint point) 150 { 151 if (!IsEnabled()) { 152 BControl::MouseDown(point); 153 return; 154 } 155 156 SetMouseEventMask(B_POINTER_EVENTS, 157 B_NO_POINTER_HISTORY | B_SUSPEND_VIEW_FOCUS); 158 159 if (fBehavior == B_ONE_STATE_BUTTON) { 160 SetValue(B_CONTROL_ON); 161 } else { 162 if (Value() == B_CONTROL_ON) 163 SetValue(B_CONTROL_OFF); 164 else 165 SetValue(B_CONTROL_ON); 166 } 167 SetTracking(true); 168 } 169 170 171 void 172 BPictureButton::MouseUp(BPoint point) 173 { 174 if (IsEnabled() && IsTracking()) { 175 if (Bounds().Contains(point)) { 176 if (fBehavior == B_ONE_STATE_BUTTON) { 177 if (Value() == B_CONTROL_ON) { 178 snooze(75000); 179 SetValue(B_CONTROL_OFF); 180 } 181 } 182 Invoke(); 183 } 184 185 SetTracking(false); 186 } 187 } 188 189 190 void 191 BPictureButton::MouseMoved(BPoint point, uint32 transit, const BMessage *msg) 192 { 193 if (IsEnabled() && IsTracking()) { 194 if (transit == B_EXITED_VIEW) 195 SetValue(B_CONTROL_OFF); 196 else if (transit == B_ENTERED_VIEW) 197 SetValue(B_CONTROL_ON); 198 } else 199 BControl::MouseMoved(point, transit, msg); 200 } 201 202 203 void 204 BPictureButton::KeyDown(const char *bytes, int32 numBytes) 205 { 206 if (numBytes == 1) { 207 switch (bytes[0]) { 208 case B_ENTER: 209 case B_SPACE: 210 if (fBehavior == B_ONE_STATE_BUTTON) { 211 SetValue(B_CONTROL_ON); 212 snooze(50000); 213 SetValue(B_CONTROL_OFF); 214 } else { 215 if (Value() == B_CONTROL_ON) 216 SetValue(B_CONTROL_OFF); 217 else 218 SetValue(B_CONTROL_ON); 219 } 220 Invoke(); 221 return; 222 } 223 } 224 225 BControl::KeyDown(bytes, numBytes); 226 } 227 228 229 void 230 BPictureButton::SetEnabledOn(BPicture *on) 231 { 232 delete fEnabledOn; 233 fEnabledOn = new BPicture(*on); 234 } 235 236 237 void 238 BPictureButton::SetEnabledOff(BPicture *off) 239 { 240 delete fEnabledOff; 241 fEnabledOff = new BPicture(*off); 242 } 243 244 245 void 246 BPictureButton::SetDisabledOn(BPicture *on) 247 { 248 delete fDisabledOn; 249 fDisabledOn = new BPicture(*on); 250 } 251 252 253 void 254 BPictureButton::SetDisabledOff(BPicture *off) 255 { 256 delete fDisabledOff; 257 fDisabledOff = new BPicture(*off); 258 } 259 260 261 BPicture * 262 BPictureButton::EnabledOn() const 263 { 264 return fEnabledOn; 265 } 266 267 268 BPicture * 269 BPictureButton::EnabledOff() const 270 { 271 return fEnabledOff; 272 } 273 274 275 BPicture * 276 BPictureButton::DisabledOn() const 277 { 278 return fDisabledOn; 279 } 280 281 282 BPicture * 283 BPictureButton::DisabledOff() const 284 { 285 return fDisabledOff; 286 } 287 288 289 void 290 BPictureButton::SetBehavior(uint32 behavior) 291 { 292 fBehavior = behavior; 293 } 294 295 296 uint32 297 BPictureButton::Behavior() const 298 { 299 return fBehavior; 300 } 301 302 303 void 304 BPictureButton::MessageReceived(BMessage *msg) 305 { 306 BControl::MessageReceived(msg); 307 } 308 309 310 void 311 BPictureButton::WindowActivated(bool state) 312 { 313 BControl::WindowActivated(state); 314 } 315 316 317 void 318 BPictureButton::AttachedToWindow() 319 { 320 BControl::AttachedToWindow(); 321 } 322 323 324 void 325 BPictureButton::DetachedFromWindow() 326 { 327 BControl::DetachedFromWindow(); 328 } 329 330 331 void 332 BPictureButton::SetValue(int32 value) 333 { 334 BControl::SetValue(value); 335 } 336 337 338 status_t 339 BPictureButton::Invoke(BMessage *msg) 340 { 341 return BControl::Invoke(msg); 342 } 343 344 345 void 346 BPictureButton::FrameMoved(BPoint newPosition) 347 { 348 BControl::FrameMoved(newPosition); 349 } 350 351 352 void 353 BPictureButton::FrameResized(float newWidth, float newHeight) 354 { 355 BControl::FrameResized(newWidth, newHeight); 356 } 357 358 359 BHandler * 360 BPictureButton::ResolveSpecifier(BMessage *msg, int32 index, 361 BMessage *specifier, int32 form, const char *property) 362 { 363 return BControl::ResolveSpecifier(msg, index, specifier, form, property); 364 } 365 366 367 status_t 368 BPictureButton::GetSupportedSuites(BMessage *data) 369 { 370 return BControl::GetSupportedSuites(data); 371 } 372 373 374 void 375 BPictureButton::ResizeToPreferred() 376 { 377 BControl::ResizeToPreferred(); 378 } 379 380 381 void 382 BPictureButton::GetPreferredSize(float* _width, float* _height) 383 { 384 // Need to do some test to see what the Be method returns... 385 BControl::GetPreferredSize(_width, _height); 386 } 387 388 389 void 390 BPictureButton::MakeFocus(bool state) 391 { 392 BControl::MakeFocus(state); 393 } 394 395 396 void 397 BPictureButton::AllAttached() 398 { 399 BControl::AllAttached(); 400 } 401 402 403 void 404 BPictureButton::AllDetached() 405 { 406 BControl::AllDetached(); 407 } 408 409 410 status_t 411 BPictureButton::Perform(perform_code d, void *arg) 412 { 413 return BControl::Perform(d, arg); 414 } 415 416 417 void BPictureButton::_ReservedPictureButton1() {} 418 void BPictureButton::_ReservedPictureButton2() {} 419 void BPictureButton::_ReservedPictureButton3() {} 420 421 422 BPictureButton & 423 BPictureButton::operator=(const BPictureButton &button) 424 { 425 return *this; 426 } 427 428 429 void 430 BPictureButton::Redraw() 431 { 432 } 433 434 435 void 436 BPictureButton::InitData() 437 { 438 } 439 440