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