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 kMsgIconLabelBackground = 'ilcb'; 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 fIconLabelBackground = new BCheckBox(rect, "iconLabelBackground", 211 "Icon label background", new BMessage(kMsgIconLabelBackground)); 212 fIconLabelBackground->SetValue(B_CONTROL_ON); 213 fIconLabelBackground->ResizeToPreferred(); 214 rightbox->AddChild(fIconLabelBackground); 215 216 rect.top += fIconLabelBackground->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(fIconLabelBackground->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 fIconLabelBackground->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 kMsgIconLabelBackground: 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 } else { 511 fIconLabelBackground->SetValue(fCurrentInfo->fEraseTextWidgetBackground 512 ? B_CONTROL_ON : B_CONTROL_OFF); 513 514 BString xtext, ytext; 515 int32 cmd = 0; 516 switch (fCurrentInfo->fMode) { 517 case BackgroundImage::kCentered: 518 cmd = kMsgCenterPlacement; 519 break; 520 case BackgroundImage::kScaledToFit: 521 cmd = kMsgScalePlacement; 522 break; 523 case BackgroundImage::kAtOffset: 524 cmd = kMsgManualPlacement; 525 xtext << (int)fCurrentInfo->fOffset.x; 526 ytext << (int)fCurrentInfo->fOffset.y; 527 break; 528 case BackgroundImage::kTiled: 529 cmd = kMsgTilePlacement; 530 break; 531 } 532 533 if (cmd != 0) 534 fPlacementMenu->FindItem(cmd)->SetMarked(true); 535 536 fXPlacementText->SetText(xtext.String()); 537 fYPlacementText->SetText(ytext.String()); 538 539 fLastImageIndex = fCurrentInfo->fImageIndex; 540 FindImageItem(fLastImageIndex)->SetMarked(true); 541 } 542 543 rgb_color color = {255, 255, 255, 255}; 544 if (fCurrent->IsDesktop()) { 545 color = BScreen().DesktopColor(); 546 fPicker->SetEnabled(true); 547 } else 548 fPicker->SetEnabled(false); 549 550 fPicker->SetValue(color); 551 552 UpdatePreview(); 553 UpdateButtons(); 554 } 555 556 557 void 558 BackgroundsView::Save() 559 { 560 bool eraseTextWidgetBackground = 561 fIconLabelBackground->Value() == B_CONTROL_ON; 562 BackgroundImage::Mode mode = FindPlacementMode(); 563 BPoint offset(atoi(fXPlacementText->Text()), atoi(fYPlacementText->Text())); 564 565 if (!fCurrent->IsDesktop()) { 566 if (fCurrentInfo == NULL) { 567 fCurrentInfo = new BackgroundImage::BackgroundImageInfo(B_ALL_WORKSPACES, 568 fLastImageIndex, mode, offset, eraseTextWidgetBackground, 0, 0); 569 fCurrent->Add(fCurrentInfo); 570 } else { 571 fCurrentInfo->fEraseTextWidgetBackground = eraseTextWidgetBackground; 572 fCurrentInfo->fMode = mode; 573 if (fCurrentInfo->fMode == BackgroundImage::kAtOffset) 574 fCurrentInfo->fOffset = offset; 575 fCurrentInfo->fImageIndex = fLastImageIndex; 576 } 577 } else { 578 uint32 workspaceMask = 1; 579 int32 workspace = current_workspace(); 580 for (; workspace; workspace--) 581 workspaceMask *= 2; 582 583 if (fCurrentInfo != NULL) { 584 if (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 585 if (fCurrentInfo->fWorkspace != workspaceMask) { 586 fCurrentInfo->fWorkspace = fCurrentInfo->fWorkspace 587 ^ workspaceMask; 588 if (fLastImageIndex > -1) { 589 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 590 workspaceMask, fLastImageIndex, mode, offset, 591 eraseTextWidgetBackground, fCurrentInfo->fImageSet, 592 fCurrentInfo->fCacheMode); 593 fCurrent->Add(fCurrentInfo); 594 } 595 } else { 596 if (fLastImageIndex > -1) { 597 fCurrentInfo->fEraseTextWidgetBackground = 598 eraseTextWidgetBackground; 599 fCurrentInfo->fMode = mode; 600 if (fCurrentInfo->fMode == BackgroundImage::kAtOffset) 601 fCurrentInfo->fOffset = offset; 602 603 fCurrentInfo->fImageIndex = fLastImageIndex; 604 } else { 605 fCurrent->Remove(fCurrentInfo); 606 fCurrentInfo = NULL; 607 } 608 } 609 } else if (fLastImageIndex > -1) { 610 fCurrent->RemoveAll(); 611 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 612 B_ALL_WORKSPACES, fLastImageIndex, mode, offset, 613 eraseTextWidgetBackground, fCurrent->GetShowingImageSet(), 614 fCurrentInfo->fCacheMode); 615 fCurrent->Add(fCurrentInfo); 616 } 617 } else if (fLastImageIndex > -1) { 618 if (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 619 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 620 workspaceMask, fLastImageIndex, mode, offset, 621 eraseTextWidgetBackground, fCurrent->GetShowingImageSet(), 0); 622 } else { 623 fCurrent->RemoveAll(); 624 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 625 B_ALL_WORKSPACES, fLastImageIndex, mode, offset, 626 eraseTextWidgetBackground, fCurrent->GetShowingImageSet(), 0); 627 } 628 fCurrent->Add(fCurrentInfo); 629 } 630 631 if (!fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 632 for (int32 i = 0; i < count_workspaces(); i++) { 633 BScreen().SetDesktopColor(fPicker->ValueAsColor(), i, true); 634 } 635 } else 636 BScreen().SetDesktopColor(fPicker->ValueAsColor(), true); 637 } 638 639 BNode node(&fCurrentRef); 640 641 status_t status = fCurrent->SetBackgroundImage(&node); 642 if (status != B_OK) { 643 // TODO: this should be a BAlert! 644 printf("setting background image failed: %s\n", strerror(status)); 645 } 646 } 647 648 649 void 650 BackgroundsView::NotifyServer() 651 { 652 BMessenger tracker("application/x-vnd.Be-TRAK"); 653 654 if (fCurrent->IsDesktop()) { 655 tracker.SendMessage(new BMessage(B_RESTORE_BACKGROUND_IMAGE)); 656 } else { 657 int32 i = -1; 658 BMessage reply; 659 int32 err; 660 BEntry currentEntry(&fCurrentRef); 661 BPath currentPath(¤tEntry); 662 bool isCustomFolder = !fWorkspaceMenu->FindItem(kMsgDefaultFolder)->IsMarked(); 663 664 do { 665 BMessage msg(B_GET_PROPERTY); 666 i++; 667 668 // look at the "Poses" in every Tracker window 669 msg.AddSpecifier("Poses"); 670 msg.AddSpecifier("Window", i); 671 672 reply.MakeEmpty(); 673 tracker.SendMessage(&msg, &reply); 674 675 // break out of the loop when we're at the end of 676 // the windows 677 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD 678 && reply.FindInt32("error", &err) == B_OK 679 && err == B_BAD_INDEX) 680 break; 681 682 // don't stop for windows that don't understand 683 // a request for "Poses"; they're not displaying 684 // folders 685 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD 686 && reply.FindInt32("error", &err) == B_OK 687 && err != B_BAD_SCRIPT_SYNTAX) 688 continue; 689 690 BMessenger trackerWindow; 691 if (reply.FindMessenger("result", &trackerWindow) != B_OK) 692 continue; 693 694 if (isCustomFolder) { 695 // found a window with poses, ask for its path 696 msg.MakeEmpty(); 697 msg.what = B_GET_PROPERTY; 698 msg.AddSpecifier("Path"); 699 msg.AddSpecifier("Poses"); 700 msg.AddSpecifier("Window", i); 701 702 reply.MakeEmpty(); 703 tracker.SendMessage(&msg, &reply); 704 705 // go on with the next if this din't have a path 706 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD) 707 continue; 708 709 entry_ref ref; 710 if (reply.FindRef("result", &ref) == B_OK) { 711 BEntry entry(&ref); 712 BPath path(&entry); 713 714 // these are not the paths you're looking for 715 if (currentPath != path) 716 continue; 717 } 718 } 719 720 trackerWindow.SendMessage(B_RESTORE_BACKGROUND_IMAGE); 721 } while (true); 722 } 723 } 724 725 726 int32 727 BackgroundsView::NotifyThread(void *data) 728 { 729 BackgroundsView *view = (BackgroundsView*)data; 730 731 view->NotifyServer(); 732 return B_OK; 733 } 734 735 736 void 737 BackgroundsView::SaveSettings(void) 738 { 739 BPath path; 740 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 741 path.Append(SETTINGS_FILE); 742 BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); 743 744 BPoint point = Window()->Frame().LeftTop(); 745 if (fSettings.ReplacePoint("pos", point) != B_OK) 746 fSettings.AddPoint("pos", point); 747 748 entry_ref ref; 749 BEntry entry; 750 BPath path; 751 752 fPanel->GetPanelDirectory(&ref); 753 entry.SetTo(&ref); 754 entry.GetPath(&path); 755 if (fSettings.ReplaceString("paneldir", path.Path()) != B_OK) 756 fSettings.AddString("paneldir", path.Path()); 757 758 fFolderPanel->GetPanelDirectory(&ref); 759 entry.SetTo(&ref); 760 entry.GetPath(&path); 761 if (fSettings.ReplaceString("folderpaneldir", path.Path()) != B_OK) 762 fSettings.AddString("folderpaneldir", path.Path()); 763 764 fSettings.RemoveName("recentfolder"); 765 for (int32 i = 0; i < fPathList.CountItems(); i++) { 766 fSettings.AddString("recentfolder", fPathList.ItemAt(i)->Path()); 767 } 768 769 fSettings.Flatten(&file); 770 } 771 } 772 773 774 void 775 BackgroundsView::LoadSettings() 776 { 777 fSettings.MakeEmpty(); 778 779 BPath path; 780 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 781 return; 782 783 path.Append(SETTINGS_FILE); 784 BFile file(path.Path(), B_READ_ONLY); 785 if (file.InitCheck() != B_OK) 786 return; 787 788 if (fSettings.Unflatten(&file) != B_OK) { 789 printf("Error unflattening settings file %s\n", path.Path()); 790 return; 791 } 792 793 PRINT_OBJECT(fSettings); 794 795 BPoint point; 796 if (fSettings.FindPoint("pos", &point) == B_OK) 797 Window()->MoveTo(point); 798 799 BString string; 800 if (fSettings.FindString("paneldir", &string) == B_OK) 801 fPanel->SetPanelDirectory(string.String()); 802 803 if (fSettings.FindString("folderpaneldir", &string) == B_OK) 804 fFolderPanel->SetPanelDirectory(string.String()); 805 806 int32 index = 0; 807 while (fSettings.FindString("recentfolder", index, &string) == B_OK) { 808 if (index == 0) 809 fWorkspaceMenu->AddSeparatorItem(); 810 811 BPath path(string.String()); 812 int32 i = AddPath(path); 813 BString s; 814 s << "Folder: " << path.Leaf(); 815 BMenuItem *item = new BMenuItem(s.String(), 816 new BMessage(kMsgFolderSelected)); 817 fWorkspaceMenu->AddItem(item, -i - 1 + 6); 818 index++; 819 } 820 fWorkspaceMenu->SetTargetForItems(this); 821 822 PRINT(("Settings Loaded\n")); 823 } 824 825 826 void 827 BackgroundsView::WorkspaceActivated(uint32 oldWorkspaces, bool active) 828 { 829 UpdateWithCurrent(); 830 } 831 832 833 void 834 BackgroundsView::UpdatePreview() 835 { 836 bool imageEnabled = !(fImageMenu->FindItem(kMsgNoImage)->IsMarked()); 837 if (fPlacementMenu->IsEnabled() ^ imageEnabled) 838 fPlacementMenu->SetEnabled(imageEnabled); 839 if (fIconLabelBackground->IsEnabled() ^ imageEnabled) 840 fIconLabelBackground->SetEnabled(imageEnabled); 841 842 bool textEnabled = (fPlacementMenu->FindItem(kMsgManualPlacement)->IsMarked()) 843 && imageEnabled; 844 if (fXPlacementText->IsEnabled() ^ textEnabled) 845 fXPlacementText->SetEnabled(textEnabled); 846 if (fYPlacementText->IsEnabled() ^ textEnabled) 847 fYPlacementText->SetEnabled(textEnabled); 848 849 if (textEnabled && (strcmp(fXPlacementText->Text(), "") == 0)) { 850 fXPlacementText->SetText("0"); 851 fYPlacementText->SetText("0"); 852 } 853 if (!textEnabled) { 854 fXPlacementText->SetText(NULL); 855 fYPlacementText->SetText(NULL); 856 } 857 858 fXPlacementText->TextView()->MakeSelectable(textEnabled); 859 fYPlacementText->TextView()->MakeSelectable(textEnabled); 860 fXPlacementText->TextView()->MakeEditable(textEnabled); 861 fYPlacementText->TextView()->MakeEditable(textEnabled); 862 863 fPreView->ClearViewBitmap(); 864 865 int32 index = ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex(); 866 if (index >= 0) { 867 BBitmap *bitmap = GetImage(index)->GetBitmap(); 868 if (bitmap) { 869 BackgroundImage::BackgroundImageInfo *info = 870 new BackgroundImage::BackgroundImageInfo(0, index, 871 FindPlacementMode(), BPoint(atoi(fXPlacementText->Text()), 872 atoi(fYPlacementText->Text())), 873 fIconLabelBackground->Value() == B_CONTROL_ON, 0, 0); 874 if (info->fMode == BackgroundImage::kAtOffset) { 875 fPreView->SetEnabled(true); 876 fPreView->fPoint.x = atoi(fXPlacementText->Text()); 877 fPreView->fPoint.y = atoi(fYPlacementText->Text()); 878 } else 879 fPreView->SetEnabled(false); 880 881 fPreView->fImageBounds = BRect(bitmap->Bounds()); 882 fCurrent->Show(info, fPreView); 883 } 884 } else 885 fPreView->SetEnabled(false); 886 887 fPreView->SetViewColor(fPicker->ValueAsColor()); 888 fPreView->Invalidate(); 889 } 890 891 892 BackgroundImage::Mode 893 BackgroundsView::FindPlacementMode() 894 { 895 BackgroundImage::Mode mode = BackgroundImage::kAtOffset; 896 897 if (fPlacementMenu->FindItem(kMsgCenterPlacement)->IsMarked()) 898 mode = BackgroundImage::kCentered; 899 if (fPlacementMenu->FindItem(kMsgScalePlacement)->IsMarked()) 900 mode = BackgroundImage::kScaledToFit; 901 if (fPlacementMenu->FindItem(kMsgManualPlacement)->IsMarked()) 902 mode = BackgroundImage::kAtOffset; 903 if (fPlacementMenu->FindItem(kMsgTilePlacement)->IsMarked()) 904 mode = BackgroundImage::kTiled; 905 906 return mode; 907 } 908 909 910 #ifndef __HAIKU__ 911 inline bool operator!=(const rgb_color& x, const rgb_color& y) 912 { 913 return (x.red != y.red || x.blue != y.blue || x.green != y.green); 914 } 915 #endif 916 917 918 void 919 BackgroundsView::UpdateButtons() 920 { 921 bool hasChanged = false; 922 if (fPicker->IsEnabled() 923 && fPicker->ValueAsColor() != BScreen().DesktopColor()) { 924 hasChanged = true; 925 } else if (fCurrentInfo) { 926 if ((fIconLabelBackground->Value() == B_CONTROL_ON) ^ 927 fCurrentInfo->fEraseTextWidgetBackground) { 928 hasChanged = true; 929 } else if (FindPlacementMode() != fCurrentInfo->fMode) { 930 hasChanged = true; 931 } else if (fCurrentInfo->fImageIndex != 932 ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex()) { 933 hasChanged = true; 934 } else if (fCurrent->IsDesktop() 935 && ((fCurrentInfo->fWorkspace != B_ALL_WORKSPACES) 936 ^ (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()))) { 937 hasChanged = true; 938 } else if (fCurrentInfo->fMode == BackgroundImage::kAtOffset) { 939 BString oldString, newString; 940 oldString << (int)fCurrentInfo->fOffset.x; 941 if (oldString != BString(fXPlacementText->Text())) { 942 hasChanged = true; 943 } 944 oldString = ""; 945 oldString << (int)fCurrentInfo->fOffset.y; 946 if (oldString != BString(fYPlacementText->Text())) { 947 hasChanged = true; 948 } 949 } 950 } else if (fImageMenu->IndexOf(fImageMenu->FindMarked()) > 0) { 951 hasChanged = true; 952 } 953 954 fApply->SetEnabled(hasChanged); 955 fRevert->SetEnabled(hasChanged); 956 } 957 958 959 void 960 BackgroundsView::RefsReceived(BMessage *msg) 961 { 962 entry_ref ref; 963 int32 i = 0; 964 BMimeType imageType("image"); 965 BPath desktopPath; 966 find_directory(B_DESKTOP_DIRECTORY, &desktopPath); 967 968 while (msg->FindRef("refs", i++, &ref) == B_OK) { 969 BPath path; 970 BEntry entry(&ref, true); 971 path.SetTo(&entry); 972 BNode node(&entry); 973 974 if (node.IsFile()) { 975 BMimeType refType; 976 BMimeType::GuessMimeType(&ref, &refType); 977 if (!imageType.Contains(&refType)) 978 continue; 979 980 BGImageMenuItem *item; 981 int32 index = AddImage(path); 982 if (index >= 0) { 983 item = FindImageItem(index); 984 fLastImageIndex = index; 985 } else { 986 const char* name = GetImage(-index - 1)->GetName(); 987 item = new BGImageMenuItem(name, -index - 1, 988 new BMessage(kMsgImageSelected)); 989 AddItem(item); 990 item->SetTarget(this); 991 fLastImageIndex = -index - 1; 992 } 993 994 item->SetMarked(true); 995 BMessenger(this).SendMessage(kMsgImageSelected); 996 } else if (node.IsDirectory()) { 997 if (desktopPath == path) { 998 fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->SetMarked(true); 999 BMessenger(this).SendMessage(kMsgCurrentWorkspace); 1000 break; 1001 } 1002 BMenuItem *item; 1003 int32 index = AddPath(path); 1004 if (index >= 0) { 1005 item = fWorkspaceMenu->ItemAt(index + 6); 1006 fLastWorkspaceIndex = index + 6; 1007 } else { 1008 if (fWorkspaceMenu->CountItems() <= 5) 1009 fWorkspaceMenu->AddSeparatorItem(); 1010 BString s; 1011 s << "Folder: " << path.Leaf(); 1012 item = new BMenuItem(s.String(), new BMessage(kMsgFolderSelected)); 1013 fWorkspaceMenu->AddItem(item, -index - 1 + 6); 1014 item->SetTarget(this); 1015 fLastWorkspaceIndex = -index - 1 + 6; 1016 } 1017 1018 item->SetMarked(true); 1019 BMessenger(this).SendMessage(kMsgFolderSelected); 1020 } 1021 } 1022 } 1023 1024 1025 int32 1026 BackgroundsView::AddPath(BPath path) 1027 { 1028 int32 count = fPathList.CountItems(); 1029 int32 index = 0; 1030 for (; index < count; index++) { 1031 BPath *p = fPathList.ItemAt(index); 1032 int c = BString(p->Path()).ICompare(path.Path()); 1033 if (c == 0) 1034 return index; 1035 1036 if (c > 0) 1037 break; 1038 } 1039 fPathList.AddItem(new BPath(path), index); 1040 return -index - 1; 1041 } 1042 1043 1044 int32 1045 BackgroundsView::AddImage(BPath path) 1046 { 1047 int32 count = fImageList.CountItems(); 1048 int32 index = 0; 1049 for (; index < count; index++) { 1050 Image *image = fImageList.ItemAt(index); 1051 if (image->GetPath() == path) 1052 return index; 1053 } 1054 1055 fImageList.AddItem(new Image(path)); 1056 return -index - 1; 1057 } 1058 1059 1060 void 1061 BackgroundsView::ProcessRefs(entry_ref dir, BMessage* refs) 1062 { 1063 fWorkspaceMenu->FindItem(kMsgDefaultFolder)->SetMarked(true); 1064 BMessenger messenger(this); 1065 messenger.SendMessage(kMsgDefaultFolder); 1066 1067 if (refs->CountNames(B_REF_TYPE) > 0) { 1068 messenger.SendMessage(refs); 1069 } else { 1070 BMessage message(B_REFS_RECEIVED); 1071 message.AddRef("refs", &dir); 1072 messenger.SendMessage(&message); 1073 } 1074 } 1075 1076 1077 Image* 1078 BackgroundsView::GetImage(int32 imageIndex) 1079 { 1080 return fImageList.ItemAt(imageIndex); 1081 } 1082 1083 1084 BGImageMenuItem* 1085 BackgroundsView::FindImageItem(const int32 imageIndex) 1086 { 1087 if (imageIndex < 0) 1088 return (BGImageMenuItem *)fImageMenu->ItemAt(0); 1089 1090 int32 count = fImageMenu->CountItems() - 2; 1091 int32 index = 2; 1092 for (; index < count; index++) { 1093 BGImageMenuItem *image = (BGImageMenuItem *)fImageMenu->ItemAt(index); 1094 if (image->ImageIndex() == imageIndex) 1095 return image; 1096 } 1097 return NULL; 1098 } 1099 1100 1101 bool 1102 BackgroundsView::AddItem(BGImageMenuItem *item) 1103 { 1104 int32 count = fImageMenu->CountItems() - 2; 1105 int32 index = 2; 1106 if (count < index) { 1107 fImageMenu->AddItem(new BSeparatorItem(), 1); 1108 count = fImageMenu->CountItems() - 2; 1109 } 1110 1111 for (; index < count; index++) { 1112 BGImageMenuItem* image = (BGImageMenuItem *)fImageMenu->ItemAt(index); 1113 int c = (BString(image->Label()).ICompare(BString(item->Label()))); 1114 if (c > 0) 1115 break; 1116 } 1117 return fImageMenu->AddItem(item, index); 1118 } 1119 1120 1121 // #pragma mark - 1122 1123 1124 PreView::PreView(BRect frame, const char *name, int32 resize, int32 flags) 1125 : BControl(frame, name, NULL, NULL, resize, flags), 1126 fMoveHandCursor(kHandCursorData) 1127 { 1128 } 1129 1130 1131 void 1132 PreView::AttachedToWindow() 1133 { 1134 rgb_color color = ViewColor(); 1135 BControl::AttachedToWindow(); 1136 SetViewColor(color); 1137 } 1138 1139 1140 void 1141 PreView::MouseDown(BPoint point) 1142 { 1143 if (IsEnabled() && Bounds().Contains(point)) { 1144 uint32 buttons; 1145 GetMouse(&point, &buttons); 1146 if (buttons & B_PRIMARY_MOUSE_BUTTON) { 1147 fOldPoint = point; 1148 SetTracking(true); 1149 BScreen().GetMode(&mode); 1150 x_ratio = Bounds().Width() / mode.virtual_width; 1151 y_ratio = Bounds().Height() / mode.virtual_height; 1152 SetMouseEventMask(B_POINTER_EVENTS, 1153 B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY); 1154 } 1155 } 1156 } 1157 1158 1159 void 1160 PreView::MouseUp(BPoint point) 1161 { 1162 if (IsTracking()) 1163 SetTracking(false); 1164 } 1165 1166 1167 void 1168 PreView::MouseMoved(BPoint point, uint32 transit, const BMessage *message) 1169 { 1170 if (IsEnabled()) 1171 SetViewCursor(&fMoveHandCursor); 1172 else 1173 SetViewCursor(B_CURSOR_SYSTEM_DEFAULT); 1174 1175 if (IsTracking()) { 1176 float x, y; 1177 x = fPoint.x + (point.x - fOldPoint.x) / x_ratio; 1178 y = fPoint.y + (point.y - fOldPoint.y) / y_ratio; 1179 bool min, max, mustSend = false; 1180 min = (x > -fImageBounds.Width()); 1181 max = (x < mode.virtual_width); 1182 if (min && max) { 1183 fOldPoint.x = point.x; 1184 fPoint.x = x; 1185 mustSend = true; 1186 } else { 1187 if (!min && fPoint.x > -fImageBounds.Width()) { 1188 fPoint.x = -fImageBounds.Width(); 1189 fOldPoint.x = point.x - (x - fPoint.x) * x_ratio; 1190 mustSend = true; 1191 } 1192 if (!max && fPoint.x < mode.virtual_width) { 1193 fPoint.x = mode.virtual_width; 1194 fOldPoint.x = point.x - (x - fPoint.x) * x_ratio; 1195 mustSend = true; 1196 } 1197 } 1198 1199 min = (y > -fImageBounds.Height()); 1200 max = (y < mode.virtual_height); 1201 if (min && max) { 1202 fOldPoint.y = point.y; 1203 fPoint.y = y; 1204 mustSend = true; 1205 } else { 1206 if (!min && fPoint.y > -fImageBounds.Height()) { 1207 fPoint.y = -fImageBounds.Height(); 1208 fOldPoint.y = point.y - (y - fPoint.y) * y_ratio; 1209 mustSend = true; 1210 } 1211 if (!max && fPoint.y < mode.virtual_height) { 1212 fPoint.y = mode.virtual_height; 1213 fOldPoint.y = point.y - (y - fPoint.y) * y_ratio; 1214 mustSend = true; 1215 } 1216 } 1217 1218 if (mustSend) { 1219 BMessenger messenger(Parent()); 1220 messenger.SendMessage(kMsgUpdatePreviewPlacement); 1221 } 1222 } 1223 BControl::MouseMoved(point, transit, message); 1224 } 1225 1226 1227 // #pragma mark - 1228 1229 1230 PreviewBox::PreviewBox(BRect frame, const char *name) 1231 : BBox(frame, name) 1232 { 1233 fIsDesktop = true; 1234 } 1235 1236 1237 void 1238 PreviewBox::Draw(BRect rect) 1239 { 1240 // TODO: make view size dependent! 1241 rgb_color color = HighColor(); 1242 1243 SetHighColor(LowColor()); 1244 FillRect(BRect(9, 19, 141, 127)); 1245 1246 if (fIsDesktop) { 1247 BPoint points[] = { 1248 BPoint(11, 19), BPoint(139, 19), BPoint(141, 21), 1249 BPoint(141, 119), BPoint(139, 121), BPoint(118, 121), 1250 BPoint(118, 126), BPoint(117, 127), BPoint(33, 127), 1251 BPoint(32, 126), BPoint(32, 121), BPoint(11, 121), 1252 BPoint(9, 119), BPoint(9, 21), BPoint(11, 19) 1253 }; 1254 SetHighColor(184, 184, 184); 1255 FillPolygon(points, 15); 1256 SetHighColor(96, 96, 96); 1257 StrokePolygon(points, 15); 1258 FillRect(BRect(107, 121, 111, 123)); 1259 SetHighColor(0, 0, 0); 1260 StrokeRect(BRect(14, 24, 136, 116)); 1261 SetHighColor(0, 255, 0); 1262 FillRect(BRect(101, 122, 103, 123)); 1263 } else { 1264 SetHighColor(152, 152, 152); 1265 StrokeLine(BPoint(11, 13), BPoint(67, 13)); 1266 StrokeLine(BPoint(67, 21)); 1267 StrokeLine(BPoint(139, 21)); 1268 StrokeLine(BPoint(139, 119)); 1269 StrokeLine(BPoint(11, 119)); 1270 StrokeLine(BPoint(11, 13)); 1271 StrokeRect(BRect(14, 24, 136, 116)); 1272 SetHighColor(255, 203, 0); 1273 FillRect(BRect(12, 14, 66, 21)); 1274 SetHighColor(240, 240, 240); 1275 StrokeRect(BRect(12, 22, 137, 117)); 1276 StrokeLine(BPoint(138, 22), BPoint(138, 22)); 1277 StrokeLine(BPoint(12, 118), BPoint(12, 118)); 1278 SetHighColor(200, 200, 200); 1279 StrokeRect(BRect(13, 23, 138, 118)); 1280 } 1281 1282 SetHighColor(color); 1283 BBox::Draw(rect); 1284 } 1285 1286 1287 void 1288 PreviewBox::SetDesktop(bool isDesktop) 1289 { 1290 fIsDesktop = isDesktop; 1291 Invalidate(); 1292 } 1293 1294 1295 // #pragma mark - 1296 1297 1298 BGImageMenuItem::BGImageMenuItem(const char *label, int32 imageIndex, 1299 BMessage *message, char shortcut, uint32 modifiers) 1300 : BMenuItem(label, message, shortcut, modifiers), 1301 fImageIndex(imageIndex) 1302 { 1303 } 1304