1 /* 2 * Copyright 2002-2013 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 * Jerome Duval, jerome.duval@free.fr 8 * Jonas Sundström, jonas@kirilla.se 9 * John Scipione, jscipione@gmail.com 10 */ 11 12 13 #include "BackgroundsView.h" 14 15 #include <stdio.h> 16 #include <stdlib.h> 17 18 #include <Bitmap.h> 19 #include <Catalog.h> 20 #include <ControlLook.h> 21 #include <Cursor.h> 22 #include <Debug.h> 23 #include <File.h> 24 #include <FindDirectory.h> 25 #include <LayoutBuilder.h> 26 #include <Locale.h> 27 #include <MenuField.h> 28 #include <Messenger.h> 29 #include <MimeType.h> 30 #include <Point.h> 31 #include <PopUpMenu.h> 32 33 #include <be_apps/Tracker/Background.h> 34 35 #include "ImageFilePanel.h" 36 37 38 #undef B_TRANSLATION_CONTEXT 39 #define B_TRANSLATION_CONTEXT "Main View" 40 41 42 static const uint32 kMsgApplySettings = 'aply'; 43 static const uint32 kMsgRevertSettings = 'rvrt'; 44 45 static const uint32 kMsgUpdateColor = 'upcl'; 46 static const uint32 kMsgAllWorkspaces = 'alwk'; 47 static const uint32 kMsgCurrentWorkspace = 'crwk'; 48 static const uint32 kMsgDefaultFolder = 'dffl'; 49 static const uint32 kMsgOtherFolder = 'otfl'; 50 static const uint32 kMsgNoImage = 'noim'; 51 static const uint32 kMsgOtherImage = 'otim'; 52 static const uint32 kMsgImageSelected = 'imsl'; 53 static const uint32 kMsgFolderSelected = 'flsl'; 54 55 static const uint32 kMsgCenterPlacement = 'cnpl'; 56 static const uint32 kMsgManualPlacement = 'mnpl'; 57 static const uint32 kMsgScalePlacement = 'scpl'; 58 static const uint32 kMsgTilePlacement = 'tlpl'; 59 static const uint32 kMsgIconLabelOutline = 'ilol'; 60 61 static const uint32 kMsgImagePlacement = 'xypl'; 62 static const uint32 kMsgUpdatePreviewPlacement = 'pvpl'; 63 64 65 BackgroundsView::BackgroundsView() 66 : 67 BBox("BackgroundsView"), 68 fCurrent(NULL), 69 fCurrentInfo(NULL), 70 fLastImageIndex(-1), 71 fPathList(1, true), 72 fImageList(1, true), 73 fFoundPositionSetting(false) 74 { 75 SetBorder(B_NO_BORDER); 76 77 BBox* previewBox = new BBox("preview"); 78 previewBox->SetLabel(B_TRANSLATE("Preview")); 79 80 fPreview = new Preview(); 81 82 fTopLeft = new FramePart(FRAME_TOP_LEFT); 83 fTop = new FramePart(FRAME_TOP); 84 fTopRight = new FramePart(FRAME_TOP_RIGHT); 85 fLeft = new FramePart(FRAME_LEFT_SIDE); 86 fRight = new FramePart(FRAME_RIGHT_SIDE); 87 fBottomLeft = new FramePart(FRAME_BOTTOM_LEFT); 88 fBottom = new FramePart(FRAME_BOTTOM); 89 fBottomRight = new FramePart(FRAME_BOTTOM_RIGHT); 90 91 fXPlacementText = new BTextControl(B_TRANSLATE("X:"), NULL, 92 new BMessage(kMsgImagePlacement)); 93 fYPlacementText = new BTextControl(B_TRANSLATE("Y:"), NULL, 94 new BMessage(kMsgImagePlacement)); 95 96 fXPlacementText->TextView()->SetMaxBytes(5); 97 fYPlacementText->TextView()->SetMaxBytes(5); 98 99 for (int32 i = 0; i < 256; i++) { 100 if ((i < '0' || i > '9') && i != '-') { 101 fXPlacementText->TextView()->DisallowChar(i); 102 fYPlacementText->TextView()->DisallowChar(i); 103 } 104 } 105 106 previewBox->AddChild(BLayoutBuilder::Group<>() 107 .AddGlue() 108 .AddGroup(B_VERTICAL, 0) 109 .AddGroup(B_HORIZONTAL, 0) 110 .AddGlue() 111 .AddGrid(0, 0, 1) 112 .Add(fTopLeft, 0, 0) 113 .Add(fTop, 1, 0) 114 .Add(fTopRight, 2, 0) 115 .Add(fLeft, 0, 1) 116 .Add(fPreview, 1, 1) 117 .Add(fRight, 2, 1) 118 .Add(fBottomLeft, 0, 2) 119 .Add(fBottom, 1, 2) 120 .Add(fBottomRight, 2, 2) 121 .End() 122 .AddGlue() 123 .End() 124 .AddStrut(be_control_look->DefaultItemSpacing() * 2) 125 .AddGroup(B_HORIZONTAL) 126 .Add(fXPlacementText) 127 .Add(fYPlacementText) 128 .End() 129 .AddGlue() 130 .SetInsets(B_USE_DEFAULT_SPACING) 131 .End() 132 .AddGlue() 133 .View()); 134 135 BBox* rightbox = new BBox("rightbox"); 136 137 fWorkspaceMenu = new BPopUpMenu(B_TRANSLATE("pick one")); 138 fWorkspaceMenu->AddItem(new BMenuItem(B_TRANSLATE("All workspaces"), 139 new BMessage(kMsgAllWorkspaces))); 140 BMenuItem* menuItem; 141 fWorkspaceMenu->AddItem(menuItem = new BMenuItem( 142 B_TRANSLATE("Current workspace"), 143 new BMessage(kMsgCurrentWorkspace))); 144 menuItem->SetMarked(true); 145 fLastWorkspaceIndex = 146 fWorkspaceMenu->IndexOf(fWorkspaceMenu->FindMarked()); 147 fWorkspaceMenu->AddSeparatorItem(); 148 fWorkspaceMenu->AddItem(new BMenuItem(B_TRANSLATE("Default folder"), 149 new BMessage(kMsgDefaultFolder))); 150 fWorkspaceMenu->AddItem(new BMenuItem( 151 B_TRANSLATE("Other folder" B_UTF8_ELLIPSIS), 152 new BMessage(kMsgOtherFolder))); 153 154 BMenuField* workspaceMenuField = new BMenuField("workspaceMenuField", 155 NULL, fWorkspaceMenu); 156 workspaceMenuField->ResizeToPreferred(); 157 rightbox->SetLabel(workspaceMenuField); 158 159 fImageMenu = new BPopUpMenu(B_TRANSLATE("pick one")); 160 fImageMenu->AddItem(new BGImageMenuItem(B_TRANSLATE("None"), -1, 161 new BMessage(kMsgNoImage))); 162 fImageMenu->AddSeparatorItem(); 163 fImageMenu->AddItem(new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS), 164 new BMessage(kMsgOtherImage))); 165 166 BMenuField* imageMenuField = new BMenuField("image", 167 B_TRANSLATE("Image:"), fImageMenu); 168 imageMenuField->SetAlignment(B_ALIGN_RIGHT); 169 170 fPlacementMenu = new BPopUpMenu(B_TRANSLATE("pick one")); 171 fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Manual"), 172 new BMessage(kMsgManualPlacement))); 173 fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Center"), 174 new BMessage(kMsgCenterPlacement))); 175 fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Scale to fit"), 176 new BMessage(kMsgScalePlacement))); 177 fPlacementMenu->AddItem(new BMenuItem(B_TRANSLATE("Tile"), 178 new BMessage(kMsgTilePlacement))); 179 180 BMenuField* placementMenuField = new BMenuField("placement", 181 B_TRANSLATE("Placement:"), fPlacementMenu); 182 placementMenuField->SetAlignment(B_ALIGN_RIGHT); 183 184 fIconLabelOutline = new BCheckBox(B_TRANSLATE("Icon label outline"), 185 new BMessage(kMsgIconLabelOutline)); 186 fIconLabelOutline->SetValue(B_CONTROL_OFF); 187 188 fPicker = new BColorControl(BPoint(0, 0), B_CELLS_32x8, 8.0, "Picker", 189 new BMessage(kMsgUpdateColor)); 190 191 rightbox->AddChild(BLayoutBuilder::Group<>(B_VERTICAL) 192 .AddGroup(B_HORIZONTAL, 0.0f) 193 .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) 194 .Add(imageMenuField->CreateLabelLayoutItem(), 0, 0) 195 .AddGroup(B_HORIZONTAL, 0.0f, 1, 0) 196 .Add(imageMenuField->CreateMenuBarLayoutItem(), 0.0f) 197 .AddGlue() 198 .End() 199 .Add(placementMenuField->CreateLabelLayoutItem(), 0, 1) 200 .AddGroup(B_HORIZONTAL, 0.0f, 1, 1) 201 .Add(placementMenuField->CreateMenuBarLayoutItem(), 0.0f) 202 .AddGlue() 203 .End() 204 .Add(fIconLabelOutline, 1, 2) 205 .End() 206 .AddGlue() 207 .End() 208 .AddGlue() 209 .Add(fPicker) 210 .SetInsets(B_USE_DEFAULT_SPACING) 211 .View()); 212 213 fRevert = new BButton(B_TRANSLATE("Revert"), 214 new BMessage(kMsgRevertSettings)); 215 fApply = new BButton(B_TRANSLATE("Apply"), 216 new BMessage(kMsgApplySettings)); 217 218 fRevert->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, 219 B_ALIGN_NO_VERTICAL)); 220 fApply->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, 221 B_ALIGN_NO_VERTICAL)); 222 223 AddChild(BLayoutBuilder::Group<>(B_VERTICAL) 224 .AddGroup(B_HORIZONTAL) 225 .AddGroup(B_VERTICAL, 0) 226 .AddStrut(floorf(rightbox->TopBorderOffset() 227 - previewBox->TopBorderOffset()) - 1) 228 .Add(previewBox) 229 .End() 230 .Add(rightbox) 231 .End() 232 .AddGroup(B_HORIZONTAL) 233 .Add(fRevert) 234 .Add(fApply) 235 .End() 236 .SetInsets(B_USE_DEFAULT_SPACING) 237 .View()); 238 239 fApply->MakeDefault(true); 240 } 241 242 243 BackgroundsView::~BackgroundsView() 244 { 245 delete fPanel; 246 delete fFolderPanel; 247 } 248 249 250 void 251 BackgroundsView::AllAttached() 252 { 253 fPlacementMenu->SetTargetForItems(this); 254 fImageMenu->SetTargetForItems(this); 255 fWorkspaceMenu->SetTargetForItems(this); 256 fXPlacementText->SetTarget(this); 257 fYPlacementText->SetTarget(this); 258 fIconLabelOutline->SetTarget(this); 259 fPicker->SetTarget(this); 260 fApply->SetTarget(this); 261 fRevert->SetTarget(this); 262 263 BPath path; 264 entry_ref ref; 265 if (find_directory(B_SYSTEM_DATA_DIRECTORY, &path) == B_OK) { 266 path.Append("artwork"); 267 get_ref_for_path(path.Path(), &ref); 268 } 269 270 BMessenger messenger(this); 271 fPanel = new ImageFilePanel(B_OPEN_PANEL, &messenger, &ref, 272 B_FILE_NODE, false, NULL, new CustomRefFilter(true)); 273 fPanel->SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Select")); 274 275 fFolderPanel = new BFilePanel(B_OPEN_PANEL, &messenger, NULL, 276 B_DIRECTORY_NODE, false, NULL, new CustomRefFilter(false)); 277 fFolderPanel->SetButtonLabel(B_DEFAULT_BUTTON, B_TRANSLATE("Select")); 278 279 _LoadSettings(); 280 _LoadDesktopFolder(); 281 282 BPoint point; 283 if (fSettings.FindPoint("pos", &point) == B_OK) { 284 fFoundPositionSetting = true; 285 Window()->MoveTo(point); 286 } 287 288 fApply->SetEnabled(false); 289 fRevert->SetEnabled(false); 290 } 291 292 293 void 294 BackgroundsView::MessageReceived(BMessage* message) 295 { 296 switch (message->what) { 297 case B_SIMPLE_DATA: 298 case B_REFS_RECEIVED: 299 RefsReceived(message); 300 break; 301 302 case kMsgUpdatePreviewPlacement: 303 { 304 BString xstring, ystring; 305 xstring << (int)fPreview->fPoint.x; 306 ystring << (int)fPreview->fPoint.y; 307 fXPlacementText->SetText(xstring.String()); 308 fYPlacementText->SetText(ystring.String()); 309 _UpdatePreview(); 310 _UpdateButtons(); 311 break; 312 } 313 314 case kMsgManualPlacement: 315 case kMsgTilePlacement: 316 case kMsgScalePlacement: 317 case kMsgCenterPlacement: 318 _UpdatePreview(); 319 _UpdateButtons(); 320 break; 321 322 case kMsgIconLabelOutline: 323 _UpdateButtons(); 324 break; 325 326 case kMsgUpdateColor: 327 case kMsgImagePlacement: 328 _UpdatePreview(); 329 _UpdateButtons(); 330 break; 331 332 case kMsgCurrentWorkspace: 333 case kMsgAllWorkspaces: 334 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("None")); 335 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf( 336 fWorkspaceMenu->FindMarked()); 337 if (fCurrent && fCurrent->IsDesktop()) { 338 _UpdateButtons(); 339 } else { 340 _SetDesktop(true); 341 _LoadDesktopFolder(); 342 } 343 break; 344 345 case kMsgDefaultFolder: 346 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("None")); 347 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf( 348 fWorkspaceMenu->FindMarked()); 349 _SetDesktop(false); 350 _LoadDefaultFolder(); 351 break; 352 353 case kMsgOtherFolder: 354 fFolderPanel->Show(); 355 break; 356 357 case kMsgOtherImage: 358 fPanel->Show(); 359 break; 360 361 case B_CANCEL: 362 { 363 PRINT(("cancel received\n")); 364 void* pointer; 365 message->FindPointer("source", &pointer); 366 if (pointer == fPanel) { 367 if (fLastImageIndex >= 0) 368 _FindImageItem(fLastImageIndex)->SetMarked(true); 369 else 370 fImageMenu->ItemAt(0)->SetMarked(true); 371 } else if (pointer == fFolderPanel) { 372 if (fLastWorkspaceIndex >= 0) 373 fWorkspaceMenu->ItemAt(fLastWorkspaceIndex) 374 ->SetMarked(true); 375 } 376 break; 377 } 378 379 case kMsgImageSelected: 380 case kMsgNoImage: 381 fLastImageIndex = ((BGImageMenuItem*)fImageMenu->FindMarked()) 382 ->ImageIndex(); 383 _UpdatePreview(); 384 _UpdateButtons(); 385 break; 386 387 case kMsgFolderSelected: 388 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("Default")); 389 fLastWorkspaceIndex = fWorkspaceMenu->IndexOf( 390 fWorkspaceMenu->FindMarked()); 391 _SetDesktop(false); 392 393 _LoadRecentFolder(*fPathList.ItemAt(fWorkspaceMenu->IndexOf( 394 fWorkspaceMenu->FindMarked()) - 6)); 395 break; 396 397 case kMsgApplySettings: 398 { 399 _Save(); 400 401 //_NotifyServer(); 402 thread_id notify_thread; 403 notify_thread = spawn_thread(BackgroundsView::_NotifyThread, 404 "notifyServer", B_NORMAL_PRIORITY, this); 405 resume_thread(notify_thread); 406 _UpdateButtons(); 407 break; 408 } 409 case kMsgRevertSettings: 410 _UpdateWithCurrent(); 411 break; 412 413 default: 414 BView::MessageReceived(message); 415 break; 416 } 417 } 418 419 420 void 421 BackgroundsView::_LoadDesktopFolder() 422 { 423 BPath path; 424 if (find_directory(B_DESKTOP_DIRECTORY, &path) == B_OK) { 425 status_t err; 426 err = get_ref_for_path(path.Path(), &fCurrentRef); 427 if (err != B_OK) 428 printf("error in LoadDesktopSettings\n"); 429 _LoadFolder(true); 430 } 431 } 432 433 434 void 435 BackgroundsView::_LoadDefaultFolder() 436 { 437 BPath path; 438 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 439 BString pathString = path.Path(); 440 pathString << "/Tracker/DefaultFolderTemplate"; 441 status_t err; 442 err = get_ref_for_path(pathString.String(), &fCurrentRef); 443 if (err != B_OK) 444 printf("error in LoadDefaultFolderSettings\n"); 445 _LoadFolder(false); 446 } 447 } 448 449 450 void 451 BackgroundsView::_LoadRecentFolder(BPath path) 452 { 453 status_t err; 454 err = get_ref_for_path(path.Path(), &fCurrentRef); 455 if (err != B_OK) 456 printf("error in LoadRecentFolder\n"); 457 _LoadFolder(false); 458 } 459 460 461 void 462 BackgroundsView::_LoadFolder(bool isDesktop) 463 { 464 if (fCurrent) { 465 delete fCurrent; 466 fCurrent = NULL; 467 } 468 469 BNode node(&fCurrentRef); 470 if (node.InitCheck() == B_OK) 471 fCurrent = BackgroundImage::GetBackgroundImage(&node, isDesktop, this); 472 473 _UpdateWithCurrent(); 474 } 475 476 477 void 478 BackgroundsView::_UpdateWithCurrent(void) 479 { 480 if (fCurrent == NULL) 481 return; 482 483 fPlacementMenu->FindItem(kMsgScalePlacement) 484 ->SetEnabled(fCurrent->IsDesktop()); 485 fPlacementMenu->FindItem(kMsgCenterPlacement) 486 ->SetEnabled(fCurrent->IsDesktop()); 487 488 if (fWorkspaceMenu->IndexOf(fWorkspaceMenu->FindMarked()) > 5) 489 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("Default")); 490 else 491 fImageMenu->FindItem(kMsgNoImage)->SetLabel(B_TRANSLATE("None")); 492 493 for (int32 i = fImageMenu->CountItems() - 5; i >= 0; i--) { 494 fImageMenu->RemoveItem(2); 495 } 496 497 for (int32 i = fImageList.CountItems() - 1; i >= 0; i--) { 498 BMessage* message = new BMessage(kMsgImageSelected); 499 _AddItem(new BGImageMenuItem(GetImage(i)->GetName(), i, message)); 500 } 501 502 fImageMenu->SetTargetForItems(this); 503 504 fCurrentInfo = fCurrent->ImageInfoForWorkspace(current_workspace()); 505 506 if (!fCurrentInfo) { 507 fImageMenu->FindItem(kMsgNoImage)->SetMarked(true); 508 fPlacementMenu->FindItem(kMsgManualPlacement)->SetMarked(true); 509 fIconLabelOutline->SetValue(B_CONTROL_ON); 510 } else { 511 fIconLabelOutline->SetValue(fCurrentInfo->fTextWidgetLabelOutline 512 ? B_CONTROL_ON : B_CONTROL_OFF); 513 514 fLastImageIndex = fCurrentInfo->fImageIndex; 515 _FindImageItem(fLastImageIndex)->SetMarked(true); 516 517 if (fLastImageIndex > -1) { 518 519 BString xtext, ytext; 520 int32 cmd = 0; 521 switch (fCurrentInfo->fMode) { 522 case BackgroundImage::kCentered: 523 cmd = kMsgCenterPlacement; 524 break; 525 case BackgroundImage::kScaledToFit: 526 cmd = kMsgScalePlacement; 527 break; 528 case BackgroundImage::kAtOffset: 529 cmd = kMsgManualPlacement; 530 xtext << (int)fCurrentInfo->fOffset.x; 531 ytext << (int)fCurrentInfo->fOffset.y; 532 break; 533 case BackgroundImage::kTiled: 534 cmd = kMsgTilePlacement; 535 break; 536 } 537 538 if (cmd != 0) 539 fPlacementMenu->FindItem(cmd)->SetMarked(true); 540 541 fXPlacementText->SetText(xtext.String()); 542 fYPlacementText->SetText(ytext.String()); 543 } else { 544 fPlacementMenu->FindItem(kMsgManualPlacement)->SetMarked(true); 545 } 546 } 547 548 rgb_color color = {255, 255, 255, 255}; 549 if (fCurrent->IsDesktop()) { 550 color = BScreen().DesktopColor(); 551 fPicker->SetEnabled(true); 552 } else 553 fPicker->SetEnabled(false); 554 555 fPicker->SetValue(color); 556 557 _UpdatePreview(); 558 _UpdateButtons(); 559 } 560 561 562 void 563 BackgroundsView::_Save() 564 { 565 bool textWidgetLabelOutline 566 = fIconLabelOutline->Value() == B_CONTROL_ON; 567 568 BackgroundImage::Mode mode = _FindPlacementMode(); 569 BPoint offset(atoi(fXPlacementText->Text()), atoi(fYPlacementText->Text())); 570 571 if (!fCurrent->IsDesktop()) { 572 if (fCurrentInfo == NULL) { 573 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 574 B_ALL_WORKSPACES, fLastImageIndex, mode, offset, 575 textWidgetLabelOutline, 0, 0); 576 fCurrent->Add(fCurrentInfo); 577 } else { 578 fCurrentInfo->fTextWidgetLabelOutline = textWidgetLabelOutline; 579 fCurrentInfo->fMode = mode; 580 if (fCurrentInfo->fMode == BackgroundImage::kAtOffset) 581 fCurrentInfo->fOffset = offset; 582 fCurrentInfo->fImageIndex = fLastImageIndex; 583 } 584 } else { 585 uint32 workspaceMask = 1; 586 int32 workspace = current_workspace(); 587 for (; workspace; workspace--) 588 workspaceMask *= 2; 589 590 if (fCurrentInfo != NULL) { 591 if (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 592 if (fCurrentInfo->fWorkspace & workspaceMask 593 && fCurrentInfo->fWorkspace != workspaceMask) { 594 fCurrentInfo->fWorkspace = fCurrentInfo->fWorkspace 595 ^ workspaceMask; 596 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 597 workspaceMask, fLastImageIndex, mode, offset, 598 textWidgetLabelOutline, fCurrentInfo->fImageSet, 599 fCurrentInfo->fCacheMode); 600 fCurrent->Add(fCurrentInfo); 601 } else if (fCurrentInfo->fWorkspace == workspaceMask) { 602 fCurrentInfo->fTextWidgetLabelOutline 603 = textWidgetLabelOutline; 604 fCurrentInfo->fMode = mode; 605 if (fCurrentInfo->fMode == BackgroundImage::kAtOffset) 606 fCurrentInfo->fOffset = offset; 607 608 fCurrentInfo->fImageIndex = fLastImageIndex; 609 } 610 } else { 611 fCurrent->RemoveAll(); 612 613 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 614 B_ALL_WORKSPACES, fLastImageIndex, mode, offset, 615 textWidgetLabelOutline, fCurrent->GetShowingImageSet(), 616 fCurrentInfo->fCacheMode); 617 fCurrent->Add(fCurrentInfo); 618 } 619 } else { 620 if (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 621 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 622 workspaceMask, fLastImageIndex, mode, offset, 623 textWidgetLabelOutline, fCurrent->GetShowingImageSet(), 0); 624 } else { 625 fCurrent->RemoveAll(); 626 fCurrentInfo = new BackgroundImage::BackgroundImageInfo( 627 B_ALL_WORKSPACES, fLastImageIndex, mode, offset, 628 textWidgetLabelOutline, fCurrent->GetShowingImageSet(), 0); 629 } 630 fCurrent->Add(fCurrentInfo); 631 } 632 633 if (!fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()) { 634 for (int32 i = 0; i < count_workspaces(); i++) { 635 BScreen().SetDesktopColor(fPicker->ValueAsColor(), i, true); 636 } 637 } else 638 BScreen().SetDesktopColor(fPicker->ValueAsColor(), true); 639 } 640 641 BNode node(&fCurrentRef); 642 643 status_t status = fCurrent->SetBackgroundImage(&node); 644 if (status != B_OK) { 645 // TODO: this should be a BAlert! 646 printf("setting background image failed: %s\n", strerror(status)); 647 } 648 } 649 650 651 void 652 BackgroundsView::_NotifyServer() 653 { 654 BMessenger tracker("application/x-vnd.Be-TRAK"); 655 656 if (fCurrent->IsDesktop()) { 657 tracker.SendMessage(new BMessage(B_RESTORE_BACKGROUND_IMAGE)); 658 } else { 659 int32 i = -1; 660 BMessage reply; 661 int32 err; 662 BEntry currentEntry(&fCurrentRef); 663 BPath currentPath(¤tEntry); 664 bool isCustomFolder 665 = !fWorkspaceMenu->FindItem(kMsgDefaultFolder)->IsMarked(); 666 667 do { 668 BMessage msg(B_GET_PROPERTY); 669 i++; 670 671 // look at the "Poses" in every Tracker window 672 msg.AddSpecifier("Poses"); 673 msg.AddSpecifier("Window", i); 674 675 reply.MakeEmpty(); 676 tracker.SendMessage(&msg, &reply); 677 678 // break out of the loop when we're at the end of 679 // the windows 680 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD 681 && reply.FindInt32("error", &err) == B_OK 682 && err == B_BAD_INDEX) 683 break; 684 685 // don't stop for windows that don't understand 686 // a request for "Poses"; they're not displaying 687 // folders 688 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD 689 && reply.FindInt32("error", &err) == B_OK 690 && err != B_BAD_SCRIPT_SYNTAX) 691 continue; 692 693 BMessenger trackerWindow; 694 if (reply.FindMessenger("result", &trackerWindow) != B_OK) 695 continue; 696 697 if (isCustomFolder) { 698 // found a window with poses, ask for its path 699 msg.MakeEmpty(); 700 msg.what = B_GET_PROPERTY; 701 msg.AddSpecifier("Path"); 702 msg.AddSpecifier("Poses"); 703 msg.AddSpecifier("Window", i); 704 705 reply.MakeEmpty(); 706 tracker.SendMessage(&msg, &reply); 707 708 // go on with the next if this din't have a path 709 if (reply.what == B_MESSAGE_NOT_UNDERSTOOD) 710 continue; 711 712 entry_ref ref; 713 if (reply.FindRef("result", &ref) == B_OK) { 714 BEntry entry(&ref); 715 BPath path(&entry); 716 717 // these are not the paths you're looking for 718 if (currentPath != path) 719 continue; 720 } 721 } 722 723 trackerWindow.SendMessage(B_RESTORE_BACKGROUND_IMAGE); 724 } while (true); 725 } 726 } 727 728 729 int32 730 BackgroundsView::_NotifyThread(void* data) 731 { 732 BackgroundsView* view = (BackgroundsView*)data; 733 734 view->_NotifyServer(); 735 return B_OK; 736 } 737 738 739 void 740 BackgroundsView::SaveSettings(void) 741 { 742 BPath path; 743 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 744 path.Append(SETTINGS_FILE); 745 BFile file(path.Path(), B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); 746 747 BPoint point = Window()->Frame().LeftTop(); 748 if (fSettings.ReplacePoint("pos", point) != B_OK) 749 fSettings.AddPoint("pos", point); 750 751 entry_ref ref; 752 BEntry entry; 753 754 fPanel->GetPanelDirectory(&ref); 755 entry.SetTo(&ref); 756 entry.GetPath(&path); 757 if (fSettings.ReplaceString("paneldir", path.Path()) != B_OK) 758 fSettings.AddString("paneldir", path.Path()); 759 760 fFolderPanel->GetPanelDirectory(&ref); 761 entry.SetTo(&ref); 762 entry.GetPath(&path); 763 if (fSettings.ReplaceString("folderpaneldir", path.Path()) != B_OK) 764 fSettings.AddString("folderpaneldir", path.Path()); 765 766 fSettings.RemoveName("recentfolder"); 767 for (int32 i = 0; i < fPathList.CountItems(); i++) { 768 fSettings.AddString("recentfolder", fPathList.ItemAt(i)->Path()); 769 } 770 771 fSettings.Flatten(&file); 772 } 773 } 774 775 776 void 777 BackgroundsView::_LoadSettings() 778 { 779 fSettings.MakeEmpty(); 780 781 BPath path; 782 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 783 return; 784 785 path.Append(SETTINGS_FILE); 786 BFile file(path.Path(), B_READ_ONLY); 787 if (file.InitCheck() != B_OK) 788 return; 789 790 if (fSettings.Unflatten(&file) != B_OK) { 791 printf("Error unflattening settings file %s\n", path.Path()); 792 return; 793 } 794 795 PRINT_OBJECT(fSettings); 796 797 BString string; 798 if (fSettings.FindString("paneldir", &string) == B_OK) 799 fPanel->SetPanelDirectory(string.String()); 800 801 if (fSettings.FindString("folderpaneldir", &string) == B_OK) 802 fFolderPanel->SetPanelDirectory(string.String()); 803 804 int32 index = 0; 805 while (fSettings.FindString("recentfolder", index, &string) == B_OK) { 806 if (index == 0) 807 fWorkspaceMenu->AddSeparatorItem(); 808 809 path.SetTo(string.String()); 810 int32 i = _AddPath(path); 811 BString s; 812 s << B_TRANSLATE("Folder: ") << path.Leaf(); 813 BMenuItem* item = new BMenuItem(s.String(), 814 new BMessage(kMsgFolderSelected)); 815 fWorkspaceMenu->AddItem(item, -i - 1 + 6); 816 index++; 817 } 818 fWorkspaceMenu->SetTargetForItems(this); 819 820 PRINT(("Settings Loaded\n")); 821 } 822 823 824 void 825 BackgroundsView::WorkspaceActivated(uint32 oldWorkspaces, bool active) 826 { 827 _UpdateWithCurrent(); 828 } 829 830 831 void 832 BackgroundsView::_UpdatePreview() 833 { 834 bool imageEnabled = !(fImageMenu->FindItem(kMsgNoImage)->IsMarked()); 835 if (fPlacementMenu->IsEnabled() ^ imageEnabled) 836 fPlacementMenu->SetEnabled(imageEnabled); 837 838 bool textEnabled 839 = (fPlacementMenu->FindItem(kMsgManualPlacement)->IsMarked()) 840 && imageEnabled; 841 if (fXPlacementText->IsEnabled() ^ textEnabled) 842 fXPlacementText->SetEnabled(textEnabled); 843 if (fYPlacementText->IsEnabled() ^ textEnabled) 844 fYPlacementText->SetEnabled(textEnabled); 845 846 if (textEnabled && (strcmp(fXPlacementText->Text(), "") == 0)) { 847 fXPlacementText->SetText("0"); 848 fYPlacementText->SetText("0"); 849 } 850 if (!textEnabled) { 851 fXPlacementText->SetText(NULL); 852 fYPlacementText->SetText(NULL); 853 } 854 855 fXPlacementText->TextView()->MakeSelectable(textEnabled); 856 fYPlacementText->TextView()->MakeSelectable(textEnabled); 857 fXPlacementText->TextView()->MakeEditable(textEnabled); 858 fYPlacementText->TextView()->MakeEditable(textEnabled); 859 860 fPreview->ClearViewBitmap(); 861 862 int32 index = ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex(); 863 if (index >= 0) { 864 BBitmap* bitmap = GetImage(index)->GetBitmap(); 865 if (bitmap) { 866 BackgroundImage::BackgroundImageInfo* info 867 = new BackgroundImage::BackgroundImageInfo(0, index, 868 _FindPlacementMode(), BPoint(atoi(fXPlacementText->Text()), 869 atoi(fYPlacementText->Text())), 870 fIconLabelOutline->Value() == B_CONTROL_ON, 0, 0); 871 if (info->fMode == BackgroundImage::kAtOffset) { 872 fPreview->SetEnabled(true); 873 fPreview->fPoint.x = atoi(fXPlacementText->Text()); 874 fPreview->fPoint.y = atoi(fYPlacementText->Text()); 875 } else 876 fPreview->SetEnabled(false); 877 878 fPreview->fImageBounds = BRect(bitmap->Bounds()); 879 fCurrent->Show(info, fPreview); 880 881 delete info; 882 } 883 } else 884 fPreview->SetEnabled(false); 885 886 fPreview->SetViewColor(fPicker->ValueAsColor()); 887 fPreview->Invalidate(); 888 } 889 890 891 BackgroundImage::Mode 892 BackgroundsView::_FindPlacementMode() 893 { 894 BackgroundImage::Mode mode = BackgroundImage::kAtOffset; 895 896 if (fPlacementMenu->FindItem(kMsgCenterPlacement)->IsMarked()) 897 mode = BackgroundImage::kCentered; 898 if (fPlacementMenu->FindItem(kMsgScalePlacement)->IsMarked()) 899 mode = BackgroundImage::kScaledToFit; 900 if (fPlacementMenu->FindItem(kMsgManualPlacement)->IsMarked()) 901 mode = BackgroundImage::kAtOffset; 902 if (fPlacementMenu->FindItem(kMsgTilePlacement)->IsMarked()) 903 mode = BackgroundImage::kTiled; 904 905 return mode; 906 } 907 908 909 void 910 BackgroundsView::_UpdateButtons() 911 { 912 bool hasChanged = false; 913 if (fPicker->IsEnabled() 914 && fPicker->ValueAsColor() != BScreen().DesktopColor()) { 915 hasChanged = true; 916 } else if (fCurrentInfo) { 917 if ((fIconLabelOutline->Value() == B_CONTROL_ON) 918 ^ fCurrentInfo->fTextWidgetLabelOutline) { 919 hasChanged = true; 920 } else if (_FindPlacementMode() != fCurrentInfo->fMode) { 921 hasChanged = true; 922 } else if (fCurrentInfo->fImageIndex 923 != ((BGImageMenuItem*)fImageMenu->FindMarked())->ImageIndex()) { 924 hasChanged = true; 925 } else if (fCurrent->IsDesktop() 926 && ((fCurrentInfo->fWorkspace != B_ALL_WORKSPACES) 927 ^ (fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->IsMarked()))) 928 { 929 hasChanged = true; 930 } else if (fCurrentInfo->fImageIndex > -1 931 && fCurrentInfo->fMode == BackgroundImage::kAtOffset) { 932 BString oldString, newString; 933 oldString << (int)fCurrentInfo->fOffset.x; 934 if (oldString != BString(fXPlacementText->Text())) { 935 hasChanged = true; 936 } 937 oldString = ""; 938 oldString << (int)fCurrentInfo->fOffset.y; 939 if (oldString != BString(fYPlacementText->Text())) { 940 hasChanged = true; 941 } 942 } 943 } else if (fImageMenu->IndexOf(fImageMenu->FindMarked()) > 0) { 944 hasChanged = true; 945 } else if (fIconLabelOutline->Value() == B_CONTROL_OFF) { 946 hasChanged = true; 947 } 948 949 fApply->SetEnabled(hasChanged); 950 fRevert->SetEnabled(hasChanged); 951 } 952 953 954 void 955 BackgroundsView::RefsReceived(BMessage* message) 956 { 957 if (!message->HasRef("refs") && message->HasRef("dir_ref")) { 958 entry_ref dirRef; 959 if (message->FindRef("dir_ref", &dirRef) == B_OK) 960 message->AddRef("refs", &dirRef); 961 } 962 963 entry_ref ref; 964 int32 i = 0; 965 BMimeType imageType("image"); 966 BPath desktopPath; 967 find_directory(B_DESKTOP_DIRECTORY, &desktopPath); 968 969 while (message->FindRef("refs", i++, &ref) == B_OK) { 970 BPath path; 971 BEntry entry(&ref, true); 972 path.SetTo(&entry); 973 BNode node(&entry); 974 975 if (node.IsFile()) { 976 BMimeType refType; 977 BMimeType::GuessMimeType(&ref, &refType); 978 if (!imageType.Contains(&refType)) 979 continue; 980 981 BGImageMenuItem* item; 982 int32 index = AddImage(path); 983 if (index >= 0) { 984 item = _FindImageItem(index); 985 fLastImageIndex = index; 986 } else { 987 const char* name = GetImage(-index - 1)->GetName(); 988 item = new BGImageMenuItem(name, -index - 1, 989 new BMessage(kMsgImageSelected)); 990 _AddItem(item); 991 item->SetTarget(this); 992 fLastImageIndex = -index - 1; 993 } 994 995 // An optional placement may have been sent 996 int32 placement = 0; 997 if (message->FindInt32("placement", &placement) == B_OK) { 998 BMenuItem* item = fPlacementMenu->FindItem(placement); 999 if (item) 1000 item->SetMarked(true); 1001 } 1002 item->SetMarked(true); 1003 BMessenger(this).SendMessage(kMsgImageSelected); 1004 } else if (node.IsDirectory()) { 1005 if (desktopPath == path) { 1006 fWorkspaceMenu->FindItem(kMsgCurrentWorkspace)->SetMarked(true); 1007 BMessenger(this).SendMessage(kMsgCurrentWorkspace); 1008 break; 1009 } 1010 BMenuItem* item; 1011 int32 index = _AddPath(path); 1012 if (index >= 0) { 1013 item = fWorkspaceMenu->ItemAt(index + 6); 1014 fLastWorkspaceIndex = index + 6; 1015 } else { 1016 if (fWorkspaceMenu->CountItems() <= 5) 1017 fWorkspaceMenu->AddSeparatorItem(); 1018 BString s; 1019 s << B_TRANSLATE("Folder: ") << path.Leaf(); 1020 item = new BMenuItem(s.String(), 1021 new BMessage(kMsgFolderSelected)); 1022 fWorkspaceMenu->AddItem(item, -index - 1 + 6); 1023 item->SetTarget(this); 1024 fLastWorkspaceIndex = -index - 1 + 6; 1025 } 1026 1027 item->SetMarked(true); 1028 BMessenger(this).SendMessage(kMsgFolderSelected); 1029 } 1030 } 1031 } 1032 1033 1034 int32 1035 BackgroundsView::_AddPath(BPath path) 1036 { 1037 int32 count = fPathList.CountItems(); 1038 int32 index = 0; 1039 for (; index < count; index++) { 1040 BPath* p = fPathList.ItemAt(index); 1041 int c = BString(p->Path()).ICompare(path.Path()); 1042 if (c == 0) 1043 return index; 1044 1045 if (c > 0) 1046 break; 1047 } 1048 fPathList.AddItem(new BPath(path), index); 1049 return -index - 1; 1050 } 1051 1052 1053 int32 1054 BackgroundsView::AddImage(BPath path) 1055 { 1056 int32 count = fImageList.CountItems(); 1057 int32 index = 0; 1058 for (; index < count; index++) { 1059 Image* image = fImageList.ItemAt(index); 1060 if (image->GetPath() == path) 1061 return index; 1062 } 1063 1064 fImageList.AddItem(new Image(path)); 1065 return -index - 1; 1066 } 1067 1068 1069 Image* 1070 BackgroundsView::GetImage(int32 imageIndex) 1071 { 1072 return fImageList.ItemAt(imageIndex); 1073 } 1074 1075 1076 BGImageMenuItem* 1077 BackgroundsView::_FindImageItem(const int32 imageIndex) 1078 { 1079 if (imageIndex < 0) 1080 return (BGImageMenuItem*)fImageMenu->ItemAt(0); 1081 1082 int32 count = fImageMenu->CountItems() - 2; 1083 int32 index = 2; 1084 for (; index < count; index++) { 1085 BGImageMenuItem* image = (BGImageMenuItem*)fImageMenu->ItemAt(index); 1086 if (image->ImageIndex() == imageIndex) 1087 return image; 1088 } 1089 return NULL; 1090 } 1091 1092 1093 bool 1094 BackgroundsView::_AddItem(BGImageMenuItem* item) 1095 { 1096 int32 count = fImageMenu->CountItems() - 2; 1097 int32 index = 2; 1098 if (count < index) { 1099 fImageMenu->AddItem(new BSeparatorItem(), 1); 1100 count = fImageMenu->CountItems() - 2; 1101 } 1102 1103 for (; index < count; index++) { 1104 BGImageMenuItem* image = (BGImageMenuItem*)fImageMenu->ItemAt(index); 1105 int c = (BString(image->Label()).ICompare(BString(item->Label()))); 1106 if (c > 0) 1107 break; 1108 } 1109 return fImageMenu->AddItem(item, index); 1110 } 1111 1112 1113 void 1114 BackgroundsView::_SetDesktop(bool isDesktop) 1115 { 1116 fTopLeft->SetDesktop(isDesktop); 1117 fTop->SetDesktop(isDesktop); 1118 fTopRight->SetDesktop(isDesktop); 1119 fLeft->SetDesktop(isDesktop); 1120 fRight->SetDesktop(isDesktop); 1121 fBottomLeft->SetDesktop(isDesktop); 1122 fBottom->SetDesktop(isDesktop); 1123 fBottomRight->SetDesktop(isDesktop); 1124 1125 Invalidate(); 1126 } 1127 1128 1129 bool 1130 BackgroundsView::FoundPositionSetting() 1131 { 1132 return fFoundPositionSetting; 1133 } 1134 1135 1136 // #pragma mark - 1137 1138 1139 Preview::Preview() 1140 : 1141 BControl("PreView", NULL, NULL, B_WILL_DRAW | B_SUBPIXEL_PRECISE) 1142 { 1143 float aspectRatio = BScreen().Frame().Width() / BScreen().Frame().Height(); 1144 float previewWidth = 120.0f; 1145 float previewHeight = ceil(previewWidth / aspectRatio); 1146 1147 ResizeTo(previewWidth, previewHeight); 1148 SetExplicitMinSize(BSize(previewWidth, previewHeight)); 1149 SetExplicitMaxSize(BSize(previewWidth, previewHeight)); 1150 } 1151 1152 1153 void 1154 Preview::AttachedToWindow() 1155 { 1156 rgb_color color = ViewColor(); 1157 BControl::AttachedToWindow(); 1158 SetViewColor(color); 1159 } 1160 1161 1162 void 1163 Preview::MouseDown(BPoint point) 1164 { 1165 if (IsEnabled() && Bounds().Contains(point)) { 1166 uint32 buttons; 1167 GetMouse(&point, &buttons); 1168 if (buttons & B_PRIMARY_MOUSE_BUTTON) { 1169 fOldPoint = point; 1170 SetTracking(true); 1171 BScreen().GetMode(&fMode); 1172 fXRatio = Bounds().Width() / fMode.virtual_width; 1173 fYRatio = Bounds().Height() / fMode.virtual_height; 1174 SetMouseEventMask(B_POINTER_EVENTS, 1175 B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY); 1176 1177 BCursor grabbingCursor(B_CURSOR_ID_GRABBING); 1178 SetViewCursor(&grabbingCursor); 1179 } 1180 } 1181 } 1182 1183 1184 void 1185 Preview::MouseUp(BPoint point) 1186 { 1187 if (IsTracking()) { 1188 SetTracking(false); 1189 BCursor grabCursor(B_CURSOR_ID_GRAB); 1190 SetViewCursor(&grabCursor); 1191 } 1192 } 1193 1194 1195 void 1196 Preview::MouseMoved(BPoint point, uint32 transit, const BMessage* message) 1197 { 1198 if (!IsTracking()) { 1199 BCursor cursor(IsEnabled() 1200 ? B_CURSOR_ID_GRAB : B_CURSOR_ID_SYSTEM_DEFAULT); 1201 SetViewCursor(&cursor); 1202 } else { 1203 float x, y; 1204 x = fPoint.x + (point.x - fOldPoint.x) / fXRatio; 1205 y = fPoint.y + (point.y - fOldPoint.y) / fYRatio; 1206 bool min, max, mustSend = false; 1207 min = (x > -fImageBounds.Width()); 1208 max = (x < fMode.virtual_width); 1209 if (min && max) { 1210 fOldPoint.x = point.x; 1211 fPoint.x = x; 1212 mustSend = true; 1213 } else { 1214 if (!min && fPoint.x > -fImageBounds.Width()) { 1215 fPoint.x = -fImageBounds.Width(); 1216 fOldPoint.x = point.x - (x - fPoint.x) * fXRatio; 1217 mustSend = true; 1218 } 1219 if (!max && fPoint.x < fMode.virtual_width) { 1220 fPoint.x = fMode.virtual_width; 1221 fOldPoint.x = point.x - (x - fPoint.x) * fXRatio; 1222 mustSend = true; 1223 } 1224 } 1225 1226 min = (y > -fImageBounds.Height()); 1227 max = (y < fMode.virtual_height); 1228 if (min && max) { 1229 fOldPoint.y = point.y; 1230 fPoint.y = y; 1231 mustSend = true; 1232 } else { 1233 if (!min && fPoint.y > -fImageBounds.Height()) { 1234 fPoint.y = -fImageBounds.Height(); 1235 fOldPoint.y = point.y - (y - fPoint.y) * fYRatio; 1236 mustSend = true; 1237 } 1238 if (!max && fPoint.y < fMode.virtual_height) { 1239 fPoint.y = fMode.virtual_height; 1240 fOldPoint.y = point.y - (y - fPoint.y) * fYRatio; 1241 mustSend = true; 1242 } 1243 } 1244 1245 if (mustSend) { 1246 BMessenger messenger(Parent()); 1247 messenger.SendMessage(kMsgUpdatePreviewPlacement); 1248 } 1249 } 1250 1251 BControl::MouseMoved(point, transit, message); 1252 } 1253 1254 1255 // #pragma mark - 1256 1257 1258 BGImageMenuItem::BGImageMenuItem(const char* label, int32 imageIndex, 1259 BMessage* message, char shortcut, uint32 modifiers) 1260 : BMenuItem(label, message, shortcut, modifiers), 1261 fImageIndex(imageIndex) 1262 { 1263 } 1264 1265 1266 // #pragma mark - 1267 1268 1269 FramePart::FramePart(int32 part) 1270 : 1271 BView(NULL, B_WILL_DRAW | B_FRAME_EVENTS), 1272 fFramePart(part), 1273 fIsDesktop(true) 1274 { 1275 _SetSizeAndAlignment(); 1276 } 1277 1278 1279 void 1280 FramePart::Draw(BRect rect) 1281 { 1282 rgb_color color = HighColor(); 1283 SetDrawingMode(B_OP_COPY); 1284 SetHighColor(Parent()->ViewColor()); 1285 1286 if (fIsDesktop) { 1287 switch (fFramePart) { 1288 case FRAME_TOP_LEFT: 1289 FillRect(rect); 1290 SetHighColor(160, 160, 160); 1291 FillRoundRect(BRect(0, 0, 8, 8), 3, 3); 1292 SetHighColor(96, 96, 96); 1293 StrokeRoundRect(BRect(0, 0, 8, 8), 3, 3); 1294 break; 1295 1296 case FRAME_TOP: 1297 SetHighColor(160, 160, 160); 1298 FillRect(BRect(0, 1, rect.right, 3)); 1299 SetHighColor(96, 96, 96); 1300 StrokeLine(BPoint(0, 0), BPoint(rect.right, 0)); 1301 SetHighColor(0, 0, 0); 1302 StrokeLine(BPoint(0, 4), BPoint(rect.right, 4)); 1303 break; 1304 1305 case FRAME_TOP_RIGHT: 1306 FillRect(rect); 1307 SetHighColor(160, 160, 160); 1308 FillRoundRect(BRect(-4, 0, 4, 8), 3, 3); 1309 SetHighColor(96, 96, 96); 1310 StrokeRoundRect(BRect(-4, 0, 4, 8), 3, 3); 1311 break; 1312 1313 case FRAME_LEFT_SIDE: 1314 SetHighColor(160, 160, 160); 1315 FillRect(BRect(1, 0, 3, rect.bottom)); 1316 SetHighColor(96, 96, 96); 1317 StrokeLine(BPoint(0, 0), BPoint(0, rect.bottom)); 1318 SetHighColor(0, 0, 0); 1319 StrokeLine(BPoint(4, 0), BPoint(4, rect.bottom)); 1320 break; 1321 1322 case FRAME_RIGHT_SIDE: 1323 SetHighColor(160, 160, 160); 1324 FillRect(BRect(1, 0, 3, rect.bottom)); 1325 SetHighColor(0, 0, 0); 1326 StrokeLine(BPoint(0, 0), BPoint(0, rect.bottom)); 1327 SetHighColor(96, 96, 96); 1328 StrokeLine(BPoint(4, 0), BPoint(4, rect.bottom)); 1329 break; 1330 1331 case FRAME_BOTTOM_LEFT: 1332 FillRect(rect); 1333 SetHighColor(160, 160, 160); 1334 FillRoundRect(BRect(0, -4, 8, 4), 3, 3); 1335 SetHighColor(96, 96, 96); 1336 StrokeRoundRect(BRect(0, -4, 8, 4), 3, 3); 1337 break; 1338 1339 case FRAME_BOTTOM: 1340 SetHighColor(160, 160, 160); 1341 FillRect(BRect(0, 1, rect.right, 3)); 1342 SetHighColor(0, 0, 0); 1343 StrokeLine(BPoint(0, 0), BPoint(rect.right, 0)); 1344 SetHighColor(96, 96, 96); 1345 StrokeLine(BPoint(0, 4), BPoint(rect.right, 4)); 1346 SetHighColor(228, 0, 0); 1347 StrokeLine(BPoint(5, 2), BPoint(7, 2)); 1348 break; 1349 1350 case FRAME_BOTTOM_RIGHT: 1351 FillRect(rect); 1352 SetHighColor(160, 160, 160); 1353 FillRoundRect(BRect(-4, -4, 4, 4), 3, 3); 1354 SetHighColor(96, 96, 96); 1355 StrokeRoundRect(BRect(-4, -4, 4, 4), 3, 3); 1356 break; 1357 1358 default: 1359 break; 1360 } 1361 } else { 1362 switch (fFramePart) { 1363 case FRAME_TOP_LEFT: 1364 SetHighColor(152, 152, 152); 1365 StrokeLine(BPoint(0, 0), BPoint(0, 12)); 1366 StrokeLine(BPoint(0, 0), BPoint(4, 0)); 1367 StrokeLine(BPoint(3, 12), BPoint(3, 12)); 1368 SetHighColor(255, 203, 0); 1369 FillRect(BRect(1, 1, 3, 9)); 1370 SetHighColor(240, 240, 240); 1371 StrokeLine(BPoint(1, 12), BPoint(1, 10)); 1372 StrokeLine(BPoint(2, 10), BPoint(3, 10)); 1373 SetHighColor(200, 200, 200); 1374 StrokeLine(BPoint(2, 12), BPoint(2, 11)); 1375 StrokeLine(BPoint(3, 11), BPoint(3, 11)); 1376 break; 1377 1378 case FRAME_TOP: 1379 FillRect(BRect(54, 0, rect.right, 8)); 1380 SetHighColor(255, 203, 0); 1381 FillRect(BRect(0, 1, 52, 9)); 1382 SetHighColor(152, 152, 152); 1383 StrokeLine(BPoint(0, 0), BPoint(53, 0)); 1384 StrokeLine(BPoint(53, 1), BPoint(53, 9)); 1385 StrokeLine(BPoint(54, 9), BPoint(rect.right, 9)); 1386 SetHighColor(240, 240, 240); 1387 StrokeLine(BPoint(0, 10), BPoint(rect.right, 10)); 1388 SetHighColor(200, 200, 200); 1389 StrokeLine(BPoint(0, 11), BPoint(rect.right, 11)); 1390 SetHighColor(152, 152, 152); 1391 StrokeLine(BPoint(0, 12), BPoint(rect.right, 12)); 1392 break; 1393 1394 case FRAME_TOP_RIGHT: 1395 FillRect(BRect(0, 0, 3, 8)); 1396 SetHighColor(152, 152, 152); 1397 StrokeLine(BPoint(0, 12), BPoint(0, 12)); 1398 StrokeLine(BPoint(0, 9), BPoint(3, 9)); 1399 StrokeLine(BPoint(3, 12), BPoint(3, 9)); 1400 SetHighColor(240, 240, 240); 1401 StrokeLine(BPoint(0, 10), BPoint(2, 10)); 1402 StrokeLine(BPoint(1, 12), BPoint(1, 12)); 1403 SetHighColor(200, 200, 200); 1404 StrokeLine(BPoint(2, 12), BPoint(2, 12)); 1405 StrokeLine(BPoint(0, 11), BPoint(2, 11)); 1406 break; 1407 1408 case FRAME_LEFT_SIDE: 1409 case FRAME_RIGHT_SIDE: 1410 SetHighColor(152, 152, 152); 1411 StrokeLine(BPoint(0, 0), BPoint(0, rect.bottom)); 1412 SetHighColor(240, 240, 240); 1413 StrokeLine(BPoint(1, 0), BPoint(1, rect.bottom)); 1414 SetHighColor(200, 200, 200); 1415 StrokeLine(BPoint(2, 0), BPoint(2, rect.bottom)); 1416 SetHighColor(152, 152, 152); 1417 StrokeLine(BPoint(3, 0), BPoint(3, rect.bottom)); 1418 break; 1419 1420 case FRAME_BOTTOM_LEFT: 1421 SetHighColor(152, 152, 152); 1422 StrokeLine(BPoint(0, 0), BPoint(0, 3)); 1423 StrokeLine(BPoint(0, 3), BPoint(3, 3)); 1424 StrokeLine(BPoint(3, 0), BPoint(3, 0)); 1425 SetHighColor(240, 240, 240); 1426 StrokeLine(BPoint(1, 0), BPoint(1, 2)); 1427 StrokeLine(BPoint(3, 1), BPoint(3, 1)); 1428 SetHighColor(200, 200, 200); 1429 StrokeLine(BPoint(2, 0), BPoint(2, 2)); 1430 StrokeLine(BPoint(3, 2), BPoint(3, 2)); 1431 break; 1432 1433 case FRAME_BOTTOM: 1434 SetHighColor(152, 152, 152); 1435 StrokeLine(BPoint(0, 0), BPoint(rect.right, 0)); 1436 SetHighColor(240, 240, 240); 1437 StrokeLine(BPoint(0, 1), BPoint(rect.right, 1)); 1438 SetHighColor(200, 200, 200); 1439 StrokeLine(BPoint(0, 2), BPoint(rect.right, 2)); 1440 SetHighColor(152, 152, 152); 1441 StrokeLine(BPoint(0, 3), BPoint(rect.right, 3)); 1442 break; 1443 1444 case FRAME_BOTTOM_RIGHT: 1445 SetHighColor(152, 152, 152); 1446 StrokeLine(BPoint(0, 0), BPoint(0, 0)); 1447 SetHighColor(240, 240, 240); 1448 StrokeLine(BPoint(1, 0), BPoint(1, 1)); 1449 StrokeLine(BPoint(0, 1), BPoint(0, 1)); 1450 SetHighColor(200, 200, 200); 1451 StrokeLine(BPoint(2, 0), BPoint(2, 2)); 1452 StrokeLine(BPoint(0, 2), BPoint(1, 2)); 1453 SetHighColor(152, 152, 152); 1454 StrokeLine(BPoint(3, 0), BPoint(3, 3)); 1455 StrokeLine(BPoint(0, 3), BPoint(2, 3)); 1456 break; 1457 1458 default: 1459 break; 1460 } 1461 } 1462 1463 SetHighColor(color); 1464 } 1465 1466 1467 void 1468 FramePart::SetDesktop(bool isDesktop) 1469 { 1470 fIsDesktop = isDesktop; 1471 1472 _SetSizeAndAlignment(); 1473 Invalidate(); 1474 } 1475 1476 1477 void 1478 FramePart::_SetSizeAndAlignment() 1479 { 1480 if (fIsDesktop) { 1481 switch (fFramePart) { 1482 case FRAME_TOP_LEFT: 1483 SetExplicitMinSize(BSize(4, 4)); 1484 SetExplicitMaxSize(BSize(4, 4)); 1485 break; 1486 1487 case FRAME_TOP: 1488 SetExplicitMinSize(BSize(1, 4)); 1489 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 4)); 1490 break; 1491 1492 case FRAME_TOP_RIGHT: 1493 SetExplicitMinSize(BSize(4, 4)); 1494 SetExplicitMaxSize(BSize(4, 4)); 1495 break; 1496 1497 case FRAME_LEFT_SIDE: 1498 SetExplicitMinSize(BSize(4, 1)); 1499 SetExplicitMaxSize(BSize(4, B_SIZE_UNLIMITED)); 1500 break; 1501 1502 case FRAME_RIGHT_SIDE: 1503 SetExplicitMinSize(BSize(4, 1)); 1504 SetExplicitMaxSize(BSize(4, B_SIZE_UNLIMITED)); 1505 break; 1506 1507 case FRAME_BOTTOM_LEFT: 1508 SetExplicitMinSize(BSize(4, 4)); 1509 SetExplicitMaxSize(BSize(4, 4)); 1510 break; 1511 1512 case FRAME_BOTTOM: 1513 SetExplicitMinSize(BSize(1, 4)); 1514 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 4)); 1515 break; 1516 1517 case FRAME_BOTTOM_RIGHT: 1518 SetExplicitMaxSize(BSize(4, 4)); 1519 SetExplicitMinSize(BSize(4, 4)); 1520 break; 1521 1522 default: 1523 break; 1524 } 1525 } else { 1526 switch (fFramePart) { 1527 case FRAME_TOP_LEFT: 1528 SetExplicitMinSize(BSize(3, 12)); 1529 SetExplicitMaxSize(BSize(3, 12)); 1530 break; 1531 1532 case FRAME_TOP: 1533 SetExplicitMinSize(BSize(1, 12)); 1534 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 12)); 1535 break; 1536 1537 case FRAME_TOP_RIGHT: 1538 SetExplicitMinSize(BSize(3, 12)); 1539 SetExplicitMaxSize(BSize(3, 12)); 1540 break; 1541 1542 case FRAME_LEFT_SIDE: 1543 SetExplicitMinSize(BSize(3, 1)); 1544 SetExplicitMaxSize(BSize(3, B_SIZE_UNLIMITED)); 1545 break; 1546 1547 case FRAME_RIGHT_SIDE: 1548 SetExplicitMinSize(BSize(3, 1)); 1549 SetExplicitMaxSize(BSize(3, B_SIZE_UNLIMITED)); 1550 break; 1551 1552 case FRAME_BOTTOM_LEFT: 1553 SetExplicitMinSize(BSize(3, 3)); 1554 SetExplicitMaxSize(BSize(3, 3)); 1555 break; 1556 1557 case FRAME_BOTTOM: 1558 SetExplicitMinSize(BSize(1, 3)); 1559 SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 3)); 1560 break; 1561 1562 case FRAME_BOTTOM_RIGHT: 1563 SetExplicitMaxSize(BSize(3, 3)); 1564 SetExplicitMinSize(BSize(3, 3)); 1565 break; 1566 1567 default: 1568 break; 1569 } 1570 } 1571 1572 switch (fFramePart) { 1573 case FRAME_TOP_LEFT: 1574 SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_BOTTOM)); 1575 break; 1576 1577 case FRAME_TOP: 1578 SetExplicitAlignment(BAlignment(B_ALIGN_CENTER, B_ALIGN_BOTTOM)); 1579 break; 1580 1581 case FRAME_TOP_RIGHT: 1582 SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_BOTTOM)); 1583 break; 1584 1585 case FRAME_LEFT_SIDE: 1586 SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE)); 1587 break; 1588 1589 case FRAME_RIGHT_SIDE: 1590 SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); 1591 break; 1592 1593 case FRAME_BOTTOM_LEFT: 1594 SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_TOP)); 1595 break; 1596 1597 case FRAME_BOTTOM: 1598 SetExplicitAlignment(BAlignment(B_ALIGN_CENTER, B_ALIGN_TOP)); 1599 break; 1600 1601 case FRAME_BOTTOM_RIGHT: 1602 SetExplicitAlignment(BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP)); 1603 break; 1604 1605 default: 1606 break; 1607 } 1608 } 1609 1610