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