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 } 90 91 92 TBarView::~TBarView() 93 { 94 delete fDragMessage; 95 delete fCachedTypesList; 96 } 97 98 99 void 100 TBarView::AttachedToWindow() 101 { 102 BView::AttachedToWindow(); 103 104 SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); 105 SetFont(be_plain_font); 106 107 fReplicantTray = new TReplicantTray(this, fVertical); 108 fDragRegion = new TDragRegion(this, fReplicantTray); 109 fDragRegion->AddChild(fReplicantTray); 110 if (fTrayLocation != 0) 111 AddChild(fDragRegion); 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 fBarMenuBar->SmartResize(width, menuFrame.Height()); 246 fBarMenuBar->MoveTo(loc); 247 } 248 249 250 void 251 TBarView::PlaceTray(bool, bool, BRect screenFrame) 252 { 253 BPoint statusLoc; 254 if (fState == kFullState) { 255 fDragRegion->ResizeTo(fBarMenuBar->Frame().Width(), kMenuBarHeight); 256 statusLoc.y = fBarMenuBar->Frame().bottom + 1; 257 statusLoc.x = 0; 258 fDragRegion->MoveTo(statusLoc); 259 260 if (!fReplicantTray->IsHidden()) 261 fReplicantTray->Hide(); 262 263 return; 264 } 265 266 if (fReplicantTray->IsHidden()) 267 fReplicantTray->Show(); 268 269 if (fTrayLocation != 0) { 270 fReplicantTray->SetMultiRow(fVertical); 271 fReplicantTray->RealignReplicants(); 272 fDragRegion->ResizeToPreferred(); 273 274 if (fVertical) { 275 statusLoc.y = fBarMenuBar->Frame().bottom + 1; 276 statusLoc.x = 0; 277 if (Left() && Vertical()) 278 fReplicantTray->MoveTo(5, 2); 279 else 280 fReplicantTray->MoveTo(2, 2); 281 } else { 282 statusLoc.x = screenFrame.right - fDragRegion->Bounds().Width(); 283 statusLoc.y = -1; 284 } 285 286 fDragRegion->MoveTo(statusLoc); 287 } 288 } 289 290 291 void 292 TBarView::PlaceApplicationBar(BRect screenFrame) 293 { 294 if (fExpando != NULL) { 295 fExpando->RemoveSelf(); 296 delete fExpando; 297 fExpando = NULL; 298 } 299 if (fState == kMiniState) 300 return; 301 302 BRect expandoFrame(0, 0, 0, 0); 303 if (fVertical) { 304 // top left/right 305 if (fTrayLocation != 0) 306 expandoFrame.top = fDragRegion->Frame().bottom + 1; 307 else 308 expandoFrame.top = fBarMenuBar->Frame().bottom + 1; 309 310 expandoFrame.bottom = expandoFrame.top + 1; 311 if (fState == kFullState) 312 expandoFrame.right = fBarMenuBar->Frame().Width(); 313 else 314 expandoFrame.right = sMinimumWindowWidth; 315 } else { 316 // top or bottom 317 expandoFrame.top = 0; 318 expandoFrame.bottom = kHModeHeight; 319 if (fTrayLocation != 0) 320 expandoFrame.right = fDragRegion->Frame().left - 1; 321 else 322 expandoFrame.right = screenFrame.Width(); 323 } 324 325 fExpando = new TExpandoMenuBar(this, expandoFrame, "ExpandoMenuBar", 326 fVertical, fState != kFullState); 327 AddChild(fExpando); 328 } 329 330 331 void 332 TBarView::GetPreferredWindowSize(BRect screenFrame, float *width, float *height) 333 { 334 float windowHeight = 0; 335 float windowWidth = sMinimumWindowWidth; 336 if (fState == kFullState) { 337 windowHeight = screenFrame.bottom; 338 windowWidth = fBarMenuBar->Frame().Width(); 339 } else if (fState == kExpandoState) { 340 if (fVertical) { 341 // top left or right 342 windowHeight = fExpando->Frame().bottom; 343 } else { 344 // top or bottom, full 345 fExpando->CheckItemSizes(0); 346 windowHeight = kHModeHeight; 347 windowWidth = screenFrame.Width(); 348 } 349 } else { 350 // four corners 351 if (fTrayLocation != 0) 352 windowHeight = fDragRegion->Frame().bottom; 353 else 354 windowHeight = fBarMenuBar->Frame().bottom; 355 } 356 357 *width = windowWidth; 358 *height = windowHeight; 359 } 360 361 362 void 363 TBarView::SizeWindow(BRect screenFrame) 364 { 365 float windowWidth, windowHeight; 366 GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight); 367 Window()->ResizeTo(windowWidth, windowHeight); 368 if (fExpando) 369 fExpando->CheckForSizeOverrun(); 370 } 371 372 373 void 374 TBarView::PositionWindow(BRect screenFrame) 375 { 376 float windowWidth, windowHeight; 377 GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight); 378 379 BPoint moveLoc(0, 0); 380 // right, expanded 381 if (!fLeft && fVertical) { 382 if (fState == kFullState) 383 moveLoc.x = screenFrame.right - fBarMenuBar->Frame().Width(); 384 else 385 moveLoc.x = screenFrame.right - windowWidth; 386 } 387 388 // bottom, full or corners 389 if (!fTop) 390 moveLoc.y = screenFrame.bottom - windowHeight; 391 392 Window()->MoveTo(moveLoc); 393 } 394 395 396 void 397 TBarView::SaveSettings() 398 { 399 desk_settings *settings = ((TBarApp *)be_app)->Settings(); 400 401 settings->vertical = Vertical(); 402 settings->left = Left(); 403 settings->top = Top(); 404 settings->ampmMode = MilTime(); 405 settings->state = (uint32)State(); 406 settings->width = 0; 407 settings->showTime = ShowingClock(); 408 409 fReplicantTray->RememberClockSettings(); 410 settings->alwaysOnTop = (Window()->Feel() & B_FLOATING_ALL_WINDOW_FEEL) != 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 437 fState = state; 438 fVertical = vertical; 439 fLeft = left; 440 fTop = top; 441 442 BRect screenFrame = (BScreen(Window())).Frame(); 443 444 PlaceBeMenu(); 445 PlaceTray(vertSwap, leftSwap, screenFrame); 446 447 // We need to keep track of what apps are expanded. 448 BList expandedItems; 449 BString *signature = NULL; 450 if (fVertical && Expando() && static_cast<TBarApp *>(be_app)->Settings()->superExpando) { 451 // Get a list of the Signatures of expanded apps - Can't use team_id because 452 // there can be more than one team per application 453 if (fVertical && Expando() && vertical && fExpando) { 454 for (int index = 0; index < fExpando->CountItems(); index++) { 455 TTeamMenuItem *item = dynamic_cast<TTeamMenuItem *>(fExpando->ItemAt(index)); 456 if (item != NULL && item->IsExpanded()) { 457 signature = new BString(item->Signature()); 458 expandedItems.AddItem((void *)signature); 459 } 460 } 461 } 462 } 463 464 PlaceApplicationBar(screenFrame); 465 SizeWindow(screenFrame); 466 PositionWindow(screenFrame); 467 Window()->UpdateIfNeeded(); 468 469 // Re-expand those apps. 470 if (expandedItems.CountItems() > 0) { 471 for (int sigIndex = expandedItems.CountItems(); sigIndex-- > 0;) { 472 signature = static_cast<BString *>(expandedItems.ItemAt(sigIndex)); 473 if (signature == NULL) 474 continue; 475 476 // Start at the 'bottom' of the list working up. 477 // Prevents being thrown off by expanding items. 478 for (int teamIndex = fExpando->CountItems(); teamIndex-- > 0;) { 479 TTeamMenuItem *item = dynamic_cast<TTeamMenuItem *>(fExpando->ItemAt(teamIndex)); 480 if (item != NULL && !signature->Compare(item->Signature())) { 481 item->ToggleExpandState(false); 482 break; 483 } 484 } 485 } 486 487 // Clean up expanded signature list. 488 while (!expandedItems.IsEmpty()) { 489 delete static_cast<BString *>(expandedItems.RemoveItem((int32)0)); 490 } 491 492 fExpando->SizeWindow(); 493 } 494 495 Invalidate(); 496 } 497 498 499 // window placement functions 500 501 bool 502 TBarView::Vertical() const 503 { 504 return fVertical; 505 } 506 507 508 bool 509 TBarView::Left() const 510 { 511 return fLeft; 512 } 513 514 515 bool 516 TBarView::AcrossTop() const 517 { 518 return fTop && !fVertical; 519 } 520 521 522 bool 523 TBarView::AcrossBottom() const 524 { 525 return !fTop && !fVertical; 526 } 527 528 529 bool 530 TBarView::Expando() const 531 { 532 return fState == kExpandoState; 533 } 534 535 536 bool 537 TBarView::Top() const 538 { 539 return fTop; 540 } 541 542 543 int32 544 TBarView::State() const 545 { 546 return fState; 547 } 548 549 550 // optional functionality functions 551 552 bool 553 TBarView::MilTime() const 554 { 555 return fShowInterval; 556 } 557 558 559 void 560 TBarView::ShowClock(bool on) 561 { 562 fShowClock = on; 563 } 564 565 566 bool 567 TBarView::ShowingClock() const 568 { 569 return fShowClock; 570 } 571 572 573 // #pragma mark - Drag and Drop 574 575 void 576 TBarView::CacheDragData(const BMessage *incoming) 577 { 578 if (!incoming) 579 return; 580 581 if (Dragging() && SpringLoadedFolderCompareMessages(incoming, fDragMessage)) 582 return; 583 584 // disposes then fills cached drag message and 585 // mimetypes list 586 SpringLoadedFolderCacheDragData(incoming, &fDragMessage, &fCachedTypesList); 587 } 588 589 590 static void 591 init_tracking_hook(BMenuItem *item, 592 bool (*hookFunction)(BMenu *, void *), void *state) 593 { 594 if (!item) 595 return; 596 597 BMenu *windowMenu = item->Submenu(); 598 if (windowMenu) { 599 // have a menu, set the tracking hook 600 windowMenu->SetTrackingHook(hookFunction, state); 601 } 602 } 603 604 605 status_t 606 TBarView::DragStart() 607 { 608 if (!Dragging()) 609 return B_OK; 610 611 BPoint loc; 612 uint32 buttons; 613 GetMouse(&loc, &buttons); 614 615 if (fExpando && fExpando->Frame().Contains(loc)) { 616 ConvertToScreen(&loc); 617 BPoint expandoLocation = fExpando->ConvertFromScreen(loc); 618 TTeamMenuItem *item = fExpando->TeamItemAtPoint(expandoLocation); 619 620 if (fLastDragItem) 621 init_tracking_hook(fLastDragItem, NULL, NULL); 622 623 if (item) { 624 if (item == fLastDragItem) 625 return B_OK; 626 627 fLastDragItem = item; 628 } 629 } 630 631 return B_OK; 632 } 633 634 635 bool 636 TBarView::MenuTrackingHook(BMenu *menu, void *castToThis) 637 { 638 // return true if the menu should go away 639 TrackingHookData *data = static_cast<TrackingHookData *>(castToThis); 640 if (!data) 641 return false; 642 643 TBarView *barview = dynamic_cast<TBarView *>(data->fTarget.Target(NULL)); 644 if (!barview || !menu->LockLooper()) 645 return false; 646 647 uint32 buttons; 648 BPoint location; 649 menu->GetMouse(&location, &buttons); 650 651 bool endMenu = true; 652 BRect frame(menu->Bounds()); 653 frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin); 654 655 if (frame.Contains(location)) { 656 // if current loc is still in the menu 657 // keep tracking 658 endMenu = false; 659 } else { 660 // see if the mouse is in the team/be menu item 661 menu->ConvertToScreen(&location); 662 if (barview->LockLooper()) { 663 TExpandoMenuBar *expando = barview->ExpandoMenuBar(); 664 TBeMenu *bemenu = (dynamic_cast<TBarWindow*>(barview->Window()))->BeMenu(); 665 666 if (bemenu && bemenu->LockLooper()) { 667 bemenu->ConvertFromScreen(&location); 668 if (bemenu->Frame().Contains(location)) 669 endMenu = false; 670 671 bemenu->UnlockLooper(); 672 } 673 674 if (endMenu && expando) { 675 expando->ConvertFromScreen(&location); 676 BMenuItem *item = expando->TeamItemAtPoint(location); 677 if (item) 678 endMenu = false; 679 } 680 barview->UnlockLooper(); 681 } 682 } 683 684 menu->UnlockLooper(); 685 return endMenu; 686 } 687 688 689 // used by WindowMenu and TeamMenu to 690 // set the tracking hook for dragging 691 TrackingHookData * 692 TBarView::GetTrackingHookData() 693 { 694 // all tracking hook data is 695 // preset in AttachedToWindow 696 // data should never change 697 return &fTrackingHookData; 698 } 699 700 701 void 702 TBarView::DragStop(bool full) 703 { 704 if (!Dragging()) 705 return; 706 707 if (fExpando) { 708 if (fLastDragItem) { 709 init_tracking_hook(fLastDragItem, NULL, NULL); 710 fLastDragItem = NULL; 711 } 712 } 713 714 if (full) { 715 delete fDragMessage; 716 fDragMessage = NULL; 717 718 delete fCachedTypesList; 719 fCachedTypesList = NULL; 720 } 721 } 722 723 724 bool 725 TBarView::AppCanHandleTypes(const char *signature) 726 { 727 // used for filtering apps/teams in the ExpandoMenuBar and TeamMenu 728 729 if (modifiers() & B_CONTROL_KEY) { 730 // control key forces acceptance, just like drag&drop on icons 731 return true; 732 } 733 734 if (!signature || strlen(signature) == 0 735 || !fCachedTypesList || fCachedTypesList->CountItems() == 0) 736 return false; 737 738 if (strcmp(signature, kTrackerSignature) == 0) { 739 // tracker should support all types 740 // and should pass them on to the appropriate application 741 return true; 742 } 743 744 entry_ref hintref; 745 BMimeType appmime(signature); 746 if (appmime.GetAppHint(&hintref) != B_OK) 747 return false; 748 749 // an app was found, now see if it supports any of 750 // the refs in the message 751 BFile file(&hintref, O_RDONLY); 752 BAppFileInfo fileinfo(&file); 753 754 // scan the cached mimetype list and see if this app 755 // supports anything in the list 756 // only one item needs to match in the list of refs 757 758 int32 count = fCachedTypesList->CountItems(); 759 for (int32 i = 0 ; i < count ; i++) { 760 if (fileinfo.IsSupportedType(fCachedTypesList->ItemAt(i)->String())) 761 return true; 762 } 763 764 return false; 765 } 766 767 768 void 769 TBarView::SetDragOverride(bool on) 770 { 771 fRefsRcvdOnly = on; 772 } 773 774 775 bool 776 TBarView::DragOverride() 777 { 778 return fRefsRcvdOnly; 779 } 780 781 782 status_t 783 TBarView::SendDragMessage(const char *signature, entry_ref *ref) 784 { 785 status_t err = B_ERROR; 786 if (fDragMessage) { 787 if (fRefsRcvdOnly) { 788 // current message sent to apps is only B_REFS_RECEIVED 789 fDragMessage->what = B_REFS_RECEIVED; 790 } 791 792 BRoster roster; 793 if (signature && strlen(signature) > 0 && roster.IsRunning(signature)) { 794 BMessenger mess(signature); 795 // drag message is still owned by DB, copy is sent 796 // can toss it after send 797 err = mess.SendMessage(fDragMessage); 798 } else if (ref) { 799 FSLaunchItem((const entry_ref*)ref, (const BMessage*)fDragMessage, 800 true, true); 801 } else if (signature && strlen(signature) > 0) { 802 roster.Launch(signature, fDragMessage); 803 } 804 } 805 return err; 806 } 807 808 809 bool 810 TBarView::InvokeItem(const char *signature) 811 { 812 // sent from TeamMenuItem 813 if (Dragging() && AppCanHandleTypes(signature)) { 814 SendDragMessage(signature); 815 // invoking okay to toss memory 816 DragStop(true); 817 return true; 818 } 819 820 return false; 821 } 822 823 824 void 825 TBarView::HandleBeMenu(BMessage *messagewithdestination) 826 { 827 if (!Dragging()) 828 return; 829 830 // in mini-mode 831 if (Vertical() && !Expando()) { 832 // if drop is in the team menu, bail 833 if (fBarMenuBar->CountItems() >= 2) { 834 uint32 buttons; 835 BPoint location; 836 GetMouse(&location, &buttons); 837 if (fBarMenuBar->ItemAt(1)->Frame().Contains(location)) 838 return; 839 } 840 } 841 842 if (messagewithdestination) { 843 entry_ref ref; 844 if (messagewithdestination->FindRef("refs", &ref) == B_OK) { 845 BEntry entry(&ref, true); 846 if (entry.IsDirectory()) { 847 // if the ref received (should only be 1) is a directory 848 // then add the drag refs to the directory 849 AddRefsToBeMenu(DragMessage(), &ref); 850 } else 851 SendDragMessage(NULL, &ref); 852 } 853 } else { 854 // adds drag refs to top level in be menu 855 AddRefsToBeMenu(DragMessage(), NULL); 856 } 857 858 // clean up drag message and types list 859 DragStop(true); 860 } 861 862 863 // #pragma mark - Add-ons 864 865 866 // shelf is ignored for now, 867 // it exists in anticipation of having other 'shelves' for 868 // storing items 869 870 status_t 871 TBarView::ItemInfo(int32 id, const char **name, DeskbarShelf *shelf) 872 { 873 *shelf = B_DESKBAR_TRAY; 874 return fReplicantTray->ItemInfo(id, name); 875 } 876 877 878 status_t 879 TBarView::ItemInfo(const char *name, int32 *id, DeskbarShelf *shelf) 880 { 881 *shelf = B_DESKBAR_TRAY; 882 return fReplicantTray->ItemInfo(name, id); 883 } 884 885 886 bool 887 TBarView::ItemExists(int32 id, DeskbarShelf) 888 { 889 return fReplicantTray->IconExists(id); 890 } 891 892 893 bool 894 TBarView::ItemExists(const char *name, DeskbarShelf) 895 { 896 return fReplicantTray->IconExists(name); 897 } 898 899 900 int32 901 TBarView::CountItems(DeskbarShelf) 902 { 903 return fReplicantTray->IconCount(); 904 } 905 906 907 status_t 908 TBarView::AddItem(BMessage *item, DeskbarShelf, int32 *id) 909 { 910 return fReplicantTray->AddIcon(item, id); 911 } 912 913 914 void 915 TBarView::RemoveItem(int32 id) 916 { 917 fReplicantTray->RemoveIcon(id); 918 } 919 920 921 void 922 TBarView::RemoveItem(const char *name, DeskbarShelf) 923 { 924 fReplicantTray->RemoveIcon(name); 925 } 926 927 928 BRect 929 TBarView::OffsetIconFrame(BRect rect) const 930 { 931 BRect frame(Frame()); 932 frame.left += fDragRegion->Frame().left + fReplicantTray->Frame().left + rect.left; 933 frame.top += fDragRegion->Frame().top + fReplicantTray->Frame().top + rect.top; 934 935 frame.right = frame.left + rect.Width(); 936 frame.bottom = frame.top + rect.Height(); 937 938 return frame; 939 } 940 941 942 BRect 943 TBarView::IconFrame(int32 id) const 944 { 945 return OffsetIconFrame(fReplicantTray->IconFrame(id)); 946 } 947 948 949 BRect 950 TBarView::IconFrame(const char *name) const 951 { 952 return OffsetIconFrame(fReplicantTray->IconFrame(name)); 953 } 954 955