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