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