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