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