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