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