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