6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
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:
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.
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.
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.
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
30 trademarks of Be Incorporated in the United States and other countries. Other
31 brand product names are registered trademarks or trademarks of their respective
39 #include <AppFileInfo.h>
42 #include <Directory.h>
43 #include <LocaleRoster.h>
51 #include "BarMenuBar.h"
52 #include "BarWindow.h"
53 #include "DeskbarMenu.h"
54 #include "DeskbarUtils.h"
55 #include "ExpandoMenuBar.h"
57 #include "InlineScrollView.h"
58 #include "ResourceSet.h"
59 #include "StatusView.h"
60 #include "TeamMenuItem.h"
63 const int32 kDefaultRecentDocCount
= 10;
64 const int32 kDefaultRecentFolderCount
= 10;
65 const int32 kDefaultRecentAppCount
= 10;
67 const int32 kMenuTrackMargin
= 20;
69 const uint32 kUpdateOrientation
= 'UpOr';
70 const float kSepItemWidth
= 5.0f
;
73 class BarViewMessageFilter
: public BMessageFilter
76 BarViewMessageFilter(TBarView
* barView
);
77 virtual ~BarViewMessageFilter();
79 virtual filter_result
Filter(BMessage
* message
, BHandler
** target
);
86 BarViewMessageFilter::BarViewMessageFilter(TBarView
* barView
)
88 BMessageFilter(B_ANY_DELIVERY
, B_ANY_SOURCE
),
94 BarViewMessageFilter::~BarViewMessageFilter()
100 BarViewMessageFilter::Filter(BMessage
* message
, BHandler
** target
)
102 if (message
->what
== B_MOUSE_DOWN
|| message
->what
== B_MOUSE_MOVED
) {
103 BPoint where
= message
->FindPoint("be:view_where");
104 uint32 transit
= message
->FindInt32("be:transit");
105 BMessage
* dragMessage
= NULL
;
106 if (message
->HasMessage("be:drag_message")) {
107 dragMessage
= new BMessage();
108 message
->FindMessage("be:drag_message", dragMessage
);
111 switch (message
->what
) {
113 fBarView
->MouseDown(where
);
117 fBarView
->MouseMoved(where
, transit
, dragMessage
);
124 return B_DISPATCH_MESSAGE
;
128 // #pragma mark - TBarView
131 TBarView::TBarView(BRect frame
, bool vertical
, bool left
, bool top
,
134 BView(frame
, "BarView", B_FOLLOW_ALL_SIDES
, B_WILL_DRAW
),
135 fBarApp(static_cast<TBarApp
*>(be_app
)),
136 fInlineScrollView(NULL
),
138 fExpandoMenuBar(NULL
),
146 fCachedTypesList(NULL
),
147 fMaxRecentDocs(kDefaultRecentDocCount
),
148 fMaxRecentApps(kDefaultRecentAppCount
),
152 // determine the initial Be menu size
153 BRect
menuFrame(frame
);
155 menuFrame
.bottom
= menuFrame
.top
+ kMenuBarHeight
;
157 menuFrame
.bottom
= menuFrame
.top
+ fBarApp
->IconSize() + 4;
159 // create and add the Be menu
160 fBarMenuBar
= new TBarMenuBar(menuFrame
, "BarMenuBar", this);
161 AddChild(fBarMenuBar
);
163 // create the status tray
164 fReplicantTray
= new TReplicantTray(this, fVertical
);
166 // create the resize control
167 fResizeControl
= new TResizeControl(this);
169 // create the drag region and add the resize control
170 // and replicant tray to it
171 fDragRegion
= new TDragRegion(this, fReplicantTray
);
172 fDragRegion
->AddChild(fResizeControl
);
173 fDragRegion
->AddChild(fReplicantTray
);
175 // Add the drag region
176 if (fTrayLocation
!= 0)
177 AddChild(fDragRegion
);
179 // create and add the application menubar
180 fExpandoMenuBar
= new TExpandoMenuBar(this, fVertical
);
181 fInlineScrollView
= new TInlineScrollView(fExpandoMenuBar
,
182 fVertical
? B_VERTICAL
: B_HORIZONTAL
);
183 AddChild(fInlineScrollView
);
185 // If mini mode, hide the application menubar
186 if (state
== kMiniState
)
187 fInlineScrollView
->Hide();
191 TBarView::~TBarView()
194 delete fCachedTypesList
;
200 TBarView::AttachedToWindow()
202 BView::AttachedToWindow();
204 SetViewUIColor(B_MENU_BACKGROUND_COLOR
);
205 SetFont(be_plain_font
);
207 fMouseFilter
= new BarViewMessageFilter(this);
208 Window()->AddCommonFilter(fMouseFilter
);
210 fTrackingHookData
.fTrackingHook
= MenuTrackingHook
;
211 fTrackingHookData
.fTarget
= BMessenger(this);
212 fTrackingHookData
.fDragMessage
= new BMessage(B_REFS_RECEIVED
);
217 TBarView::DetachedFromWindow()
219 Window()->RemoveCommonFilter(fMouseFilter
);
222 delete fTrackingHookData
.fDragMessage
;
223 fTrackingHookData
.fDragMessage
= NULL
;
228 TBarView::Draw(BRect
)
230 BRect
bounds(Bounds());
232 rgb_color hilite
= tint_color(ViewColor(), B_DARKEN_1_TINT
);
234 SetHighColor(hilite
);
236 StrokeLine(bounds
.LeftBottom(), bounds
.RightBottom());
237 else if (AcrossBottom())
238 StrokeLine(bounds
.LeftTop(), bounds
.RightTop());
240 if (fVertical
&& fState
== kExpandoState
) {
241 SetHighColor(hilite
);
242 BRect
frame(fExpandoMenuBar
->Frame());
243 StrokeLine(BPoint(frame
.left
, frame
.top
- 1),
244 BPoint(frame
.right
, frame
.top
-1));
250 TBarView::MessageReceived(BMessage
* message
)
252 switch (message
->what
) {
253 case B_LOCALE_CHANGED
:
254 case kRealignReplicants
:
259 case kGetClockSettings
:
260 fReplicantTray
->MessageReceived(message
);
263 case B_REFS_RECEIVED
:
264 // received when an item is selected during DnD
265 // message is targeted here from Be menu
266 HandleDeskbarMenu(message
);
269 case B_ARCHIVED_OBJECT
:
271 // this message has been retargeted to here
272 // instead of directly to the replicant tray
273 // so that I can follow the common pathway
274 // for adding icons to the tray
276 if (AddItem(message
, B_DESKBAR_TRAY
, &id
) == B_OK
)
277 Looper()->DetachCurrentMessage();
281 case kUpdateOrientation
:
283 _ChangeState(message
);
288 BView::MessageReceived(message
);
294 TBarView::MouseMoved(BPoint where
, uint32 transit
, const BMessage
* dragMessage
)
296 if (fDragRegion
->IsDragging()) {
297 fDragRegion
->MouseMoved(where
, transit
, dragMessage
);
301 if (transit
== B_ENTERED_VIEW
&& EventMask() == 0)
302 SetEventMask(B_POINTER_EVENTS
, B_NO_POINTER_HISTORY
);
304 BPoint whereScreen
= ConvertToScreen(where
);
306 desk_settings
* settings
= fBarApp
->Settings();
307 bool alwaysOnTop
= settings
->alwaysOnTop
;
308 bool autoRaise
= settings
->autoRaise
;
309 bool autoHide
= settings
->autoHide
;
311 if (!autoRaise
&& !autoHide
) {
312 if (transit
== B_EXITED_VIEW
|| transit
== B_OUTSIDE_VIEW
)
317 bool isTopMost
= Window()->Feel() == B_FLOATING_ALL_WINDOW_FEEL
;
320 BRect screenFrame
= (BScreen(Window())).Frame();
321 if ((whereScreen
.x
== screenFrame
.left
322 || whereScreen
.x
== screenFrame
.right
323 || whereScreen
.y
== screenFrame
.top
324 || whereScreen
.y
== screenFrame
.bottom
)
325 && Window()->Frame().Contains(whereScreen
)) {
326 // cursor is on a screen edge within the window frame
328 if (!alwaysOnTop
&& autoRaise
&& !isTopMost
)
331 if (autoHide
&& IsHidden())
334 TBarWindow
* window
= (TBarWindow
*)Window();
335 if (window
->IsShowingMenu())
338 // cursor is not on screen edge
339 BRect preventHideArea
= Window()->Frame().InsetByCopy(
340 -kMaxPreventHidingDist
, -kMaxPreventHidingDist
);
342 if (preventHideArea
.Contains(whereScreen
))
345 // cursor to bar distance above threshold
346 if (!alwaysOnTop
&& autoRaise
&& isTopMost
) {
351 if (autoHide
&& !IsHidden())
358 TBarView::MouseDown(BPoint where
)
360 BPoint whereScreen
= ConvertToScreen(where
);
362 if (Window()->Frame().Contains(whereScreen
)) {
363 Window()->Activate();
365 if ((modifiers() & (B_CONTROL_KEY
| B_COMMAND_KEY
| B_OPTION_KEY
366 | B_SHIFT_KEY
)) == (B_CONTROL_KEY
| B_COMMAND_KEY
)) {
367 // The window key was pressed - enter dragging code
368 fDragRegion
->MouseDown(fDragRegion
->DragRegion().LeftTop());
372 // hide deskbar if required
373 desk_settings
* settings
= fBarApp
->Settings();
374 bool alwaysOnTop
= settings
->alwaysOnTop
;
375 bool autoRaise
= settings
->autoRaise
;
376 bool autoHide
= settings
->autoHide
;
377 bool isTopMost
= Window()->Feel() == B_FLOATING_ALL_WINDOW_FEEL
;
379 if (!alwaysOnTop
&& autoRaise
&& isTopMost
)
382 if (autoHide
&& !IsHidden())
389 TBarView::PlaceDeskbarMenu()
394 // Calculate the size of the deskbar menu
395 BRect
menuFrame(Bounds());
397 width
= static_cast<TBarApp
*>(be_app
)->Settings()->width
;
398 height
= kMenuBarHeight
;
399 menuFrame
.bottom
= menuFrame
.top
+ height
;
401 width
= gMinimumWindowWidth
;
402 height
= fBarApp
->IconSize() + 4;
403 menuFrame
.bottom
= menuFrame
.top
+ height
;
406 if (fBarMenuBar
== NULL
) {
407 // create the Be menu
408 fBarMenuBar
= new TBarMenuBar(menuFrame
, "BarMenuBar", this);
409 AddChild(fBarMenuBar
);
411 fBarMenuBar
->SmartResize(-1, -1);
413 BPoint
loc(B_ORIGIN
);
414 if (fState
== kFullState
) {
415 fBarMenuBar
->RemoveTeamMenu();
416 fBarMenuBar
->RemoveSeperatorItem();
417 loc
= Bounds().LeftTop();
418 } else if (fState
== kExpandoState
) {
419 fBarMenuBar
->RemoveTeamMenu();
421 // shows apps below tray
422 fBarMenuBar
->RemoveSeperatorItem();
425 // shows apps to the right of bemenu
426 fBarMenuBar
->AddSeparatorItem();
427 width
= floorf(width
) / 2 + kSepItemWidth
;
429 loc
= Bounds().LeftTop();
431 // mini mode, DeskbarMenu next to team menu
432 fBarMenuBar
->RemoveSeperatorItem();
433 fBarMenuBar
->AddTeamMenu();
436 fBarMenuBar
->SmartResize(width
, height
);
437 fBarMenuBar
->MoveTo(loc
);
442 TBarView::PlaceTray(bool vertSwap
, bool leftSwap
)
445 if (fState
== kFullState
) {
446 fDragRegion
->ResizeTo(fBarMenuBar
->Frame().Width(), kMenuBarHeight
);
447 statusLoc
.y
= fBarMenuBar
->Frame().bottom
+ 1;
449 fDragRegion
->MoveTo(statusLoc
);
450 fDragRegion
->Invalidate();
452 if (!fReplicantTray
->IsHidden())
453 fReplicantTray
->Hide();
458 if (fReplicantTray
->IsHidden())
459 fReplicantTray
->Show();
461 if (fTrayLocation
!= 0) {
462 fReplicantTray
->SetMultiRow(fVertical
);
463 fReplicantTray
->RealignReplicants();
464 fDragRegion
->ResizeToPreferred();
465 // also resizes replicant tray
467 fResizeControl
->ResizeTo(kDragWidth
, fDragRegion
->Bounds().Height()
468 - 2); // make room for top and bottom border
471 if (fResizeControl
->IsHidden())
472 fResizeControl
->Show();
475 // move replicant tray past dragger width on left
476 // also down 1px so it won't cover the border
477 fReplicantTray
->MoveTo(kDragWidth
+ kGutter
, kGutter
);
479 // shrink width by same amount
480 fReplicantTray
->ResizeBy(-(kDragWidth
+ kGutter
), 0);
482 // move replicant tray down 1px so it won't cover the border
483 fReplicantTray
->MoveTo(0, kGutter
);
487 statusLoc
.y
= fBarMenuBar
->Frame().bottom
+ 1;
489 if (!fResizeControl
->IsHidden())
490 fResizeControl
->Hide();
492 // move right and down to not cover border then resize to fit
493 fReplicantTray
->MoveTo(kGutter
, kGutter
);
494 fReplicantTray
->ResizeBy(-kGutter
, -kGutter
);
495 BRect screenFrame
= (BScreen(Window())).Frame();
496 statusLoc
.x
= screenFrame
.right
- fDragRegion
->Bounds().Width();
500 fDragRegion
->MoveTo(statusLoc
);
501 fDragRegion
->Invalidate();
503 if (fVertical
&& fLeft
)
504 fResizeControl
->MoveTo(fDragRegion
->Bounds().right
- kDragWidth
, 1);
506 fResizeControl
->MoveTo(0, 1);
508 fResizeControl
->Invalidate();
514 TBarView::PlaceApplicationBar()
516 BRect screenFrame
= (BScreen(Window())).Frame();
517 if (fState
== kMiniState
) {
518 if (!fInlineScrollView
->IsHidden())
519 fInlineScrollView
->Hide();
520 SizeWindow(screenFrame
);
521 PositionWindow(screenFrame
);
522 Window()->UpdateIfNeeded();
527 if (fInlineScrollView
->IsHidden())
528 fInlineScrollView
->Show();
530 BRect
expandoFrame(0, 0, 0, 0);
533 expandoFrame
.left
= fDragRegion
->Frame().left
;
534 expandoFrame
.top
= fTrayLocation
!= 0 ? fDragRegion
->Frame().bottom
+ 1
535 : fBarMenuBar
->Frame().bottom
+ 1;
536 expandoFrame
.right
= fBarMenuBar
->Frame().right
;
537 expandoFrame
.bottom
= fState
== kFullState
? screenFrame
.bottom
541 expandoFrame
.top
= 0;
542 expandoFrame
.bottom
= fBarApp
->IconSize() + 4;
544 if (fBarMenuBar
!= NULL
)
545 expandoFrame
.left
= fBarMenuBar
->Frame().Width() + 1;
547 if (fTrayLocation
!= 0 && fDragRegion
!= NULL
) {
548 expandoFrame
.right
= screenFrame
.Width()
549 - fDragRegion
->Frame().Width() - 1;
551 expandoFrame
.right
= screenFrame
.Width();
554 fInlineScrollView
->DetachScrollers();
555 fInlineScrollView
->MoveTo(expandoFrame
.LeftTop());
556 fInlineScrollView
->ResizeTo(expandoFrame
.Width(), fVertical
557 ? screenFrame
.bottom
- expandoFrame
.top
558 : expandoFrame
.Height());
559 fExpandoMenuBar
->MoveTo(0, 0);
560 fExpandoMenuBar
->ResizeTo(expandoFrame
.Width(), expandoFrame
.Height());
563 // Set the max item width based on icon size
564 fExpandoMenuBar
->SetMaxItemWidth();
567 if (fState
== kExpandoState
)
568 fExpandoMenuBar
->BuildItems();
570 SizeWindow(screenFrame
);
571 PositionWindow(screenFrame
);
572 fExpandoMenuBar
->DoLayout();
573 // force menu to resize
575 Window()->UpdateIfNeeded();
581 TBarView::GetPreferredWindowSize(BRect screenFrame
, float* width
, float* height
)
583 float windowHeight
= 0;
584 float windowWidth
= fBarApp
->Settings()->width
;
585 bool setToHiddenSize
= fBarApp
->Settings()->autoHide
&& IsHidden()
586 && !fDragRegion
->IsDragging();
588 if (setToHiddenSize
) {
589 windowHeight
= kHiddenDimension
;
591 if (fState
== kExpandoState
&& !fVertical
) {
592 // top or bottom, full
593 fExpandoMenuBar
->CheckItemSizes(0);
594 windowWidth
= screenFrame
.Width();
596 windowWidth
= kHiddenDimension
;
598 if (fState
== kFullState
) {
599 windowHeight
= screenFrame
.bottom
;
600 windowWidth
= fBarMenuBar
->Frame().Width();
601 } else if (fState
== kExpandoState
) {
604 if (fTrayLocation
!= 0)
605 windowHeight
= fDragRegion
->Frame().bottom
+ 1;
607 windowHeight
= fBarMenuBar
->Frame().bottom
+ 1;
609 windowHeight
+= fExpandoMenuBar
->Bounds().Height();
611 // top or bottom, full
612 fExpandoMenuBar
->CheckItemSizes(0);
613 windowHeight
= fBarApp
->IconSize() + 4;
614 windowWidth
= screenFrame
.Width();
618 if (fTrayLocation
!= 0)
619 windowHeight
= fDragRegion
->Frame().bottom
;
621 windowHeight
= fBarMenuBar
->Frame().bottom
;
625 *width
= windowWidth
;
626 *height
= windowHeight
;
631 TBarView::SizeWindow(BRect screenFrame
)
635 GetPreferredWindowSize(screenFrame
, &windowWidth
, &windowHeight
);
636 Window()->ResizeTo(windowWidth
, windowHeight
);
641 TBarView::PositionWindow(BRect screenFrame
)
645 GetPreferredWindowSize(screenFrame
, &windowWidth
, &windowHeight
);
647 BPoint
moveLoc(0, 0);
649 if (!fLeft
&& fVertical
) {
650 if (fState
== kFullState
)
651 moveLoc
.x
= screenFrame
.right
- fBarMenuBar
->Frame().Width();
653 moveLoc
.x
= screenFrame
.right
- windowWidth
;
656 // bottom, full or corners
658 moveLoc
.y
= screenFrame
.bottom
- windowHeight
;
660 Window()->MoveTo(moveLoc
);
665 TBarView::CheckForScrolling()
667 if (fInlineScrollView
!= NULL
&& fExpandoMenuBar
!= NULL
) {
668 if (fExpandoMenuBar
->CheckForSizeOverrun())
669 fInlineScrollView
->AttachScrollers();
671 fInlineScrollView
->DetachScrollers();
677 TBarView::SaveSettings()
679 desk_settings
* settings
= fBarApp
->Settings();
681 settings
->vertical
= fVertical
;
682 settings
->left
= fLeft
;
683 settings
->top
= fTop
;
684 settings
->state
= fState
;
686 fReplicantTray
->SaveTimeSettings();
691 TBarView::UpdatePlacement()
693 ChangeState(fState
, fVertical
, fLeft
, fTop
);
698 TBarView::ChangeState(int32 state
, bool vertical
, bool left
, bool top
,
701 BMessage
message(kUpdateOrientation
);
702 message
.AddInt32("state", state
);
703 message
.AddBool("vertical", vertical
);
704 message
.AddBool("left", left
);
705 message
.AddBool("top", top
);
708 BMessenger(this).SendMessage(&message
);
710 _ChangeState(&message
);
715 TBarView::_ChangeState(BMessage
* message
)
717 int32 state
= message
->FindInt32("state");
718 bool vertical
= message
->FindBool("vertical");
719 bool left
= message
->FindBool("left");
720 bool top
= message
->FindBool("top");
722 bool vertSwap
= (fVertical
!= vertical
);
723 bool leftSwap
= (fLeft
!= left
);
724 bool stateChanged
= (fState
!= state
);
727 fVertical
= vertical
;
731 if (stateChanged
|| vertSwap
) {
732 be_app
->PostMessage(kStateChanged
);
733 // Send a message to the preferences window to let it know to
734 // enable or disable preference items.
736 if (vertSwap
&& fExpandoMenuBar
!= NULL
) {
738 fInlineScrollView
->SetOrientation(B_VERTICAL
);
739 fExpandoMenuBar
->SetMenuLayout(B_ITEMS_IN_COLUMN
);
740 fExpandoMenuBar
->StartMonitoringWindows();
742 fInlineScrollView
->SetOrientation(B_HORIZONTAL
);
743 fExpandoMenuBar
->SetMenuLayout(B_ITEMS_IN_ROW
);
744 fExpandoMenuBar
->StopMonitoringWindows();
750 PlaceTray(vertSwap
, leftSwap
);
751 PlaceApplicationBar();
756 TBarView::RaiseDeskbar(bool raise
)
759 Window()->SetFeel(B_FLOATING_ALL_WINDOW_FEEL
);
761 Window()->SetFeel(B_NORMAL_WINDOW_FEEL
);
766 TBarView::HideDeskbar(bool hide
)
768 BRect screenFrame
= (BScreen(Window())).Frame();
772 PositionWindow(screenFrame
);
773 SizeWindow(screenFrame
);
776 SizeWindow(screenFrame
);
777 PositionWindow(screenFrame
);
782 // #pragma mark - Drag and Drop
786 TBarView::CacheDragData(const BMessage
* incoming
)
791 if (Dragging() && SpringLoadedFolderCompareMessages(incoming
, fDragMessage
))
794 // disposes then fills cached drag message and
796 SpringLoadedFolderCacheDragData(incoming
, &fDragMessage
, &fCachedTypesList
);
801 init_tracking_hook(BMenuItem
* item
,
802 bool (*hookFunction
)(BMenu
*, void*), void* state
)
807 BMenu
* windowMenu
= item
->Submenu();
809 // have a menu, set the tracking hook
810 windowMenu
->SetTrackingHook(hookFunction
, state
);
816 TBarView::DragStart()
823 GetMouse(&loc
, &buttons
);
825 if (fExpandoMenuBar
!= NULL
&& fExpandoMenuBar
->Frame().Contains(loc
)) {
826 ConvertToScreen(&loc
);
827 BPoint expandoLocation
= fExpandoMenuBar
->ConvertFromScreen(loc
);
828 TTeamMenuItem
* item
= fExpandoMenuBar
->TeamItemAtPoint(expandoLocation
);
831 init_tracking_hook(fLastDragItem
, NULL
, NULL
);
834 if (item
== fLastDragItem
)
837 fLastDragItem
= item
;
846 TBarView::MenuTrackingHook(BMenu
* menu
, void* castToThis
)
848 // return true if the menu should go away
849 TrackingHookData
* data
= static_cast<TrackingHookData
*>(castToThis
);
853 TBarView
* barview
= dynamic_cast<TBarView
*>(data
->fTarget
.Target(NULL
));
854 if (!barview
|| !menu
->LockLooper())
859 menu
->GetMouse(&location
, &buttons
);
862 BRect
frame(menu
->Bounds());
863 frame
.InsetBy(-kMenuTrackMargin
, -kMenuTrackMargin
);
865 if (frame
.Contains(location
)) {
866 // if current loc is still in the menu
870 // see if the mouse is in the team/deskbar menu item
871 menu
->ConvertToScreen(&location
);
872 if (barview
->LockLooper()) {
873 TExpandoMenuBar
* expando
= barview
->ExpandoMenuBar();
875 = (dynamic_cast<TBarWindow
*>(barview
->Window()))->DeskbarMenu();
877 if (bemenu
&& bemenu
->LockLooper()) {
878 bemenu
->ConvertFromScreen(&location
);
879 if (bemenu
->Frame().Contains(location
))
882 bemenu
->UnlockLooper();
885 if (endMenu
&& expando
) {
886 expando
->ConvertFromScreen(&location
);
887 BMenuItem
* item
= expando
->TeamItemAtPoint(location
);
891 barview
->UnlockLooper();
895 menu
->UnlockLooper();
900 // used by WindowMenu and TeamMenu to
901 // set the tracking hook for dragging
903 TBarView::GetTrackingHookData()
905 // all tracking hook data is
906 // preset in AttachedToWindow
907 // data should never change
908 return &fTrackingHookData
;
913 TBarView::DragStop(bool full
)
918 if (fExpandoMenuBar
!= NULL
) {
919 if (fLastDragItem
!= NULL
) {
920 init_tracking_hook(fLastDragItem
, NULL
, NULL
);
921 fLastDragItem
= NULL
;
929 delete fCachedTypesList
;
930 fCachedTypesList
= NULL
;
936 TBarView::AppCanHandleTypes(const char* signature
)
938 // used for filtering apps/teams in the ExpandoMenuBar and TeamMenu
940 if (modifiers() & B_CONTROL_KEY
) {
941 // control key forces acceptance, just like drag&drop on icons
945 if (!signature
|| strlen(signature
) == 0
946 || !fCachedTypesList
|| fCachedTypesList
->CountItems() == 0)
949 if (strcasecmp(signature
, kTrackerSignature
) == 0) {
950 // tracker should support all types
951 // and should pass them on to the appropriate application
956 BMimeType
appmime(signature
);
957 if (appmime
.GetAppHint(&hintref
) != B_OK
)
960 // an app was found, now see if it supports any of
961 // the refs in the message
962 BFile
file(&hintref
, O_RDONLY
);
963 BAppFileInfo
fileinfo(&file
);
965 // scan the cached mimetype list and see if this app
966 // supports anything in the list
967 // only one item needs to match in the list of refs
969 int32 count
= fCachedTypesList
->CountItems();
970 for (int32 i
= 0 ; i
< count
; i
++) {
971 if (fileinfo
.IsSupportedType(fCachedTypesList
->ItemAt(i
)->String()))
980 TBarView::SetDragOverride(bool on
)
987 TBarView::DragOverride()
989 return fRefsRcvdOnly
;
994 TBarView::SendDragMessage(const char* signature
, entry_ref
* ref
)
996 status_t err
= B_ERROR
;
997 if (fDragMessage
!= NULL
) {
999 // current message sent to apps is only B_REFS_RECEIVED
1000 fDragMessage
->what
= B_REFS_RECEIVED
;
1004 if (signature
!= NULL
&& *signature
!= '\0'
1005 && roster
.IsRunning(signature
)) {
1006 BMessenger
messenger(signature
);
1007 // drag message is still owned by DB, copy is sent
1008 // can toss it after send
1009 err
= messenger
.SendMessage(fDragMessage
);
1010 } else if (ref
!= NULL
) {
1011 FSLaunchItem((const entry_ref
*)ref
, (const BMessage
*)fDragMessage
,
1013 } else if (signature
!= NULL
&& *signature
!= '\0')
1014 roster
.Launch(signature
, fDragMessage
);
1022 TBarView::InvokeItem(const char* signature
)
1024 // sent from TeamMenuItem
1025 if (Dragging() && AppCanHandleTypes(signature
)) {
1026 SendDragMessage(signature
);
1027 // invoking okay to toss memory
1037 TBarView::HandleDeskbarMenu(BMessage
* messagewithdestination
)
1043 if (fVertical
&& fState
!= kExpandoState
) {
1044 // if drop is in the team menu, bail
1045 if (fBarMenuBar
->CountItems() >= 2) {
1048 GetMouse(&location
, &buttons
);
1049 if (fBarMenuBar
->ItemAt(1)->Frame().Contains(location
))
1054 if (messagewithdestination
) {
1056 if (messagewithdestination
->FindRef("refs", &ref
) == B_OK
) {
1057 BEntry
entry(&ref
, true);
1058 if (entry
.IsDirectory()) {
1059 // if the ref received (should only be 1) is a directory
1060 // then add the drag refs to the directory
1061 AddRefsToDeskbarMenu(DragMessage(), &ref
);
1063 SendDragMessage(NULL
, &ref
);
1066 // adds drag refs to top level in deskbar menu
1067 AddRefsToDeskbarMenu(DragMessage(), NULL
);
1070 // clean up drag message and types list
1075 // #pragma mark - Add-ons
1078 // shelf is ignored for now,
1079 // it exists in anticipation of having other 'shelves' for
1083 TBarView::ItemInfo(int32 id
, const char** name
, DeskbarShelf
* shelf
)
1085 *shelf
= B_DESKBAR_TRAY
;
1086 return fReplicantTray
->ItemInfo(id
, name
);
1091 TBarView::ItemInfo(const char* name
, int32
* id
, DeskbarShelf
* shelf
)
1093 *shelf
= B_DESKBAR_TRAY
;
1094 return fReplicantTray
->ItemInfo(name
, id
);
1099 TBarView::ItemExists(int32 id
, DeskbarShelf
)
1101 return fReplicantTray
->IconExists(id
);
1106 TBarView::ItemExists(const char* name
, DeskbarShelf
)
1108 return fReplicantTray
->IconExists(name
);
1113 TBarView::CountItems(DeskbarShelf
)
1115 return fReplicantTray
->ReplicantCount();
1120 TBarView::AddItem(BMessage
* item
, DeskbarShelf
, int32
* id
)
1122 return fReplicantTray
->AddIcon(item
, id
);
1127 TBarView::AddItem(BEntry
* entry
, DeskbarShelf
, int32
* id
)
1129 return fReplicantTray
->LoadAddOn(entry
, id
);
1134 TBarView::RemoveItem(int32 id
)
1136 fReplicantTray
->RemoveIcon(id
);
1141 TBarView::RemoveItem(const char* name
, DeskbarShelf
)
1143 fReplicantTray
->RemoveIcon(name
);
1148 TBarView::OffsetIconFrame(BRect rect
) const
1150 BRect
frame(Frame());
1152 frame
.left
+= fDragRegion
->Frame().left
+ fReplicantTray
->Frame().left
1154 frame
.top
+= fDragRegion
->Frame().top
+ fReplicantTray
->Frame().top
1157 frame
.right
= frame
.left
+ rect
.Width();
1158 frame
.bottom
= frame
.top
+ rect
.Height();
1165 TBarView::IconFrame(int32 id
) const
1167 return OffsetIconFrame(fReplicantTray
->IconFrame(id
));
1172 TBarView::IconFrame(const char* name
) const
1174 return OffsetIconFrame(fReplicantTray
->IconFrame(name
));