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