1 /* 2 Open Tracker License 3 4 Terms and Conditions 5 6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy of 9 this software and associated documentation files (the "Software"), to deal in 10 the Software without restriction, including without limitation the rights to 11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 of the Software, and to permit persons to whom the Software is furnished to do 13 so, subject to the following conditions: 14 15 The above copyright notice and this permission notice applies to all licensees 16 and shall be included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 Except as contained in this notice, the name of Be Incorporated shall not be 26 used in advertising or otherwise to promote the sale, use or other dealings in 27 this Software without prior written authorization from Be Incorporated. 28 29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered 30 trademarks of Be Incorporated in the United States and other countries. Other 31 brand product names are registered trademarks or trademarks of their respective 32 holders. 33 All rights reserved. 34 */ 35 36 #include <Debug.h> 37 38 #include "BarView.h" 39 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 44 #include <AppFileInfo.h> 45 #include <Bitmap.h> 46 #include <Directory.h> 47 #include <NodeInfo.h> 48 #include <Roster.h> 49 #include <Screen.h> 50 #include <String.h> 51 52 #include "icons.h" 53 #include "BarApp.h" 54 #include "BarMenuBar.h" 55 #include "BarWindow.h" 56 #include "BeMenu.h" 57 #include "DeskBarUtils.h" 58 #include "ExpandoMenuBar.h" 59 #include "FSUtils.h" 60 #include "ResourceSet.h" 61 #include "StatusView.h" 62 #include "TeamMenuItem.h" 63 64 65 const int32 kDefaultRecentDocCount = 10; 66 const int32 kDefaultRecentFolderCount = 10; 67 const int32 kDefaultRecentAppCount = 10; 68 69 const int32 kMenuTrackMargin = 20; 70 71 TBarView::TBarView(BRect frame, bool vertical, bool left, bool top, 72 bool showInterval, uint32 state, float, bool showTime) 73 : BView(frame, "BarView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW), 74 fBarMenuBar(NULL), 75 fExpando(NULL), 76 fTrayLocation(1), 77 fShowInterval(showInterval), 78 fShowClock(showTime), 79 fVertical(vertical), 80 fTop(top), 81 fLeft(left), 82 fState(static_cast<int32>(state)), 83 fRefsRcvdOnly(true), 84 fDragMessage(NULL), 85 fCachedTypesList(NULL), 86 fMaxRecentDocs(kDefaultRecentDocCount), 87 fMaxRecentApps(kDefaultRecentAppCount), 88 fLastDragItem(NULL) 89 { 90 fReplicantTray = new TReplicantTray(this, fVertical); 91 fDragRegion = new TDragRegion(this, fReplicantTray); 92 fDragRegion->AddChild(fReplicantTray); 93 if (fTrayLocation != 0) 94 AddChild(fDragRegion); 95 } 96 97 98 TBarView::~TBarView() 99 { 100 delete fDragMessage; 101 delete fCachedTypesList; 102 } 103 104 105 void 106 TBarView::AttachedToWindow() 107 { 108 BView::AttachedToWindow(); 109 110 SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); 111 SetFont(be_plain_font); 112 113 UpdateAutoRaise(); 114 UpdatePlacement(); 115 116 fTrackingHookData.fTrackingHook = MenuTrackingHook; 117 fTrackingHookData.fTarget = BMessenger(this); 118 fTrackingHookData.fDragMessage = new BMessage(B_REFS_RECEIVED); 119 } 120 121 122 void 123 TBarView::DetachedFromWindow() 124 { 125 delete fTrackingHookData.fDragMessage; 126 fTrackingHookData.fDragMessage = NULL; 127 } 128 129 130 void 131 TBarView::Draw(BRect) 132 { 133 BRect bounds(Bounds()); 134 135 rgb_color hilite = tint_color(ViewColor(), B_DARKEN_1_TINT); 136 rgb_color light = tint_color(ViewColor(), B_LIGHTEN_2_TINT); 137 138 SetHighColor(hilite); 139 if (AcrossTop()) 140 StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); 141 else if (AcrossBottom()) 142 StrokeLine(bounds.LeftTop(), bounds.RightTop()); 143 144 if (Vertical() && Expando()) { 145 SetHighColor(hilite); 146 BRect frame(fExpando->Frame()); 147 StrokeLine(BPoint(frame.left, frame.top - 1), 148 BPoint(frame.right, frame.top -1)); 149 } 150 } 151 152 153 void 154 TBarView::MessageReceived(BMessage* message) 155 { 156 switch (message->what) { 157 case B_REFS_RECEIVED: 158 // received when an item is selected during DnD 159 // message is targeted here from Be menu 160 HandleBeMenu(message); 161 break; 162 163 case B_ARCHIVED_OBJECT: 164 { 165 // this message has been retargeted to here 166 // instead of directly to the replicant tray 167 // so that I can follow the common pathway 168 // for adding icons to the tray 169 int32 id; 170 AddItem(new BMessage(*message), B_DESKBAR_TRAY, &id); 171 break; 172 } 173 174 default: 175 BView::MessageReceived(message); 176 } 177 } 178 179 180 void 181 TBarView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage) 182 { 183 if (Window() == NULL || EventMask() == 0) 184 return; 185 186 // Auto-Raise 187 188 where = ConvertToScreen(where); 189 BScreen screen(Window()); 190 BRect frame = screen.Frame(); 191 if (where.x == frame.left || where.x == frame.right 192 || where.y == frame.top || where.y == frame.bottom) { 193 // cursor is on screen edge 194 if (Window()->Frame().Contains(where)) 195 Window()->Activate(); 196 } 197 } 198 199 200 void 201 TBarView::PlaceBeMenu() 202 { 203 // top or bottom, full 204 if (!fVertical && fBarMenuBar) { 205 fBarMenuBar->RemoveSelf(); 206 delete fBarMenuBar; 207 fBarMenuBar = NULL; 208 } 209 210 // top or bottom expando mode has Be menu built in for tracking 211 // only for vertical mini or expanded 212 // mini mode will have team menu added as part of BarMenuBar 213 if (fVertical && !fBarMenuBar) { 214 // create the Be menu 215 BRect mbarFrame(Bounds()); 216 mbarFrame.bottom = mbarFrame.top + kMenuBarHeight; 217 fBarMenuBar = new TBarMenuBar(this, mbarFrame, "BarMenuBar"); 218 AddChild(fBarMenuBar); 219 } 220 221 // if there isn't a bemenu at this point, 222 // DB should be in top/bottom mode, else error 223 if (!fBarMenuBar) 224 return; 225 226 float width = sMinimumWindowWidth; 227 BPoint loc(B_ORIGIN); 228 BRect menuFrame(fBarMenuBar->Frame()); 229 if (fState == kFullState) { 230 fBarMenuBar->RemoveTeamMenu(); 231 width = 8 + 16 + 8; 232 loc = Bounds().LeftTop(); 233 } else if (fState == kExpandoState) { 234 // shows apps below tray 235 fBarMenuBar->RemoveTeamMenu(); 236 if (fVertical) 237 width += 1; 238 else 239 width = floorf(width) / 2; 240 loc = Bounds().LeftTop(); 241 } else { 242 // mini mode, BeMenu next to team menu 243 fBarMenuBar->AddTeamMenu(); 244 } 245 246 fBarMenuBar->SmartResize(width, menuFrame.Height()); 247 fBarMenuBar->MoveTo(loc); 248 } 249 250 251 void 252 TBarView::PlaceTray(bool, bool, BRect screenFrame) 253 { 254 BPoint statusLoc; 255 if (fState == kFullState) { 256 fDragRegion->ResizeTo(fBarMenuBar->Frame().Width(), kMenuBarHeight); 257 statusLoc.y = fBarMenuBar->Frame().bottom + 1; 258 statusLoc.x = 0; 259 fDragRegion->MoveTo(statusLoc); 260 261 if (!fReplicantTray->IsHidden()) 262 fReplicantTray->Hide(); 263 264 return; 265 } 266 267 if (fReplicantTray->IsHidden()) 268 fReplicantTray->Show(); 269 270 if (fTrayLocation != 0) { 271 fReplicantTray->SetMultiRow(fVertical); 272 fReplicantTray->RealignReplicants(); 273 fDragRegion->ResizeToPreferred(); 274 275 if (fVertical) { 276 statusLoc.y = fBarMenuBar->Frame().bottom + 1; 277 statusLoc.x = 0; 278 if (Left() && Vertical()) 279 fReplicantTray->MoveTo(5, 2); 280 else 281 fReplicantTray->MoveTo(2, 2); 282 } else { 283 statusLoc.x = screenFrame.right - fDragRegion->Bounds().Width(); 284 statusLoc.y = -1; 285 } 286 287 fDragRegion->MoveTo(statusLoc); 288 } 289 } 290 291 292 void 293 TBarView::PlaceApplicationBar(BRect screenFrame) 294 { 295 if (fExpando != NULL) { 296 fExpando->RemoveSelf(); 297 delete fExpando; 298 fExpando = NULL; 299 } 300 if (fState == kMiniState) 301 return; 302 303 BRect expandoFrame(0, 0, 0, 0); 304 if (fVertical) { 305 // top left/right 306 if (fTrayLocation != 0) 307 expandoFrame.top = fDragRegion->Frame().bottom + 1; 308 else 309 expandoFrame.top = fBarMenuBar->Frame().bottom + 1; 310 311 expandoFrame.bottom = expandoFrame.top + 1; 312 if (fState == kFullState) 313 expandoFrame.right = fBarMenuBar->Frame().Width(); 314 else 315 expandoFrame.right = sMinimumWindowWidth; 316 } else { 317 // top or bottom 318 expandoFrame.top = 0; 319 expandoFrame.bottom = kHModeHeight; 320 if (fTrayLocation != 0) 321 expandoFrame.right = fDragRegion->Frame().left - 1; 322 else 323 expandoFrame.right = screenFrame.Width(); 324 } 325 326 fExpando = new TExpandoMenuBar(this, expandoFrame, "ExpandoMenuBar", 327 fVertical, fState != kFullState); 328 AddChild(fExpando); 329 } 330 331 332 void 333 TBarView::GetPreferredWindowSize(BRect screenFrame, float* width, float* height) 334 { 335 float windowHeight = 0; 336 float windowWidth = sMinimumWindowWidth; 337 if (fState == kFullState) { 338 windowHeight = screenFrame.bottom; 339 windowWidth = fBarMenuBar->Frame().Width(); 340 } else if (fState == kExpandoState) { 341 if (fVertical) { 342 // top left or right 343 windowHeight = fExpando->Frame().bottom; 344 } else { 345 // top or bottom, full 346 fExpando->CheckItemSizes(0); 347 windowHeight = kHModeHeight; 348 windowWidth = screenFrame.Width(); 349 } 350 } else { 351 // four corners 352 if (fTrayLocation != 0) 353 windowHeight = fDragRegion->Frame().bottom; 354 else 355 windowHeight = fBarMenuBar->Frame().bottom; 356 } 357 358 *width = windowWidth; 359 *height = windowHeight; 360 } 361 362 363 void 364 TBarView::SizeWindow(BRect screenFrame) 365 { 366 float windowWidth, windowHeight; 367 GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight); 368 Window()->ResizeTo(windowWidth, windowHeight); 369 if (fExpando) 370 fExpando->CheckForSizeOverrun(); 371 } 372 373 374 void 375 TBarView::PositionWindow(BRect screenFrame) 376 { 377 float windowWidth, windowHeight; 378 GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight); 379 380 BPoint moveLoc(0, 0); 381 // right, expanded 382 if (!fLeft && fVertical) { 383 if (fState == kFullState) 384 moveLoc.x = screenFrame.right - fBarMenuBar->Frame().Width(); 385 else 386 moveLoc.x = screenFrame.right - windowWidth; 387 } 388 389 // bottom, full or corners 390 if (!fTop) 391 moveLoc.y = screenFrame.bottom - windowHeight; 392 393 Window()->MoveTo(moveLoc); 394 } 395 396 397 void 398 TBarView::SaveSettings() 399 { 400 desk_settings* settings = ((TBarApp*)be_app)->Settings(); 401 402 settings->vertical = Vertical(); 403 settings->left = Left(); 404 settings->top = Top(); 405 settings->ampmMode = MilTime(); 406 settings->state = (uint32)State(); 407 settings->width = 0; 408 settings->showTime = ShowingClock(); 409 410 fReplicantTray->RememberClockSettings(); 411 settings->alwaysOnTop 412 = (Window()->Feel() & B_FLOATING_ALL_WINDOW_FEEL) != 0; 413 } 414 415 416 void 417 TBarView::UpdateAutoRaise() 418 { 419 if (((TBarApp*)be_app)->Settings()->autoRaise) 420 SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); 421 else 422 SetEventMask(0); 423 } 424 425 426 void 427 TBarView::UpdatePlacement() 428 { 429 ChangeState(fState, fVertical, fLeft, fTop); 430 } 431 432 433 void 434 TBarView::ChangeState(int32 state, bool vertical, bool left, bool top) 435 { 436 bool vertSwap = (fVertical != vertical); 437 bool leftSwap = (fLeft != left); 438 bool stateChanged = (fState != state); 439 440 fState = state; 441 fVertical = vertical; 442 fLeft = left; 443 fTop = top; 444 445 // Send a message to the preferences window to let it know to enable 446 // or disabled preference items 447 if (stateChanged || vertSwap) 448 be_app->PostMessage(kStateChanged); 449 450 BRect screenFrame = (BScreen(Window())).Frame(); 451 452 PlaceBeMenu(); 453 PlaceTray(vertSwap, leftSwap, screenFrame); 454 455 // We need to keep track of what apps are expanded. 456 BList expandedItems; 457 BString* signature = NULL; 458 if (fVertical && Expando() 459 && static_cast<TBarApp*>(be_app)->Settings()->superExpando) { 460 // Get a list of the signatures of expanded apps. Can't use 461 // team_id because there can be more than one team per application 462 if (fVertical && Expando() && vertical && fExpando) { 463 for (int index = 0; index < fExpando->CountItems(); index++) { 464 TTeamMenuItem* item 465 = dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(index)); 466 if (item != NULL && item->IsExpanded()) { 467 signature = new BString(item->Signature()); 468 expandedItems.AddItem((void*)signature); 469 } 470 } 471 } 472 } 473 474 PlaceApplicationBar(screenFrame); 475 SizeWindow(screenFrame); 476 PositionWindow(screenFrame); 477 Window()->UpdateIfNeeded(); 478 479 // Re-expand those apps. 480 if (expandedItems.CountItems() > 0) { 481 for (int sigIndex = expandedItems.CountItems(); sigIndex-- > 0;) { 482 signature = static_cast<BString*>(expandedItems.ItemAt(sigIndex)); 483 if (signature == NULL) 484 continue; 485 486 // Start at the 'bottom' of the list working up. 487 // Prevents being thrown off by expanding items. 488 for (int teamIndex = fExpando->CountItems(); teamIndex-- > 0;) { 489 TTeamMenuItem* item 490 = dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(teamIndex)); 491 if (item != NULL && !signature->Compare(item->Signature())) { 492 item->ToggleExpandState(false); 493 break; 494 } 495 } 496 } 497 498 // Clean up expanded signature list. 499 while (!expandedItems.IsEmpty()) { 500 delete static_cast<BString*>(expandedItems.RemoveItem((int32)0)); 501 } 502 503 fExpando->SizeWindow(); 504 } 505 506 Invalidate(); 507 } 508 509 510 // window placement functions 511 512 bool 513 TBarView::Vertical() const 514 { 515 return fVertical; 516 } 517 518 519 bool 520 TBarView::Left() const 521 { 522 return fLeft; 523 } 524 525 526 bool 527 TBarView::AcrossTop() const 528 { 529 return fTop && !fVertical; 530 } 531 532 533 bool 534 TBarView::AcrossBottom() const 535 { 536 return !fTop && !fVertical; 537 } 538 539 540 bool 541 TBarView::Expando() const 542 { 543 return fState == kExpandoState; 544 } 545 546 547 bool 548 TBarView::Top() const 549 { 550 return fTop; 551 } 552 553 554 int32 555 TBarView::State() const 556 { 557 return fState; 558 } 559 560 561 // optional functionality functions 562 563 bool 564 TBarView::MilTime() const 565 { 566 return fShowInterval; 567 } 568 569 570 void 571 TBarView::ShowClock(bool on) 572 { 573 fShowClock = on; 574 } 575 576 577 bool 578 TBarView::ShowingClock() const 579 { 580 return fShowClock; 581 } 582 583 584 // #pragma mark - Drag and Drop 585 586 587 void 588 TBarView::CacheDragData(const BMessage* incoming) 589 { 590 if (!incoming) 591 return; 592 593 if (Dragging() && SpringLoadedFolderCompareMessages(incoming, fDragMessage)) 594 return; 595 596 // disposes then fills cached drag message and 597 // mimetypes list 598 SpringLoadedFolderCacheDragData(incoming, &fDragMessage, &fCachedTypesList); 599 } 600 601 602 static void 603 init_tracking_hook(BMenuItem* item, 604 bool (*hookFunction)(BMenu*, void*), void* state) 605 { 606 if (!item) 607 return; 608 609 BMenu* windowMenu = item->Submenu(); 610 if (windowMenu) { 611 // have a menu, set the tracking hook 612 windowMenu->SetTrackingHook(hookFunction, state); 613 } 614 } 615 616 617 status_t 618 TBarView::DragStart() 619 { 620 if (!Dragging()) 621 return B_OK; 622 623 BPoint loc; 624 uint32 buttons; 625 GetMouse(&loc, &buttons); 626 627 if (fExpando && fExpando->Frame().Contains(loc)) { 628 ConvertToScreen(&loc); 629 BPoint expandoLocation = fExpando->ConvertFromScreen(loc); 630 TTeamMenuItem* item = fExpando->TeamItemAtPoint(expandoLocation); 631 632 if (fLastDragItem) 633 init_tracking_hook(fLastDragItem, NULL, NULL); 634 635 if (item) { 636 if (item == fLastDragItem) 637 return B_OK; 638 639 fLastDragItem = item; 640 } 641 } 642 643 return B_OK; 644 } 645 646 647 bool 648 TBarView::MenuTrackingHook(BMenu* menu, void* castToThis) 649 { 650 // return true if the menu should go away 651 TrackingHookData* data = static_cast<TrackingHookData*>(castToThis); 652 if (!data) 653 return false; 654 655 TBarView* barview = dynamic_cast<TBarView*>(data->fTarget.Target(NULL)); 656 if (!barview || !menu->LockLooper()) 657 return false; 658 659 uint32 buttons; 660 BPoint location; 661 menu->GetMouse(&location, &buttons); 662 663 bool endMenu = true; 664 BRect frame(menu->Bounds()); 665 frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin); 666 667 if (frame.Contains(location)) { 668 // if current loc is still in the menu 669 // keep tracking 670 endMenu = false; 671 } else { 672 // see if the mouse is in the team/be menu item 673 menu->ConvertToScreen(&location); 674 if (barview->LockLooper()) { 675 TExpandoMenuBar* expando = barview->ExpandoMenuBar(); 676 TBeMenu* bemenu 677 = (dynamic_cast<TBarWindow*>(barview->Window()))->BeMenu(); 678 679 if (bemenu && bemenu->LockLooper()) { 680 bemenu->ConvertFromScreen(&location); 681 if (bemenu->Frame().Contains(location)) 682 endMenu = false; 683 684 bemenu->UnlockLooper(); 685 } 686 687 if (endMenu && expando) { 688 expando->ConvertFromScreen(&location); 689 BMenuItem* item = expando->TeamItemAtPoint(location); 690 if (item) 691 endMenu = false; 692 } 693 barview->UnlockLooper(); 694 } 695 } 696 697 menu->UnlockLooper(); 698 return endMenu; 699 } 700 701 702 // used by WindowMenu and TeamMenu to 703 // set the tracking hook for dragging 704 TrackingHookData* 705 TBarView::GetTrackingHookData() 706 { 707 // all tracking hook data is 708 // preset in AttachedToWindow 709 // data should never change 710 return &fTrackingHookData; 711 } 712 713 714 void 715 TBarView::DragStop(bool full) 716 { 717 if (!Dragging()) 718 return; 719 720 if (fExpando) { 721 if (fLastDragItem) { 722 init_tracking_hook(fLastDragItem, NULL, NULL); 723 fLastDragItem = NULL; 724 } 725 } 726 727 if (full) { 728 delete fDragMessage; 729 fDragMessage = NULL; 730 731 delete fCachedTypesList; 732 fCachedTypesList = NULL; 733 } 734 } 735 736 737 bool 738 TBarView::AppCanHandleTypes(const char* signature) 739 { 740 // used for filtering apps/teams in the ExpandoMenuBar and TeamMenu 741 742 if (modifiers() & B_CONTROL_KEY) { 743 // control key forces acceptance, just like drag&drop on icons 744 return true; 745 } 746 747 if (!signature || strlen(signature) == 0 748 || !fCachedTypesList || fCachedTypesList->CountItems() == 0) 749 return false; 750 751 if (strcmp(signature, kTrackerSignature) == 0) { 752 // tracker should support all types 753 // and should pass them on to the appropriate application 754 return true; 755 } 756 757 entry_ref hintref; 758 BMimeType appmime(signature); 759 if (appmime.GetAppHint(&hintref) != B_OK) 760 return false; 761 762 // an app was found, now see if it supports any of 763 // the refs in the message 764 BFile file(&hintref, O_RDONLY); 765 BAppFileInfo fileinfo(&file); 766 767 // scan the cached mimetype list and see if this app 768 // supports anything in the list 769 // only one item needs to match in the list of refs 770 771 int32 count = fCachedTypesList->CountItems(); 772 for (int32 i = 0 ; i < count ; i++) { 773 if (fileinfo.IsSupportedType(fCachedTypesList->ItemAt(i)->String())) 774 return true; 775 } 776 777 return false; 778 } 779 780 781 void 782 TBarView::SetDragOverride(bool on) 783 { 784 fRefsRcvdOnly = on; 785 } 786 787 788 bool 789 TBarView::DragOverride() 790 { 791 return fRefsRcvdOnly; 792 } 793 794 795 status_t 796 TBarView::SendDragMessage(const char* signature, entry_ref* ref) 797 { 798 status_t err = B_ERROR; 799 if (fDragMessage) { 800 if (fRefsRcvdOnly) { 801 // current message sent to apps is only B_REFS_RECEIVED 802 fDragMessage->what = B_REFS_RECEIVED; 803 } 804 805 BRoster roster; 806 if (signature && strlen(signature) > 0 && roster.IsRunning(signature)) { 807 BMessenger mess(signature); 808 // drag message is still owned by DB, copy is sent 809 // can toss it after send 810 err = mess.SendMessage(fDragMessage); 811 } else if (ref) { 812 FSLaunchItem((const entry_ref*)ref, (const BMessage*)fDragMessage, 813 true, true); 814 } else if (signature && strlen(signature) > 0) { 815 roster.Launch(signature, fDragMessage); 816 } 817 } 818 return err; 819 } 820 821 822 bool 823 TBarView::InvokeItem(const char* signature) 824 { 825 // sent from TeamMenuItem 826 if (Dragging() && AppCanHandleTypes(signature)) { 827 SendDragMessage(signature); 828 // invoking okay to toss memory 829 DragStop(true); 830 return true; 831 } 832 833 return false; 834 } 835 836 837 void 838 TBarView::HandleBeMenu(BMessage* messagewithdestination) 839 { 840 if (!Dragging()) 841 return; 842 843 // in mini-mode 844 if (Vertical() && !Expando()) { 845 // if drop is in the team menu, bail 846 if (fBarMenuBar->CountItems() >= 2) { 847 uint32 buttons; 848 BPoint location; 849 GetMouse(&location, &buttons); 850 if (fBarMenuBar->ItemAt(1)->Frame().Contains(location)) 851 return; 852 } 853 } 854 855 if (messagewithdestination) { 856 entry_ref ref; 857 if (messagewithdestination->FindRef("refs", &ref) == B_OK) { 858 BEntry entry(&ref, true); 859 if (entry.IsDirectory()) { 860 // if the ref received (should only be 1) is a directory 861 // then add the drag refs to the directory 862 AddRefsToBeMenu(DragMessage(), &ref); 863 } else 864 SendDragMessage(NULL, &ref); 865 } 866 } else { 867 // adds drag refs to top level in be menu 868 AddRefsToBeMenu(DragMessage(), NULL); 869 } 870 871 // clean up drag message and types list 872 DragStop(true); 873 } 874 875 876 // #pragma mark - Add-ons 877 878 879 // shelf is ignored for now, 880 // it exists in anticipation of having other 'shelves' for 881 // storing items 882 883 status_t 884 TBarView::ItemInfo(int32 id, const char** name, DeskbarShelf* shelf) 885 { 886 *shelf = B_DESKBAR_TRAY; 887 return fReplicantTray->ItemInfo(id, name); 888 } 889 890 891 status_t 892 TBarView::ItemInfo(const char* name, int32* id, DeskbarShelf* shelf) 893 { 894 *shelf = B_DESKBAR_TRAY; 895 return fReplicantTray->ItemInfo(name, id); 896 } 897 898 899 bool 900 TBarView::ItemExists(int32 id, DeskbarShelf) 901 { 902 return fReplicantTray->IconExists(id); 903 } 904 905 906 bool 907 TBarView::ItemExists(const char* name, DeskbarShelf) 908 { 909 return fReplicantTray->IconExists(name); 910 } 911 912 913 int32 914 TBarView::CountItems(DeskbarShelf) 915 { 916 return fReplicantTray->IconCount(); 917 } 918 919 920 status_t 921 TBarView::AddItem(BMessage* item, DeskbarShelf, int32* id) 922 { 923 return fReplicantTray->AddIcon(item, id); 924 } 925 926 927 void 928 TBarView::RemoveItem(int32 id) 929 { 930 fReplicantTray->RemoveIcon(id); 931 } 932 933 934 void 935 TBarView::RemoveItem(const char* name, DeskbarShelf) 936 { 937 fReplicantTray->RemoveIcon(name); 938 } 939 940 941 BRect 942 TBarView::OffsetIconFrame(BRect rect) const 943 { 944 BRect frame(Frame()); 945 frame.left += fDragRegion->Frame().left + fReplicantTray->Frame().left 946 + rect.left; 947 frame.top += fDragRegion->Frame().top + fReplicantTray->Frame().top 948 + rect.top; 949 950 frame.right = frame.left + rect.Width(); 951 frame.bottom = frame.top + rect.Height(); 952 953 return frame; 954 } 955 956 957 BRect 958 TBarView::IconFrame(int32 id) const 959 { 960 return OffsetIconFrame(fReplicantTray->IconFrame(id)); 961 } 962 963 964 BRect 965 TBarView::IconFrame(const char* name) const 966 { 967 return OffsetIconFrame(fReplicantTray->IconFrame(name)); 968 } 969 970