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