1 /* 2 * Copyright 2002-2008, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Jerome Duval (jerome.duval@free.fr) 7 * Axel Dörfler, axeld@pinc-software.de 8 */ 9 10 11 #include "BackgroundsView.h" 12 #include "ImageFilePanel.h" 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 17 #include <OS.h> 18 #include <MenuField.h> 19 #include <StorageKit.h> 20 #include <Window.h> 21 #include <Messenger.h> 22 #include <Bitmap.h> 23 #include <Point.h> 24 #include <TranslationKit.h> 25 #include <PopUpMenu.h> 26 27 #include <be_apps/Tracker/Background.h> 28 29 30 static const uint32 kMsgApplySettings = 'aply'; 31 static const uint32 kMsgRevertSettings = 'rvrt'; 32 33 static const uint32 kMsgUpdateColor = 'upcl'; 34 static const uint32 kMsgAllWorkspaces = 'alwk'; 35 static const uint32 kMsgCurrentWorkspace = 'crwk'; 36 static const uint32 kMsgDefaultFolder = 'dffl'; 37 static const uint32 kMsgOtherFolder = 'otfl'; 38 static const uint32 kMsgNoImage = 'noim'; 39 static const uint32 kMsgOtherImage = 'otim'; 40 static const uint32 kMsgImageSelected = 'imsl'; 41 static const uint32 kMsgFolderSelected = 'flsl'; 42 43 static const uint32 kMsgCenterPlacement = 'cnpl'; 44 static const uint32 kMsgManualPlacement = 'mnpl'; 45 static const uint32 kMsgScalePlacement = 'scpl'; 46 static const uint32 kMsgTilePlacement = 'tlpl'; 47 static const uint32 kMsgIconLabelOutline = 'ilol'; 48 49 static const uint32 kMsgImagePlacement = 'xypl'; 50 static const uint32 kMsgUpdatePreviewPlacement = 'pvpl'; 51 52 53 const uint8 kHandCursorData[68] = { 54 16, 1, 2, 2, 55 56 0, 0, // 0000000000000000 57 7, 128, // 0000011110000000 58 61, 112, // 0011110101110000 59 37, 40, // 0010010100101000 60 36, 168, // 0010010010101000 61 18, 148, // 0001001010010100 62 18, 84, // 0001001001010100 63 9, 42, // 0000100100101010 64 8, 1, // 0000100000000001 65 60, 1, // 0011110000000001 66 76, 1, // 0100110000000001 67 66, 1, // 0100001000000001 68 48, 1, // 0011000000000001 69 12, 1, // 0000110000000001 70 2, 0, // 0000001000000000 71 1, 0, // 0000000100000000 72 73 0, 0, // 0000000000000000 74 7, 128, // 0000011110000000 75 63, 240, // 0011111111110000 76 63, 248, // 0011111111111000 77 63, 248, // 0011111111111000 78 31, 252, // 0001111111111100 79 31, 252, // 0001111111111100 80 15, 254, // 0000111111111110 81 15, 255, // 0000111111111111 82 63, 255, // 0011111111111111 83 127, 255, // 0111111111111111 84 127, 255, // 0111111111111111 85 63, 255, // 0011111111111111 86 15, 255, // 0000111111111111 87 3, 254, // 0000001111111110 88 1, 248 // 0000000111111000 89 }; 90 91 92 BackgroundsView::BackgroundsView(BRect frame, const char *name, int32 resize, 93 int32 flags) 94 : BBox(frame, name, resize, flags | B_WILL_DRAW | B_FRAME_EVENTS, B_NO_BORDER), 95 fCurrent(NULL), 96 fCurrentInfo(NULL), 97 fLastImageIndex(-1), 98 fPathList(1, true), 99 fImageList(1, true) 100 { 101 // we need the "Current Workspace" first to get its height 102 103 BMenuItem *menuItem; 104 fWorkspaceMenu = new BPopUpMenu("pick one"); 105 fWorkspaceMenu->AddItem(menuItem = new BMenuItem("All Workspaces", 106 new BMessage(kMsgAllWorkspaces))); 107 fWorkspaceMenu->AddItem(menuItem = new BMenuItem("Current Workspace", 108 new BMessage(kMsgCurrentWorkspace))); 109 menuItem->SetMarked(true); 110 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf(fWorkspaceMenu->FindMarked()); 111 fWorkspaceMenu->AddSeparatorItem(); 112 fWorkspaceMenu->AddItem(menuItem = new BMenuItem("Default folder", 113 new BMessage(kMsgDefaultFolder))); 114 fWorkspaceMenu->AddItem(menuItem = new BMenuItem("Other folder" B_UTF8_ELLIPSIS, 115 new BMessage(kMsgOtherFolder))); 116 117 BMenuField *workspaceMenuField = new BMenuField(BRect(0, 0, 130, 18), 118 "workspaceMenuField", NULL, fWorkspaceMenu, true); 119 workspaceMenuField->ResizeToPreferred(); 120 121 /* the preview box */ 122 123 BFont font(be_plain_font); 124 font_height fontHeight; 125 font.GetHeight(&fontHeight); 126 127 fPreview = new PreviewBox(BRect(10, 8.0 + workspaceMenuField->Bounds().Height() / 2.0f 128 - ceilf(fontHeight.ascent + fontHeight.descent) / 2.0f, 160, 180), "preview"); 129 fPreview->SetFont(&font); 130 fPreview->SetLabel("Preview"); 131 AddChild(fPreview); 132 133 BRect rect(10, fPreview->Bounds().bottom - 30, 70, fPreview->Bounds().bottom - 10); 134 fXPlacementText = new BTextControl(rect, "xPlacementText", "X:", NULL, 135 new BMessage(kMsgImagePlacement), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 136 fXPlacementText->SetDivider(fXPlacementText->StringWidth(fXPlacementText->Label()) + 4.0f); 137 fXPlacementText->TextView()->SetMaxBytes(5); 138 float width, height; 139 fXPlacementText->GetPreferredSize(&width, &height); 140 float delta = fXPlacementText->Bounds().Height() - height; 141 fXPlacementText->MoveBy(0, delta); 142 fXPlacementText->ResizeTo(fXPlacementText->Bounds().Width(), height); 143 fPreview->AddChild(fXPlacementText); 144 145 rect.OffsetBy(70, delta); 146 fYPlacementText = new BTextControl(rect, "yPlacementText", "Y:", NULL, 147 new BMessage(kMsgImagePlacement), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 148 fYPlacementText->SetDivider(fYPlacementText->StringWidth(fYPlacementText->Label()) + 4.0f); 149 fYPlacementText->TextView()->SetMaxBytes(5); 150 fXPlacementText->ResizeTo(fYPlacementText->Bounds().Width(), height); 151 fPreview->AddChild(fYPlacementText); 152 153 for (int32 i = 0; i < 256; i++) { 154 if ((i < '0' || i > '9') && i != '-') { 155 fXPlacementText->TextView()->DisallowChar(i); 156 fYPlacementText->TextView()->DisallowChar(i); 157 } 158 } 159 160 fPreView = new PreView(BRect(15, 25, 135, 115), "preView", 161 B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_SUBPIXEL_PRECISE); 162 fPreview->AddChild(fPreView); 163 164 /* the right box */ 165 166 BBox *rightbox = new BBox(BRect(fPreview->Frame().right + 10, 167 7, Frame().right - 10, fPreview->Frame().bottom), 168 "rightbox"); 169 rightbox->SetLabel(workspaceMenuField); 170 AddChild(rightbox); 171 172 float offset = be_plain_font->StringWidth("Placement:") + 5; 173 rect.Set(10, 0, rightbox->Bounds().right - 10, 30); 174 #ifdef __HAIKU__ 175 rect.top = 8 + rightbox->InnerFrame().top; 176 #else 177 rect.top = 5 + workspaceMenuField->Bounds().Height(); 178 rect.bottom = rect.top + workspaceMenuField->Bounds().Height(); 179 #endif 180 181 fImageMenu = new BPopUpMenu("pick one"); 182 fImageMenu->AddItem(new BGImageMenuItem("None", -1, new BMessage(kMsgNoImage))); 183 fImageMenu->AddSeparatorItem(); 184 fImageMenu->AddItem(new BMenuItem("Other" B_UTF8_ELLIPSIS, new BMessage(kMsgOtherImage))); 185 186 BMenuField *imageMenuField = new BMenuField(rect, "imageMenuField", 187 "Image:", fImageMenu); 188 imageMenuField->SetDivider(offset); 189 imageMenuField->SetAlignment(B_ALIGN_RIGHT); 190 imageMenuField->ResizeToPreferred(); 191 rightbox->AddChild(imageMenuField); 192 193 fPlacementMenu = new BPopUpMenu("pick one"); 194 fPlacementMenu->AddItem(new BMenuItem("Manual", 195 new BMessage(kMsgManualPlacement))); 196 fPlacementMenu->AddItem(new BMenuItem("Center", 197 new BMessage(kMsgCenterPlacement))); 198 fPlacementMenu->AddItem(new BMenuItem("Scale to fit", 199 new BMessage(kMsgScalePlacement))); 200 fPlacementMenu->AddItem(new BMenuItem("Tile", 201 new BMessage(kMsgTilePlacement))); 202 203 rect.OffsetBy(0, imageMenuField->Bounds().Height() + 5); 204 BMenuField *placementMenuField = new BMenuField(rect, "placementMenuField", 205 "Placement:", fPlacementMenu); 206 placementMenuField->SetDivider(offset); 207 placementMenuField->SetAlignment(B_ALIGN_RIGHT); 208 placementMenuField->ResizeToPreferred(); 209 rightbox->AddChild(placementMenuField); 210 211 rect.OffsetBy(offset, placementMenuField->Bounds().Height() + 5); 212 fIconLabelOutline = new BCheckBox(rect, "iconLabelOutline", 213 "Icon label outline", new BMessage(kMsgIconLabelOutline)); 214 fIconLabelOutline->SetValue(B_CONTROL_OFF); 215 fIconLabelOutline->ResizeToPreferred(); 216 rightbox->AddChild(fIconLabelOutline); 217 218 rect.top += fIconLabelOutline->Bounds().Height() + 15; 219 fPicker = new BColorControl(BPoint(10, rect.top), B_CELLS_32x8, 7.0, "Picker", 220 new BMessage(kMsgUpdateColor)); 221 rightbox->AddChild(fPicker); 222 223 float xDelta = max_c(fIconLabelOutline->Frame().right, fPicker->Frame().right) 224 + 10.0f - rightbox->Bounds().Width(); 225 delta = fPicker->Frame().bottom + 10.0f - rightbox->Bounds().Height(); 226 227 rightbox->ResizeBy(xDelta, delta); 228 fPreview->ResizeBy(0, delta); 229 230 // we're not yet attached to a view, so we need to move them manually 231 fXPlacementText->MoveBy(0, delta); 232 fYPlacementText->MoveBy(0, delta); 233 234 rect = fPreview->Frame(); 235 rect.top = rect.bottom + 10.0; 236 fRevert = new BButton(rect, "revert", "Revert", new BMessage(kMsgRevertSettings)); 237 AddChild(fRevert); 238 fRevert->ResizeToPreferred(); 239 240 rect.left = rightbox->Frame().right; 241 fApply = new BButton(rect, "apply", "Apply", new BMessage(kMsgApplySettings)); 242 AddChild(fApply); 243 fApply->ResizeToPreferred(); 244 fApply->MoveBy(-fApply->Bounds().Width(), 0); 245 fApply->MakeDefault(true); 246 } 247 248 249 BackgroundsView::~BackgroundsView() 250 { 251 delete fPanel; 252 delete fFolderPanel; 253 } 254 255 256 void 257 BackgroundsView::GetPreferredSize(float* _width, float* _height) 258 { 259 if (_width) 260 *_width = fApply->Frame().right + 10; 261 if (_height) 262 *_height = fApply->Frame().bottom + 10; 263 } 264 265 266 void 267 BackgroundsView::AllAttached() 268 { 269 fPlacementMenu->SetTargetForItems(this); 270 fImageMenu->SetTargetForItems(this); 271 fWorkspaceMenu->SetTargetForItems(this); 272 fXPlacementText->SetTarget(this); 273 fYPlacementText->SetTarget(this); 274 fIconLabelOutline->SetTarget(this); 275 fPicker->SetTarget(this); 276 fApply->SetTarget(this); 277 fRevert->SetTarget(this); 278 279 BPath path; 280 entry_ref ref; 281 if (find_directory(B_BEOS_ETC_DIRECTORY, &path) == B_OK) { 282 path.Append("artwork"); 283 get_ref_for_path(path.Path(), &ref); 284 } 285 286 fPanel = new ImageFilePanel(B_OPEN_PANEL, new BMessenger(this), &ref, 287 B_FILE_NODE, false, NULL, new CustomRefFilter(true)); 288 fPanel->SetButtonLabel(B_DEFAULT_BUTTON, "Select"); 289 290 fFolderPanel = new BFilePanel(B_OPEN_PANEL, new BMessenger(this), NULL, 291 B_DIRECTORY_NODE, false, NULL, new CustomRefFilter(false)); 292 fFolderPanel->SetButtonLabel(B_DEFAULT_BUTTON, "Select"); 293 294 LoadSettings(); 295 LoadDesktopFolder(); 296 297 float width, height; 298 GetPreferredSize(&width, &height); 299 300 BPoint point; 301 if (fSettings.FindPoint("pos", &point) != B_OK) { 302 BRect frame(BScreen().Frame()); 303 point.Set((frame.right - width) / 2, (frame.bottom - height) / 2); 304 } 305 306 ResizeTo(width, height); 307 Window()->MoveTo(point); 308 Window()->ResizeTo(width, height); 309 310 fApply->SetEnabled(false); 311 fRevert->SetEnabled(false); 312 } 313 314 315 void 316 BackgroundsView::MessageReceived(BMessage *msg) 317 { 318 switch (msg->what) { 319 case B_SIMPLE_DATA: 320 case B_REFS_RECEIVED: 321 RefsReceived(msg); 322 break; 323 324 case kMsgUpdatePreviewPlacement: 325 { 326 BString xstring, ystring; 327 xstring << (int)fPreView->fPoint.x; 328 ystring << (int)fPreView->fPoint.y; 329 fXPlacementText->SetText(xstring.String()); 330 fYPlacementText->SetText(ystring.String()); 331 UpdatePreview(); 332 UpdateButtons(); 333 break; 334 } 335 336 case kMsgManualPlacement: 337 UpdatePreview(); 338 UpdateButtons(); 339 break; 340 341 case kMsgTilePlacement: 342 case kMsgScalePlacement: 343 case kMsgCenterPlacement: 344 UpdatePreview(); 345 UpdateButtons(); 346 break; 347 348 case kMsgIconLabelOutline: 349 UpdateButtons(); 350 break; 351 352 case kMsgUpdateColor: 353 case kMsgImagePlacement: 354 UpdatePreview(); 355 UpdateButtons(); 356 break; 357 358 case kMsgCurrentWorkspace: 359 case kMsgAllWorkspaces: 360 fImageMenu->FindItem(kMsgNoImage)->SetLabel("None"); 361 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf( 362 fWorkspaceMenu->FindMarked()); 363 if (!fCurrent->IsDesktop()) { 364 fPreview->SetDesktop(true); 365 LoadDesktopFolder(); 366 } else 367 UpdateButtons(); 368 break; 369 370 case kMsgDefaultFolder: 371 fImageMenu->FindItem(kMsgNoImage)->SetLabel("None"); 372 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf( 373 fWorkspaceMenu->FindMarked()); 374 fPreview->SetDesktop(false); 375 LoadDefaultFolder(); 376 break; 377 378 case kMsgOtherFolder: 379 fFolderPanel->Show(); 380 break; 381 382 case kMsgOtherImage: 383 fPanel->Show(); 384 break; 385 386 case B_CANCEL: 387 { 388 PRINT(("cancel received\n")); 389 void* pointer; 390 msg->FindPointer("source", &pointer); 391 if (pointer == fPanel) { 392 if (fLastImageIndex >= 0) 393 FindImageItem(fLastImageIndex)->SetMarked(true); 394 else 395 fImageMenu->ItemAt(0)->SetMarked(true); 396 } else if (pointer == fFolderPanel) { 397 if (fLastWorkspaceIndex >= 0) 398 fWorkspaceMenu->ItemAt(fLastWorkspaceIndex)->SetMarked(true); 399 } 400 break; 401 } 402 403 case kMsgImageSelected: 404 case kMsgNoImage: 405 fLastImageIndex = ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex(); 406 UpdatePreview(); 407 UpdateButtons(); 408 break; 409 410 case kMsgFolderSelected: 411 fImageMenu->FindItem(kMsgNoImage)->SetLabel("Default"); 412 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf( 413 fWorkspaceMenu->FindMarked()); 414 fPreview->SetDesktop(false); 415 LoadRecentFolder(*fPathList.ItemAt(fWorkspaceMenu->IndexOf( 416 fWorkspaceMenu->FindMarked()) - 6)); 417 break; 418 419 case kMsgApplySettings: 420 { 421 Save(); 422 423 //NotifyServer(); 424 thread_id notify_thread; 425 notify_thread = spawn_thread(BackgroundsView::NotifyThread, "notifyServer", 426 B_NORMAL_PRIORITY, this); 427 resume_thread(notify_thread); 428 UpdateButtons(); 429 break; 430 } 431 case kMsgRevertSettings: 432 UpdateWithCurrent(); 433 break; 434 435 default: 436 BView::MessageReceived(msg); 437 break; 438 } 439 } 440 441 442 void 443 BackgroundsView::LoadDesktopFolder() 444 { 445 BPath path; 446 if (find_directory(B_DESKTOP_DIRECTORY, &path) == B_OK) { 447 status_t err; 448 err = get_ref_for_path(path.Path(), &fCurrentRef); 449 if (err != B_OK) 450 printf("error in LoadDesktopSettings\n"); 451 LoadFolder(true); 452 } 453 } 454 455 456 void 457 BackgroundsView::LoadDefaultFolder() 458 { 459 BPath path; 460 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 461 BString pathString = path.Path(); 462 pathString << "/Tracker/DefaultFolderTemplate"; 463 status_t err; 464 err = get_ref_for_path(pathString.String(), &fCurrentRef); 465 if (err != B_OK) 466 printf("error in LoadDefaultFolderSettings\n"); 467 LoadFolder(false); 468 } 469 } 470 471 472 void 473 BackgroundsView::LoadRecentFolder(BPath path) 474 { 475 status_t err; 476 err = get_ref_for_path(path.Path(), &fCurrentRef); 477 if (err != B_OK) 478 printf("error in LoadRecentFolder\n"); 479 LoadFolder(false); 480 } 481 482 483 void 484 BackgroundsView::LoadFolder(bool isDesktop) 485 { 486 if (fCurrent) { 487 delete fCurrent; 488 fCurrent = NULL; 489 } 490 491 BNode node(&fCurrentRef); 492 if (node.InitCheck() == B_OK) 493 fCurrent = BackgroundImage::GetBackgroundImage(&node, isDesktop, this); 494 495 UpdateWithCurrent(); 496 } 497 498 499 void 500 BackgroundsView::UpdateWithCurrent(void) 501 { 502 if (fCurrent == NULL) 503 return; 504 505 fPlacementMenu->FindItem(kMsgScalePlacement)->SetEnabled(fCurrent->IsDesktop()); 506 fPlacementMenu->FindItem(kMsgCenterPlacement)->SetEnabled(fCurrent->IsDesktop()); 507 508 if (fWorkspaceMenu->IndexOf(fWorkspaceMenu->FindMarked()) > 5) 509 fImageMenu->FindItem(kMsgNoImage)->SetLabel("Default"); 510 else 511 fImageMenu->FindItem(kMsgNoImage)->SetLabel("None"); 512 513 for (int32 i = fImageMenu->CountItems() - 5; i >= 0; i--) { 514 fImageMenu->RemoveItem(2); 515 } 516 517 for (int32 i = fImageList.CountItems() - 1; i >= 0; i--) { 518 BMessage *message = new BMessage(kMsgImageSelected); 519 AddItem(new BGImageMenuItem(GetImage(i)->GetName(), i, message)); 520 } 521 522 fImageMenu->SetTargetForItems(this); 523 524 fCurrentInfo = fCurrent->ImageInfoForWorkspace(current_workspace()); 525 526 if (!fCurrentInfo) { 527 fImageMenu->FindItem(kMsgNoImage)->SetMarked(true); 528 fPlacementMenu->FindItem(kMsgManualPlacement)->SetMarked(true); 529 fIconLabelOutline->SetValue(B_CONTROL_OFF); 530 } else { 531 fIconLabelOutline->SetValue(fCurrentInfo->fTextWidgetLabelOutline 532 ? B_CONTROL_ON : B_CONTROL_OFF); 533 534 BString xtext, ytext; 535 int32 cmd = 0; 536 switch (fCurrentInfo->fMode) { 537 case BackgroundImage::kCentered: 538 cmd = kMsgCenterPlacement; 539 break; 540 case BackgroundImage::kScaledToFit: 541 cmd = kMsgScalePlacement; 542 break; 543 case BackgroundImage::kAtOffset: 544 cmd = kMsgManualPlacement; 545 xtext << (int)fCurrentInfo->fOffset.x; 546 ytext << (int)fCurrentInfo->fOffset.y; 547 break; 548 case BackgroundImage::kTiled: 549 cmd = kMsgTilePlacement; 550 break; 551 } 552 553 if (cmd != 0) 554 fPlacementMenu->FindItem(cmd)->SetMarked(true); 555 556 fXPlacementText->SetText(xtext.String()); 557 fYPlacementText->SetText(ytext.String()); 558 559 fLastImageIndex = fCurrentInfo->fImageIndex; 560 FindImageItem(fLastImageIndex)->SetMarked(true); 561 } 562 563 rgb_color color = {255, 255, 255, 255}; 564 if (fCurrent->IsDesktop()) { 565 color = BScreen().DesktopColor(); 566 fPicker->SetEnabled(true); 567 } else 568 fPicker->SetEnabled(false); 569 570 fPicker->SetValue(color); 571 572 UpdatePreview(); 573 UpdateButtons(); 574 } 575 576 577 void 578 BackgroundsView::Save() 579 { 580 bool textWidgetLabelOutline = 581 fIconLabelOutline->Value() == B_CONTROL_ON; 582 BackgroundImage::Mode mode = FindPlacementMode(); 583 BPoint offset(atoi(fXPlacementText->Text()), atoi(fYPlacementText->Text())); 584 585 if (!fCurrent->IsDesktop()) { 586 if (fCurrentInfo == NULL) { 587 fCurrentInfo = new BackgroundImage::BackgroundImageInfo(B_ALL_WORKSPACES, 588 fLastImageIndex, mode, offset, textWidgetLabelOutline, 0, 0); 589 fCurrent->Add(fCurrentInfo); 590 } else { 591 fCurrentInfo->fTextWidgetLabelOutline = textWidgetLabelOutline; 592 fCurrentInfo->fMode = mode; 593 if (fCurrentInfo->fMode == BackgroundImage::kAtOffset) 594 fCurrentInfo->fOffset = offset; 595 fCurrentInfo->fImageIndex = fLastImageIndex; 596 } 597 } else { 598 uint32 workspaceMask = 1; 599 int32 workspace = current_workspace(); 600 for (; workspace; workspace--) 601 workspaceMask *= 2; 602 603 if (fCurrentInfo != NULL) { 604 if (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 605 if (fCurrentInfo->fWorkspace != workspaceMask) { 606 fCurrentInfo->fWorkspace = fCurrentInfo->fWorkspace 607 ^ workspaceMask; 608 if (fLastImageIndex > -1) { 609 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 610 workspaceMask, fLastImageIndex, mode, offset, 611 textWidgetLabelOutline, fCurrentInfo->fImageSet, 612 fCurrentInfo->fCacheMode); 613 fCurrent->Add(fCurrentInfo); 614 } 615 } else { 616 if (fLastImageIndex > -1) { 617 fCurrentInfo->fTextWidgetLabelOutline = 618 textWidgetLabelOutline; 619 fCurrentInfo->fMode = mode; 620 if (fCurrentInfo->fMode == BackgroundImage::kAtOffset) 621 fCurrentInfo->fOffset = offset; 622 623 fCurrentInfo->fImageIndex = fLastImageIndex; 624 } else { 625 fCurrent->Remove(fCurrentInfo); 626 fCurrentInfo = NULL; 627 } 628 } 629 } else { 630 fCurrent->RemoveAll(); 631 if (fLastImageIndex > -1) { 632 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 633 B_ALL_WORKSPACES, fLastImageIndex, mode, offset, 634 textWidgetLabelOutline, fCurrent->GetShowingImageSet(), 635 fCurrentInfo->fCacheMode); 636 fCurrent->Add(fCurrentInfo); 637 } 638 } 639 } else if (fLastImageIndex > -1) { 640 if (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 641 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 642 workspaceMask, fLastImageIndex, mode, offset, 643 textWidgetLabelOutline, fCurrent->GetShowingImageSet(), 0); 644 } else { 645 fCurrent->RemoveAll(); 646 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 647 B_ALL_WORKSPACES, fLastImageIndex, mode, offset, 648 textWidgetLabelOutline, fCurrent->GetShowingImageSet(), 0); 649 } 650 fCurrent->Add(fCurrentInfo); 651 } 652 653 if (!fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 654 for (int32 i = 0; i < count_workspaces(); i++) { 655 BScreen().SetDesktopColor(fPicker->ValueAsColor(), i, true); 656 } 657 } else 658 BScreen().SetDesktopColor(fPicker->ValueAsColor(), true); 659 } 660 661 BNode node(&fCurrentRef); 662 663 status_t status = fCurrent->SetBackgroundImage(&node); 664 if (status != B_OK) { 665 // TODO: this should be a BAlert! 666 printf("setting background image failed: %s\n", strerror(status)); 667 } 668 } 669 670 671 void 672 BackgroundsView::NotifyServer() 673 { 674 BMessenger tracker("application/x-vnd.Be-TRAK"); 675 676 if (fCurrent->IsDesktop()) { 677 tracker.SendMessage(new BMessage(B_RESTORE_BACKGROUND_IMAGE)); 678 } else { 679 int32 i = -1; 680 BMessage reply; 681 int32 err; 682 BEntry currentEntry(&fCurrentRef); 683 BPath currentPath(¤tEntry); 684 bool isCustomFolder = !fWorkspaceMenu->FindItem(kMsgDefaultFolder)->IsMarked(); 685 686 do { 687 BMessage msg(B_GET_PROPERTY); 688 i++; 689 690 // look at the "Poses" in every Tracker window 691 msg.AddSpecifier("Poses"); 692 msg.AddSpecifier("Window", i); 693 694 reply.MakeEmpty(); 695 tracker.SendMessage(&msg, &reply); 696 697 // break out of the loop when we're at the end of 698 // the windows 699 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD 700 && reply.FindInt32("error", &err) == B_OK 701 && err == B_BAD_INDEX) 702 break; 703 704 // don't stop for windows that don't understand 705 // a request for "Poses"; they're not displaying 706 // folders 707 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD 708 && reply.FindInt32("error", &err) == B_OK 709 && err != B_BAD_SCRIPT_SYNTAX) 710 continue; 711 712 BMessenger trackerWindow; 713 if (reply.FindMessenger("result", &trackerWindow) != B_OK) 714 continue; 715 716 if (isCustomFolder) { 717 // found a window with poses, ask for its path 718 msg.MakeEmpty(); 719 msg.what = B_GET_PROPERTY; 720 msg.AddSpecifier("Path"); 721 msg.AddSpecifier("Poses"); 722 msg.AddSpecifier("Window", i); 723 724 reply.MakeEmpty(); 725 tracker.SendMessage(&msg, &reply); 726 727 // go on with the next if this din't have a path 728 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD) 729 continue; 730 731 entry_ref ref; 732 if (reply.FindRef("result", &ref) == B_OK) { 733 BEntry entry(&ref); 734 BPath path(&entry); 735 736 // these are not the paths you're looking for 737 if (currentPath != path) 738 continue; 739 } 740 } 741 742 trackerWindow.SendMessage(B_RESTORE_BACKGROUND_IMAGE); 743 } while (true); 744 } 745 } 746 747 748 int32 749 BackgroundsView::NotifyThread(void *data) 750 { 751 BackgroundsView *view = (BackgroundsView*)data; 752 753 view->NotifyServer(); 754 return B_OK; 755 } 756 757 758 void 759 BackgroundsView::SaveSettings(void) 760 { 761 BPath path; 762 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 763 path.Append(SETTINGS_FILE); 764 BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); 765 766 BPoint point = Window()->Frame().LeftTop(); 767 if (fSettings.ReplacePoint("pos", point) != B_OK) 768 fSettings.AddPoint("pos", point); 769 770 entry_ref ref; 771 BEntry entry; 772 BPath path; 773 774 fPanel->GetPanelDirectory(&ref); 775 entry.SetTo(&ref); 776 entry.GetPath(&path); 777 if (fSettings.ReplaceString("paneldir", path.Path()) != B_OK) 778 fSettings.AddString("paneldir", path.Path()); 779 780 fFolderPanel->GetPanelDirectory(&ref); 781 entry.SetTo(&ref); 782 entry.GetPath(&path); 783 if (fSettings.ReplaceString("folderpaneldir", path.Path()) != B_OK) 784 fSettings.AddString("folderpaneldir", path.Path()); 785 786 fSettings.RemoveName("recentfolder"); 787 for (int32 i = 0; i < fPathList.CountItems(); i++) { 788 fSettings.AddString("recentfolder", fPathList.ItemAt(i)->Path()); 789 } 790 791 fSettings.Flatten(&file); 792 } 793 } 794 795 796 void 797 BackgroundsView::LoadSettings() 798 { 799 fSettings.MakeEmpty(); 800 801 BPath path; 802 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 803 return; 804 805 path.Append(SETTINGS_FILE); 806 BFile file(path.Path(), B_READ_ONLY); 807 if (file.InitCheck() != B_OK) 808 return; 809 810 if (fSettings.Unflatten(&file) != B_OK) { 811 printf("Error unflattening settings file %s\n", path.Path()); 812 return; 813 } 814 815 PRINT_OBJECT(fSettings); 816 817 BString string; 818 if (fSettings.FindString("paneldir", &string) == B_OK) 819 fPanel->SetPanelDirectory(string.String()); 820 821 if (fSettings.FindString("folderpaneldir", &string) == B_OK) 822 fFolderPanel->SetPanelDirectory(string.String()); 823 824 int32 index = 0; 825 while (fSettings.FindString("recentfolder", index, &string) == B_OK) { 826 if (index == 0) 827 fWorkspaceMenu->AddSeparatorItem(); 828 829 BPath path(string.String()); 830 int32 i = AddPath(path); 831 BString s; 832 s << "Folder: " << path.Leaf(); 833 BMenuItem *item = new BMenuItem(s.String(), 834 new BMessage(kMsgFolderSelected)); 835 fWorkspaceMenu->AddItem(item, -i - 1 + 6); 836 index++; 837 } 838 fWorkspaceMenu->SetTargetForItems(this); 839 840 PRINT(("Settings Loaded\n")); 841 } 842 843 844 void 845 BackgroundsView::WorkspaceActivated(uint32 oldWorkspaces, bool active) 846 { 847 UpdateWithCurrent(); 848 } 849 850 851 void 852 BackgroundsView::UpdatePreview() 853 { 854 bool imageEnabled = !(fImageMenu->FindItem(kMsgNoImage)->IsMarked()); 855 if (fPlacementMenu->IsEnabled() ^ imageEnabled) 856 fPlacementMenu->SetEnabled(imageEnabled); 857 if (fIconLabelOutline->IsEnabled() ^ imageEnabled) 858 fIconLabelOutline->SetEnabled(imageEnabled); 859 860 bool textEnabled = (fPlacementMenu->FindItem(kMsgManualPlacement)->IsMarked()) 861 && imageEnabled; 862 if (fXPlacementText->IsEnabled() ^ textEnabled) 863 fXPlacementText->SetEnabled(textEnabled); 864 if (fYPlacementText->IsEnabled() ^ textEnabled) 865 fYPlacementText->SetEnabled(textEnabled); 866 867 if (textEnabled && (strcmp(fXPlacementText->Text(), "") == 0)) { 868 fXPlacementText->SetText("0"); 869 fYPlacementText->SetText("0"); 870 } 871 if (!textEnabled) { 872 fXPlacementText->SetText(NULL); 873 fYPlacementText->SetText(NULL); 874 } 875 876 fXPlacementText->TextView()->MakeSelectable(textEnabled); 877 fYPlacementText->TextView()->MakeSelectable(textEnabled); 878 fXPlacementText->TextView()->MakeEditable(textEnabled); 879 fYPlacementText->TextView()->MakeEditable(textEnabled); 880 881 fPreView->ClearViewBitmap(); 882 883 int32 index = ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex(); 884 if (index >= 0) { 885 BBitmap *bitmap = GetImage(index)->GetBitmap(); 886 if (bitmap) { 887 BackgroundImage::BackgroundImageInfo *info = 888 new BackgroundImage::BackgroundImageInfo(0, index, 889 FindPlacementMode(), BPoint(atoi(fXPlacementText->Text()), 890 atoi(fYPlacementText->Text())), 891 fIconLabelOutline->Value() == B_CONTROL_ON, 0, 0); 892 if (info->fMode == BackgroundImage::kAtOffset) { 893 fPreView->SetEnabled(true); 894 fPreView->fPoint.x = atoi(fXPlacementText->Text()); 895 fPreView->fPoint.y = atoi(fYPlacementText->Text()); 896 } else 897 fPreView->SetEnabled(false); 898 899 fPreView->fImageBounds = BRect(bitmap->Bounds()); 900 fCurrent->Show(info, fPreView); 901 } 902 } else 903 fPreView->SetEnabled(false); 904 905 fPreView->SetViewColor(fPicker->ValueAsColor()); 906 fPreView->Invalidate(); 907 } 908 909 910 BackgroundImage::Mode 911 BackgroundsView::FindPlacementMode() 912 { 913 BackgroundImage::Mode mode = BackgroundImage::kAtOffset; 914 915 if (fPlacementMenu->FindItem(kMsgCenterPlacement)->IsMarked()) 916 mode = BackgroundImage::kCentered; 917 if (fPlacementMenu->FindItem(kMsgScalePlacement)->IsMarked()) 918 mode = BackgroundImage::kScaledToFit; 919 if (fPlacementMenu->FindItem(kMsgManualPlacement)->IsMarked()) 920 mode = BackgroundImage::kAtOffset; 921 if (fPlacementMenu->FindItem(kMsgTilePlacement)->IsMarked()) 922 mode = BackgroundImage::kTiled; 923 924 return mode; 925 } 926 927 928 #ifndef __HAIKU__ 929 inline bool operator!=(const rgb_color& x, const rgb_color& y) 930 { 931 return (x.red != y.red || x.blue != y.blue || x.green != y.green); 932 } 933 #endif 934 935 936 void 937 BackgroundsView::UpdateButtons() 938 { 939 bool hasChanged = false; 940 if (fPicker->IsEnabled() 941 && fPicker->ValueAsColor() != BScreen().DesktopColor()) { 942 hasChanged = true; 943 } else if (fCurrentInfo) { 944 if ((fIconLabelOutline->Value() == B_CONTROL_ON) ^ 945 fCurrentInfo->fTextWidgetLabelOutline) { 946 hasChanged = true; 947 } else if (FindPlacementMode() != fCurrentInfo->fMode) { 948 hasChanged = true; 949 } else if (fCurrentInfo->fImageIndex != 950 ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex()) { 951 hasChanged = true; 952 } else if (fCurrent->IsDesktop() 953 && ((fCurrentInfo->fWorkspace != B_ALL_WORKSPACES) 954 ^ (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()))) { 955 hasChanged = true; 956 } else if (fCurrentInfo->fMode == BackgroundImage::kAtOffset) { 957 BString oldString, newString; 958 oldString << (int)fCurrentInfo->fOffset.x; 959 if (oldString != BString(fXPlacementText->Text())) { 960 hasChanged = true; 961 } 962 oldString = ""; 963 oldString << (int)fCurrentInfo->fOffset.y; 964 if (oldString != BString(fYPlacementText->Text())) { 965 hasChanged = true; 966 } 967 } 968 } else if (fImageMenu->IndexOf(fImageMenu->FindMarked()) > 0) { 969 hasChanged = true; 970 } 971 972 fApply->SetEnabled(hasChanged); 973 fRevert->SetEnabled(hasChanged); 974 } 975 976 977 void 978 BackgroundsView::RefsReceived(BMessage *msg) 979 { 980 entry_ref ref; 981 int32 i = 0; 982 BMimeType imageType("image"); 983 BPath desktopPath; 984 find_directory(B_DESKTOP_DIRECTORY, &desktopPath); 985 986 while (msg->FindRef("refs", i++, &ref) == B_OK) { 987 BPath path; 988 BEntry entry(&ref, true); 989 path.SetTo(&entry); 990 BNode node(&entry); 991 992 if (node.IsFile()) { 993 BMimeType refType; 994 BMimeType::GuessMimeType(&ref, &refType); 995 if (!imageType.Contains(&refType)) 996 continue; 997 998 BGImageMenuItem *item; 999 int32 index = AddImage(path); 1000 if (index >= 0) { 1001 item = FindImageItem(index); 1002 fLastImageIndex = index; 1003 } else { 1004 const char* name = GetImage(-index - 1)->GetName(); 1005 item = new BGImageMenuItem(name, -index - 1, 1006 new BMessage(kMsgImageSelected)); 1007 AddItem(item); 1008 item->SetTarget(this); 1009 fLastImageIndex = -index - 1; 1010 } 1011 1012 item->SetMarked(true); 1013 BMessenger(this).SendMessage(kMsgImageSelected); 1014 } else if (node.IsDirectory()) { 1015 if (desktopPath == path) { 1016 fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->SetMarked(true); 1017 BMessenger(this).SendMessage(kMsgCurrentWorkspace); 1018 break; 1019 } 1020 BMenuItem *item; 1021 int32 index = AddPath(path); 1022 if (index >= 0) { 1023 item = fWorkspaceMenu->ItemAt(index + 6); 1024 fLastWorkspaceIndex = index + 6; 1025 } else { 1026 if (fWorkspaceMenu->CountItems() <= 5) 1027 fWorkspaceMenu->AddSeparatorItem(); 1028 BString s; 1029 s << "Folder: " << path.Leaf(); 1030 item = new BMenuItem(s.String(), new BMessage(kMsgFolderSelected)); 1031 fWorkspaceMenu->AddItem(item, -index - 1 + 6); 1032 item->SetTarget(this); 1033 fLastWorkspaceIndex = -index - 1 + 6; 1034 } 1035 1036 item->SetMarked(true); 1037 BMessenger(this).SendMessage(kMsgFolderSelected); 1038 } 1039 } 1040 } 1041 1042 1043 int32 1044 BackgroundsView::AddPath(BPath path) 1045 { 1046 int32 count = fPathList.CountItems(); 1047 int32 index = 0; 1048 for (; index < count; index++) { 1049 BPath *p = fPathList.ItemAt(index); 1050 int c = BString(p->Path()).ICompare(path.Path()); 1051 if (c == 0) 1052 return index; 1053 1054 if (c > 0) 1055 break; 1056 } 1057 fPathList.AddItem(new BPath(path), index); 1058 return -index - 1; 1059 } 1060 1061 1062 int32 1063 BackgroundsView::AddImage(BPath path) 1064 { 1065 int32 count = fImageList.CountItems(); 1066 int32 index = 0; 1067 for (; index < count; index++) { 1068 Image *image = fImageList.ItemAt(index); 1069 if (image->GetPath() == path) 1070 return index; 1071 } 1072 1073 fImageList.AddItem(new Image(path)); 1074 return -index - 1; 1075 } 1076 1077 1078 void 1079 BackgroundsView::ProcessRefs(entry_ref dir, BMessage* refs) 1080 { 1081 fWorkspaceMenu->FindItem(kMsgDefaultFolder)->SetMarked(true); 1082 BMessenger messenger(this); 1083 messenger.SendMessage(kMsgDefaultFolder); 1084 1085 if (refs->CountNames(B_REF_TYPE) > 0) { 1086 messenger.SendMessage(refs); 1087 } else { 1088 BMessage message(B_REFS_RECEIVED); 1089 message.AddRef("refs", &dir); 1090 messenger.SendMessage(&message); 1091 } 1092 } 1093 1094 1095 Image* 1096 BackgroundsView::GetImage(int32 imageIndex) 1097 { 1098 return fImageList.ItemAt(imageIndex); 1099 } 1100 1101 1102 BGImageMenuItem* 1103 BackgroundsView::FindImageItem(const int32 imageIndex) 1104 { 1105 if (imageIndex < 0) 1106 return (BGImageMenuItem *)fImageMenu->ItemAt(0); 1107 1108 int32 count = fImageMenu->CountItems() - 2; 1109 int32 index = 2; 1110 for (; index < count; index++) { 1111 BGImageMenuItem *image = (BGImageMenuItem *)fImageMenu->ItemAt(index); 1112 if (image->ImageIndex() == imageIndex) 1113 return image; 1114 } 1115 return NULL; 1116 } 1117 1118 1119 bool 1120 BackgroundsView::AddItem(BGImageMenuItem *item) 1121 { 1122 int32 count = fImageMenu->CountItems() - 2; 1123 int32 index = 2; 1124 if (count < index) { 1125 fImageMenu->AddItem(new BSeparatorItem(), 1); 1126 count = fImageMenu->CountItems() - 2; 1127 } 1128 1129 for (; index < count; index++) { 1130 BGImageMenuItem* image = (BGImageMenuItem *)fImageMenu->ItemAt(index); 1131 int c = (BString(image->Label()).ICompare(BString(item->Label()))); 1132 if (c > 0) 1133 break; 1134 } 1135 return fImageMenu->AddItem(item, index); 1136 } 1137 1138 1139 // #pragma mark - 1140 1141 1142 PreView::PreView(BRect frame, const char *name, int32 resize, int32 flags) 1143 : BControl(frame, name, NULL, NULL, resize, flags), 1144 fMoveHandCursor(kHandCursorData) 1145 { 1146 } 1147 1148 1149 void 1150 PreView::AttachedToWindow() 1151 { 1152 rgb_color color = ViewColor(); 1153 BControl::AttachedToWindow(); 1154 SetViewColor(color); 1155 } 1156 1157 1158 void 1159 PreView::MouseDown(BPoint point) 1160 { 1161 if (IsEnabled() && Bounds().Contains(point)) { 1162 uint32 buttons; 1163 GetMouse(&point, &buttons); 1164 if (buttons & B_PRIMARY_MOUSE_BUTTON) { 1165 fOldPoint = point; 1166 SetTracking(true); 1167 BScreen().GetMode(&mode); 1168 x_ratio = Bounds().Width() / mode.virtual_width; 1169 y_ratio = Bounds().Height() / mode.virtual_height; 1170 SetMouseEventMask(B_POINTER_EVENTS, 1171 B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY); 1172 } 1173 } 1174 } 1175 1176 1177 void 1178 PreView::MouseUp(BPoint point) 1179 { 1180 if (IsTracking()) 1181 SetTracking(false); 1182 } 1183 1184 1185 void 1186 PreView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) 1187 { 1188 if (IsEnabled()) 1189 SetViewCursor(&fMoveHandCursor); 1190 else 1191 SetViewCursor(B_CURSOR_SYSTEM_DEFAULT); 1192 1193 if (IsTracking()) { 1194 float x, y; 1195 x = fPoint.x + (point.x - fOldPoint.x) / x_ratio; 1196 y = fPoint.y + (point.y - fOldPoint.y) / y_ratio; 1197 bool min, max, mustSend = false; 1198 min = (x > -fImageBounds.Width()); 1199 max = (x < mode.virtual_width); 1200 if (min && max) { 1201 fOldPoint.x = point.x; 1202 fPoint.x = x; 1203 mustSend = true; 1204 } else { 1205 if (!min && fPoint.x > -fImageBounds.Width()) { 1206 fPoint.x = -fImageBounds.Width(); 1207 fOldPoint.x = point.x - (x - fPoint.x) * x_ratio; 1208 mustSend = true; 1209 } 1210 if (!max && fPoint.x < mode.virtual_width) { 1211 fPoint.x = mode.virtual_width; 1212 fOldPoint.x = point.x - (x - fPoint.x) * x_ratio; 1213 mustSend = true; 1214 } 1215 } 1216 1217 min = (y > -fImageBounds.Height()); 1218 max = (y < mode.virtual_height); 1219 if (min && max) { 1220 fOldPoint.y = point.y; 1221 fPoint.y = y; 1222 mustSend = true; 1223 } else { 1224 if (!min && fPoint.y > -fImageBounds.Height()) { 1225 fPoint.y = -fImageBounds.Height(); 1226 fOldPoint.y = point.y - (y - fPoint.y) * y_ratio; 1227 mustSend = true; 1228 } 1229 if (!max && fPoint.y < mode.virtual_height) { 1230 fPoint.y = mode.virtual_height; 1231 fOldPoint.y = point.y - (y - fPoint.y) * y_ratio; 1232 mustSend = true; 1233 } 1234 } 1235 1236 if (mustSend) { 1237 BMessenger messenger(Parent()); 1238 messenger.SendMessage(kMsgUpdatePreviewPlacement); 1239 } 1240 } 1241 BControl::MouseMoved(point, transit, message); 1242 } 1243 1244 1245 // #pragma mark - 1246 1247 1248 PreviewBox::PreviewBox(BRect frame, const char *name) 1249 : BBox(frame, name) 1250 { 1251 fIsDesktop = true; 1252 } 1253 1254 1255 void 1256 PreviewBox::Draw(BRect rect) 1257 { 1258 // TODO: make view size dependent! 1259 rgb_color color = HighColor(); 1260 1261 SetHighColor(LowColor()); 1262 FillRect(BRect(9, 19, 141, 127)); 1263 1264 if (fIsDesktop) { 1265 BPoint points[] = { 1266 BPoint(11, 19), BPoint(139, 19), BPoint(141, 21), 1267 BPoint(141, 119), BPoint(139, 121), BPoint(118, 121), 1268 BPoint(118, 126), BPoint(117, 127), BPoint(33, 127), 1269 BPoint(32, 126), BPoint(32, 121), BPoint(11, 121), 1270 BPoint(9, 119), BPoint(9, 21), BPoint(11, 19) 1271 }; 1272 SetHighColor(184, 184, 184); 1273 FillPolygon(points, 15); 1274 SetHighColor(96, 96, 96); 1275 StrokePolygon(points, 15); 1276 FillRect(BRect(107, 121, 111, 123)); 1277 SetHighColor(0, 0, 0); 1278 StrokeRect(BRect(14, 24, 136, 116)); 1279 SetHighColor(0, 255, 0); 1280 FillRect(BRect(101, 122, 103, 123)); 1281 } else { 1282 SetHighColor(152, 152, 152); 1283 StrokeLine(BPoint(11, 13), BPoint(67, 13)); 1284 StrokeLine(BPoint(67, 21)); 1285 StrokeLine(BPoint(139, 21)); 1286 StrokeLine(BPoint(139, 119)); 1287 StrokeLine(BPoint(11, 119)); 1288 StrokeLine(BPoint(11, 13)); 1289 StrokeRect(BRect(14, 24, 136, 116)); 1290 SetHighColor(255, 203, 0); 1291 FillRect(BRect(12, 14, 66, 21)); 1292 SetHighColor(240, 240, 240); 1293 StrokeRect(BRect(12, 22, 137, 117)); 1294 StrokeLine(BPoint(138, 22), BPoint(138, 22)); 1295 StrokeLine(BPoint(12, 118), BPoint(12, 118)); 1296 SetHighColor(200, 200, 200); 1297 StrokeRect(BRect(13, 23, 138, 118)); 1298 } 1299 1300 SetHighColor(color); 1301 BBox::Draw(rect); 1302 } 1303 1304 1305 void 1306 PreviewBox::SetDesktop(bool isDesktop) 1307 { 1308 fIsDesktop = isDesktop; 1309 Invalidate(); 1310 } 1311 1312 1313 // #pragma mark - 1314 1315 1316 BGImageMenuItem::BGImageMenuItem(const char *label, int32 imageIndex, 1317 BMessage *message, char shortcut, uint32 modifiers) 1318 : BMenuItem(label, message, shortcut, modifiers), 1319 fImageIndex(imageIndex) 1320 { 1321 } 1322