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 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() 451 && static_cast<TBarApp*>(be_app)->Settings()->superExpando) { 452 // Get a list of the signatures of expanded apps. Can't use 453 // team_id because there can be more than one team per application 454 if (fVertical && Expando() && vertical && fExpando) { 455 for (int index = 0; index < fExpando->CountItems(); index++) { 456 TTeamMenuItem* item 457 = dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(index)); 458 if (item != NULL && item->IsExpanded()) { 459 signature = new BString(item->Signature()); 460 expandedItems.AddItem((void*)signature); 461 } 462 } 463 } 464 } 465 466 PlaceApplicationBar(screenFrame); 467 SizeWindow(screenFrame); 468 PositionWindow(screenFrame); 469 Window()->UpdateIfNeeded(); 470 471 // Re-expand those apps. 472 if (expandedItems.CountItems() > 0) { 473 for (int sigIndex = expandedItems.CountItems(); sigIndex-- > 0;) { 474 signature = static_cast<BString*>(expandedItems.ItemAt(sigIndex)); 475 if (signature == NULL) 476 continue; 477 478 // Start at the 'bottom' of the list working up. 479 // Prevents being thrown off by expanding items. 480 for (int teamIndex = fExpando->CountItems(); teamIndex-- > 0;) { 481 TTeamMenuItem* item 482 = dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(teamIndex)); 483 if (item != NULL && !signature->Compare(item->Signature())) { 484 item->ToggleExpandState(false); 485 break; 486 } 487 } 488 } 489 490 // Clean up expanded signature list. 491 while (!expandedItems.IsEmpty()) { 492 delete static_cast<BString*>(expandedItems.RemoveItem((int32)0)); 493 } 494 495 fExpando->SizeWindow(); 496 } 497 498 Invalidate(); 499 } 500 501 502 // window placement functions 503 504 bool 505 TBarView::Vertical() const 506 { 507 return fVertical; 508 } 509 510 511 bool 512 TBarView::Left() const 513 { 514 return fLeft; 515 } 516 517 518 bool 519 TBarView::AcrossTop() const 520 { 521 return fTop && !fVertical; 522 } 523 524 525 bool 526 TBarView::AcrossBottom() const 527 { 528 return !fTop && !fVertical; 529 } 530 531 532 bool 533 TBarView::Expando() const 534 { 535 return fState == kExpandoState; 536 } 537 538 539 bool 540 TBarView::Top() const 541 { 542 return fTop; 543 } 544 545 546 int32 547 TBarView::State() const 548 { 549 return fState; 550 } 551 552 553 // optional functionality functions 554 555 bool 556 TBarView::MilTime() const 557 { 558 return fShowInterval; 559 } 560 561 562 void 563 TBarView::ShowClock(bool on) 564 { 565 fShowClock = on; 566 } 567 568 569 bool 570 TBarView::ShowingClock() const 571 { 572 return fShowClock; 573 } 574 575 576 // #pragma mark - Drag and Drop 577 578 579 void 580 TBarView::CacheDragData(const BMessage* incoming) 581 { 582 if (!incoming) 583 return; 584 585 if (Dragging() && SpringLoadedFolderCompareMessages(incoming, fDragMessage)) 586 return; 587 588 // disposes then fills cached drag message and 589 // mimetypes list 590 SpringLoadedFolderCacheDragData(incoming, &fDragMessage, &fCachedTypesList); 591 } 592 593 594 static void 595 init_tracking_hook(BMenuItem* item, 596 bool (*hookFunction)(BMenu*, void*), void* state) 597 { 598 if (!item) 599 return; 600 601 BMenu* windowMenu = item->Submenu(); 602 if (windowMenu) { 603 // have a menu, set the tracking hook 604 windowMenu->SetTrackingHook(hookFunction, state); 605 } 606 } 607 608 609 status_t 610 TBarView::DragStart() 611 { 612 if (!Dragging()) 613 return B_OK; 614 615 BPoint loc; 616 uint32 buttons; 617 GetMouse(&loc, &buttons); 618 619 if (fExpando && fExpando->Frame().Contains(loc)) { 620 ConvertToScreen(&loc); 621 BPoint expandoLocation = fExpando->ConvertFromScreen(loc); 622 TTeamMenuItem* item = fExpando->TeamItemAtPoint(expandoLocation); 623 624 if (fLastDragItem) 625 init_tracking_hook(fLastDragItem, NULL, NULL); 626 627 if (item) { 628 if (item == fLastDragItem) 629 return B_OK; 630 631 fLastDragItem = item; 632 } 633 } 634 635 return B_OK; 636 } 637 638 639 bool 640 TBarView::MenuTrackingHook(BMenu* menu, void* castToThis) 641 { 642 // return true if the menu should go away 643 TrackingHookData* data = static_cast<TrackingHookData*>(castToThis); 644 if (!data) 645 return false; 646 647 TBarView* barview = dynamic_cast<TBarView*>(data->fTarget.Target(NULL)); 648 if (!barview || !menu->LockLooper()) 649 return false; 650 651 uint32 buttons; 652 BPoint location; 653 menu->GetMouse(&location, &buttons); 654 655 bool endMenu = true; 656 BRect frame(menu->Bounds()); 657 frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin); 658 659 if (frame.Contains(location)) { 660 // if current loc is still in the menu 661 // keep tracking 662 endMenu = false; 663 } else { 664 // see if the mouse is in the team/be menu item 665 menu->ConvertToScreen(&location); 666 if (barview->LockLooper()) { 667 TExpandoMenuBar* expando = barview->ExpandoMenuBar(); 668 TBeMenu* bemenu 669 = (dynamic_cast<TBarWindow*>(barview->Window()))->BeMenu(); 670 671 if (bemenu && bemenu->LockLooper()) { 672 bemenu->ConvertFromScreen(&location); 673 if (bemenu->Frame().Contains(location)) 674 endMenu = false; 675 676 bemenu->UnlockLooper(); 677 } 678 679 if (endMenu && expando) { 680 expando->ConvertFromScreen(&location); 681 BMenuItem* item = expando->TeamItemAtPoint(location); 682 if (item) 683 endMenu = false; 684 } 685 barview->UnlockLooper(); 686 } 687 } 688 689 menu->UnlockLooper(); 690 return endMenu; 691 } 692 693 694 // used by WindowMenu and TeamMenu to 695 // set the tracking hook for dragging 696 TrackingHookData* 697 TBarView::GetTrackingHookData() 698 { 699 // all tracking hook data is 700 // preset in AttachedToWindow 701 // data should never change 702 return &fTrackingHookData; 703 } 704 705 706 void 707 TBarView::DragStop(bool full) 708 { 709 if (!Dragging()) 710 return; 711 712 if (fExpando) { 713 if (fLastDragItem) { 714 init_tracking_hook(fLastDragItem, NULL, NULL); 715 fLastDragItem = NULL; 716 } 717 } 718 719 if (full) { 720 delete fDragMessage; 721 fDragMessage = NULL; 722 723 delete fCachedTypesList; 724 fCachedTypesList = NULL; 725 } 726 } 727 728 729 bool 730 TBarView::AppCanHandleTypes(const char* signature) 731 { 732 // used for filtering apps/teams in the ExpandoMenuBar and TeamMenu 733 734 if (modifiers() & B_CONTROL_KEY) { 735 // control key forces acceptance, just like drag&drop on icons 736 return true; 737 } 738 739 if (!signature || strlen(signature) == 0 740 || !fCachedTypesList || fCachedTypesList->CountItems() == 0) 741 return false; 742 743 if (strcmp(signature, kTrackerSignature) == 0) { 744 // tracker should support all types 745 // and should pass them on to the appropriate application 746 return true; 747 } 748 749 entry_ref hintref; 750 BMimeType appmime(signature); 751 if (appmime.GetAppHint(&hintref) != B_OK) 752 return false; 753 754 // an app was found, now see if it supports any of 755 // the refs in the message 756 BFile file(&hintref, O_RDONLY); 757 BAppFileInfo fileinfo(&file); 758 759 // scan the cached mimetype list and see if this app 760 // supports anything in the list 761 // only one item needs to match in the list of refs 762 763 int32 count = fCachedTypesList->CountItems(); 764 for (int32 i = 0 ; i < count ; i++) { 765 if (fileinfo.IsSupportedType(fCachedTypesList->ItemAt(i)->String())) 766 return true; 767 } 768 769 return false; 770 } 771 772 773 void 774 TBarView::SetDragOverride(bool on) 775 { 776 fRefsRcvdOnly = on; 777 } 778 779 780 bool 781 TBarView::DragOverride() 782 { 783 return fRefsRcvdOnly; 784 } 785 786 787 status_t 788 TBarView::SendDragMessage(const char* signature, entry_ref* ref) 789 { 790 status_t err = B_ERROR; 791 if (fDragMessage) { 792 if (fRefsRcvdOnly) { 793 // current message sent to apps is only B_REFS_RECEIVED 794 fDragMessage->what = B_REFS_RECEIVED; 795 } 796 797 BRoster roster; 798 if (signature && strlen(signature) > 0 && roster.IsRunning(signature)) { 799 BMessenger mess(signature); 800 // drag message is still owned by DB, copy is sent 801 // can toss it after send 802 err = mess.SendMessage(fDragMessage); 803 } else if (ref) { 804 FSLaunchItem((const entry_ref*)ref, (const BMessage*)fDragMessage, 805 true, true); 806 } else if (signature && strlen(signature) > 0) { 807 roster.Launch(signature, fDragMessage); 808 } 809 } 810 return err; 811 } 812 813 814 bool 815 TBarView::InvokeItem(const char* signature) 816 { 817 // sent from TeamMenuItem 818 if (Dragging() && AppCanHandleTypes(signature)) { 819 SendDragMessage(signature); 820 // invoking okay to toss memory 821 DragStop(true); 822 return true; 823 } 824 825 return false; 826 } 827 828 829 void 830 TBarView::HandleBeMenu(BMessage* messagewithdestination) 831 { 832 if (!Dragging()) 833 return; 834 835 // in mini-mode 836 if (Vertical() && !Expando()) { 837 // if drop is in the team menu, bail 838 if (fBarMenuBar->CountItems() >= 2) { 839 uint32 buttons; 840 BPoint location; 841 GetMouse(&location, &buttons); 842 if (fBarMenuBar->ItemAt(1)->Frame().Contains(location)) 843 return; 844 } 845 } 846 847 if (messagewithdestination) { 848 entry_ref ref; 849 if (messagewithdestination->FindRef("refs", &ref) == B_OK) { 850 BEntry entry(&ref, true); 851 if (entry.IsDirectory()) { 852 // if the ref received (should only be 1) is a directory 853 // then add the drag refs to the directory 854 AddRefsToBeMenu(DragMessage(), &ref); 855 } else 856 SendDragMessage(NULL, &ref); 857 } 858 } else { 859 // adds drag refs to top level in be menu 860 AddRefsToBeMenu(DragMessage(), NULL); 861 } 862 863 // clean up drag message and types list 864 DragStop(true); 865 } 866 867 868 // #pragma mark - Add-ons 869 870 871 // shelf is ignored for now, 872 // it exists in anticipation of having other 'shelves' for 873 // storing items 874 875 status_t 876 TBarView::ItemInfo(int32 id, const char** name, DeskbarShelf* shelf) 877 { 878 *shelf = B_DESKBAR_TRAY; 879 return fReplicantTray->ItemInfo(id, name); 880 } 881 882 883 status_t 884 TBarView::ItemInfo(const char* name, int32* id, DeskbarShelf* shelf) 885 { 886 *shelf = B_DESKBAR_TRAY; 887 return fReplicantTray->ItemInfo(name, id); 888 } 889 890 891 bool 892 TBarView::ItemExists(int32 id, DeskbarShelf) 893 { 894 return fReplicantTray->IconExists(id); 895 } 896 897 898 bool 899 TBarView::ItemExists(const char* name, DeskbarShelf) 900 { 901 return fReplicantTray->IconExists(name); 902 } 903 904 905 int32 906 TBarView::CountItems(DeskbarShelf) 907 { 908 return fReplicantTray->IconCount(); 909 } 910 911 912 status_t 913 TBarView::AddItem(BMessage* item, DeskbarShelf, int32* id) 914 { 915 return fReplicantTray->AddIcon(item, id); 916 } 917 918 919 void 920 TBarView::RemoveItem(int32 id) 921 { 922 fReplicantTray->RemoveIcon(id); 923 } 924 925 926 void 927 TBarView::RemoveItem(const char* name, DeskbarShelf) 928 { 929 fReplicantTray->RemoveIcon(name); 930 } 931 932 933 BRect 934 TBarView::OffsetIconFrame(BRect rect) const 935 { 936 BRect frame(Frame()); 937 frame.left += fDragRegion->Frame().left + fReplicantTray->Frame().left 938 + rect.left; 939 frame.top += fDragRegion->Frame().top + fReplicantTray->Frame().top 940 + rect.top; 941 942 frame.right = frame.left + rect.Width(); 943 frame.bottom = frame.top + rect.Height(); 944 945 return frame; 946 } 947 948 949 BRect 950 TBarView::IconFrame(int32 id) const 951 { 952 return OffsetIconFrame(fReplicantTray->IconFrame(id)); 953 } 954 955 956 BRect 957 TBarView::IconFrame(const char* name) const 958 { 959 return OffsetIconFrame(fReplicantTray->IconFrame(name)); 960 } 961 962