#include "BarView.h"
#include <AppFileInfo.h>
#include <Bitmap.h>
#include <ControlLook.h>
#include <Debug.h>
#include <Directory.h>
#include <LocaleRoster.h>
#include <NodeInfo.h>
#include <Roster.h>
#include <Screen.h>
#include <String.h>
#include <StringList.h>
#include "icons.h"
#include "BarApp.h"
#include "BarMenuBar.h"
#include "BarWindow.h"
#include "DeskbarMenu.h"
#include "DeskbarUtils.h"
#include "ExpandoMenuBar.h"
#include "FSUtils.h"
#include "InlineScrollView.h"
#include "ResourceSet.h"
#include "StatusView.h"
#include "TeamMenuItem.h"
const int32 kDefaultRecentDocCount = 10;
const int32 kDefaultRecentAppCount = 10;
const int32 kMenuTrackMargin = 20;
const float kMinTeamItemHeight = 20.0f;
const float kScrollerDimension = 12.0f;
const uint32 kUpdateOrientation = 'UpOr';
class BarViewMessageFilter : public BMessageFilter
{
public:
BarViewMessageFilter(TBarView* barView);
virtual ~BarViewMessageFilter();
virtual filter_result Filter(BMessage* message, BHandler** target);
private:
TBarView* fBarView;
};
BarViewMessageFilter::BarViewMessageFilter(TBarView* barView)
:
BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
fBarView(barView)
{
}
BarViewMessageFilter::~BarViewMessageFilter()
{
}
filter_result
BarViewMessageFilter::Filter(BMessage* message, BHandler** target)
{
if (message->what == B_MOUSE_DOWN || message->what == B_MOUSE_MOVED) {
BPoint where = message->FindPoint("be:view_where");
uint32 transit = message->FindInt32("be:transit");
BMessage* dragMessage = NULL;
if (message->HasMessage("be:drag_message")) {
dragMessage = new BMessage();
message->FindMessage("be:drag_message", dragMessage);
}
switch (message->what) {
case B_MOUSE_DOWN:
fBarView->MouseDown(where);
break;
case B_MOUSE_MOVED:
fBarView->MouseMoved(where, transit, dragMessage);
break;
}
delete dragMessage;
}
return B_DISPATCH_MESSAGE;
}
TBarView::TBarView(BRect frame, bool vertical, bool left, bool top,
int32 state, float)
:
BView(frame, "BarView", B_FOLLOW_ALL_SIDES, B_WILL_DRAW),
fBarApp(static_cast<TBarApp*>(be_app)),
fBarWindow(NULL),
fInlineScrollView(NULL),
fBarMenuBar(NULL),
fExpandoMenuBar(NULL),
fTrayLocation(1),
fIsRaised(false),
fMouseDownOutside(false),
fVertical(vertical),
fTop(top),
fLeft(left),
fState(state),
fRefsRcvdOnly(true),
fDragMessage(NULL),
fCachedTypesList(NULL),
fMaxRecentDocs(kDefaultRecentDocCount),
fMaxRecentApps(kDefaultRecentAppCount),
fLastDragItem(NULL),
fMouseFilter(NULL),
fTabHeight(kMenuBarHeight)
{
BWindow* tmpWindow = new(std::nothrow) BWindow(BRect(), NULL,
B_TITLED_WINDOW, 0);
if (tmpWindow != NULL) {
BMessage settings;
if (tmpWindow->GetDecoratorSettings(&settings) == B_OK) {
BRect tabRect;
if (settings.FindRect("tab frame", &tabRect) == B_OK)
fTabHeight = tabRect.Height();
}
delete tmpWindow;
}
BRect menuFrame(frame);
if (fVertical)
menuFrame.bottom = menuFrame.top + fTabHeight - 1;
else
menuFrame.bottom = menuFrame.top + TeamMenuItemHeight();
fBarMenuBar = new TBarMenuBar(menuFrame, "BarMenuBar", this);
AddChild(fBarMenuBar);
fReplicantTray = new TReplicantTray(this);
fResizeControl = new TResizeControl(this);
fDragRegion = new TDragRegion(this, fReplicantTray);
fDragRegion->AddChild(fResizeControl);
fDragRegion->AddChild(fReplicantTray);
if (fTrayLocation != 0)
AddChild(fDragRegion);
fExpandoMenuBar = new TExpandoMenuBar(
fVertical ? B_ITEMS_IN_COLUMN : B_ITEMS_IN_ROW, this);
fInlineScrollView = new TInlineScrollView(fExpandoMenuBar,
fVertical ? B_VERTICAL : B_HORIZONTAL);
AddChild(fInlineScrollView);
if (state == kMiniState)
fInlineScrollView->Hide();
if (fBarApp->Settings()->autoHide && !IsHidden())
Hide();
}
TBarView::~TBarView()
{
delete fDragMessage;
delete fCachedTypesList;
delete fBarMenuBar;
}
void
TBarView::AttachedToWindow()
{
BView::AttachedToWindow();
fBarWindow = dynamic_cast<TBarWindow*>(Window());
SetViewUIColor(B_MENU_BACKGROUND_COLOR);
SetFont(be_plain_font);
fMouseFilter = new BarViewMessageFilter(this);
Window()->AddCommonFilter(fMouseFilter);
fTrackingHookData.fTrackingHook = MenuTrackingHook;
fTrackingHookData.fTarget = BMessenger(this);
fTrackingHookData.fDragMessage = new BMessage(B_REFS_RECEIVED);
if (!fVertical)
UpdatePlacement();
}
void
TBarView::DetachedFromWindow()
{
Window()->RemoveCommonFilter(fMouseFilter);
delete fMouseFilter;
fMouseFilter = NULL;
delete fTrackingHookData.fDragMessage;
fTrackingHookData.fDragMessage = NULL;
}
void
TBarView::Draw(BRect)
{
BRect bounds(Bounds());
rgb_color hilite = tint_color(ViewColor(), B_DARKEN_1_TINT);
SetHighColor(hilite);
if (AcrossTop())
StrokeLine(bounds.LeftBottom(), bounds.RightBottom());
else if (AcrossBottom())
StrokeLine(bounds.LeftTop(), bounds.RightTop());
if (fVertical && fState == kExpandoState) {
SetHighColor(hilite);
BRect frame(fExpandoMenuBar->Frame());
StrokeLine(BPoint(frame.left, frame.top - 1),
BPoint(frame.right, frame.top -1));
}
}
void
TBarView::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_LOCALE_CHANGED:
case kRealignReplicants:
case kShowHideTime:
case kShowSeconds:
case kShowDayOfWeek:
case kShowTimeZone:
case kGetClockSettings:
fReplicantTray->MessageReceived(message);
break;
case B_REFS_RECEIVED:
HandleDeskbarMenu(message);
break;
case B_ARCHIVED_OBJECT:
{
int32 id;
if (AddItem(message, B_DESKBAR_TRAY, &id) == B_OK)
Looper()->DetachCurrentMessage();
break;
}
case kUpdateOrientation:
{
_ChangeState(message);
break;
}
default:
BView::MessageReceived(message);
}
}
void
TBarView::MouseDown(BPoint where)
{
if (fBarWindow == NULL || fBarWindow->IsShowingMenu()
|| fReplicantTray->fTime->IsShowingCalendar()) {
return BView::MouseDown(where);
}
BMessage* currentMessage = Window()->CurrentMessage();
if (currentMessage == NULL)
return BView::MouseDown(where);
desk_settings* settings = fBarApp->Settings();
bool alwaysOnTop = settings->alwaysOnTop;
bool autoRaise = settings->autoRaise;
bool autoHide = settings->autoHide;
BPoint whereScreen = currentMessage->GetPoint("screen_where",
ConvertToScreen(where));
fMouseDownOutside = !Window()->Frame().Contains(whereScreen);
if (fMouseDownOutside) {
if (!alwaysOnTop && autoRaise && fIsRaised)
RaiseDeskbar(false);
if (autoHide && !IsHidden())
HideDeskbar(true);
} else {
if (!autoRaise && !alwaysOnTop)
Window()->Activate(true);
if ((modifiers() & (B_CONTROL_KEY | B_COMMAND_KEY | B_OPTION_KEY
| B_SHIFT_KEY)) == (B_CONTROL_KEY | B_COMMAND_KEY)) {
fDragRegion->MouseDown(fDragRegion->DragRegion().LeftTop());
return BView::MouseDown(where);
}
}
BView::MouseDown(where);
}
void
TBarView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
{
if (fDragRegion->IsDragging())
return fDragRegion->MouseMoved(where, transit, dragMessage);
else if (fResizeControl->IsResizing())
return BView::MouseMoved(where, transit, dragMessage);
desk_settings* settings = fBarApp->Settings();
bool alwaysOnTop = settings->alwaysOnTop;
bool autoRaise = settings->autoRaise;
bool autoHide = settings->autoHide;
if (!autoRaise && !autoHide) {
SetEventMask(0);
return BView::MouseMoved(where, transit, dragMessage);
} else if (EventMask() != B_POINTER_EVENTS) {
SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
}
if (fBarWindow == NULL || fBarWindow->IsShowingMenu()
|| fReplicantTray->fTime->IsShowingCalendar()) {
return BView::MouseMoved(where, transit, dragMessage);
}
BMessage* currentMessage = Window()->CurrentMessage();
if (currentMessage == NULL)
return BView::MouseMoved(where, transit, dragMessage);
BPoint whereScreen = currentMessage->GetPoint("screen_where",
ConvertToScreen(where));
BRect screenFrame = (BScreen(Window())).Frame();
bool onScreenEdge = whereScreen.x == screenFrame.left
|| whereScreen.x == screenFrame.right
|| whereScreen.y == screenFrame.top
|| whereScreen.y == screenFrame.bottom;
if (!Window()->Frame().Contains(whereScreen)) {
if (!alwaysOnTop && autoRaise && fIsRaised && !fMouseDownOutside)
RaiseDeskbar(false);
BRect preventHideArea = Window()->Frame().InsetByCopy(
-kMaxPreventHidingDist, -kMaxPreventHidingDist);
if (!preventHideArea.Contains(whereScreen)
&& autoHide && !IsHidden()) {
HideDeskbar(true);
}
} else if (onScreenEdge) {
if (!alwaysOnTop && autoRaise && !fIsRaised && !fMouseDownOutside)
RaiseDeskbar(true);
if (autoHide && IsHidden())
HideDeskbar(false);
}
BView::MouseMoved(where, transit, dragMessage);
}
void
TBarView::MouseUp(BPoint where)
{
fMouseDownOutside = false;
BView::MouseUp(where);
}
void
TBarView::PlaceDeskbarMenu()
{
float width = 0;
float height = 0;
BRect menuFrame(Bounds());
if (fVertical) {
width = static_cast<TBarApp*>(be_app)->Settings()->width;
height = fTabHeight;
} else {
if (fState == kMiniState) {
width = gMinimumWindowWidth;
height = std::max(fTabHeight,
kGutter + fReplicantTray->MaxReplicantHeight() + kGutter);
} else {
width = gMinimumWindowWidth / 2
+ be_control_look->ComposeSpacing(kIconPadding);
height = std::max(TeamMenuItemHeight(),
kGutter + fReplicantTray->MaxReplicantHeight() + kGutter);
}
}
menuFrame.bottom = menuFrame.top + height;
if (fBarMenuBar == NULL) {
fBarMenuBar = new TBarMenuBar(menuFrame, "BarMenuBar", this);
AddChild(fBarMenuBar);
} else
fBarMenuBar->SmartResize(-1, -1);
if (fState == kMiniState) {
fBarMenuBar->RemoveSeperatorItem();
fBarMenuBar->AddTeamMenu();
} else if (fVertical) {
fBarMenuBar->RemoveSeperatorItem();
fBarMenuBar->RemoveTeamMenu();
} else {
fBarMenuBar->RemoveTeamMenu();
fBarMenuBar->AddSeparatorItem();
}
fBarMenuBar->SmartResize(width, height);
fBarMenuBar->MoveTo(B_ORIGIN);
}
void
TBarView::PlaceTray(bool vertSwap, bool leftSwap)
{
BPoint statusLoc;
if (fTrayLocation == 0) {
if (!fReplicantTray->IsHidden())
fReplicantTray->Hide();
return;
} else if (fReplicantTray->IsHidden())
fReplicantTray->Show();
fReplicantTray->RealignReplicants();
fDragRegion->ResizeToPreferred();
if (fVertical) {
if (fResizeControl->IsHidden())
fResizeControl->Show();
if (fLeft) {
fReplicantTray->MoveTo(gDragWidth + kGutter, kGutter);
fReplicantTray->ResizeBy(-(gDragWidth + kGutter), 0);
} else {
fReplicantTray->MoveTo(0, kGutter);
}
statusLoc.x = 0;
statusLoc.y = fBarMenuBar->Frame().bottom + 1;
} else {
if (fState == kMiniState) {
statusLoc.x = fLeft ? fBarMenuBar->Frame().right + 1 : 0;
statusLoc.y = 0;
fReplicantTray->MoveTo(fLeft ? gDragWidth : 0, kGutter);
fReplicantTray->ResizeBy(0, -4);
} else {
fReplicantTray->MoveTo(2, 0);
fReplicantTray->ResizeBy(-2, 0);
BRect screenFrame = (BScreen(Window())).Frame();
statusLoc.x = screenFrame.right - fDragRegion->Bounds().Width();
statusLoc.y = 0;
}
}
fDragRegion->MoveTo(statusLoc);
fResizeControl->ResizeTo(gDragWidth, fDragRegion->Bounds().Height() - 2);
if (fVertical) {
fResizeControl->MoveTo(
fLeft ? fBarApp->Settings()->width - gDragWidth : 0, 1);
if (fResizeControl->IsHidden())
fResizeControl->Show();
} else {
if (!fResizeControl->IsHidden())
fResizeControl->Hide();
}
fDragRegion->Invalidate();
}
void
TBarView::PlaceApplicationBar()
{
BRect screenFrame = (BScreen(Window())).Frame();
if (fState == kMiniState) {
if (!fInlineScrollView->IsHidden())
fInlineScrollView->Hide();
SizeWindow(screenFrame);
PositionWindow(screenFrame);
Window()->UpdateIfNeeded();
if (!fVertical) {
fBarMenuBar->MoveTo(fLeft ? 0 : fDragRegion->Bounds().right + 1,
0);
}
Invalidate();
return;
}
if (fInlineScrollView->IsHidden())
fInlineScrollView->Show();
BRect expandoFrame(0, 0, 0, 0);
if (fVertical) {
expandoFrame.left = fDragRegion->Frame().left;
expandoFrame.top = fTrayLocation != 0 ? fDragRegion->Frame().bottom + 1
: fBarMenuBar->Frame().bottom + 1;
expandoFrame.right = fBarApp->Settings()->width;
expandoFrame.bottom = fState == kFullState ? screenFrame.bottom
: Frame().bottom;
} else {
expandoFrame.top = 0;
expandoFrame.bottom = TeamMenuItemHeight();
expandoFrame.left = screenFrame.left + fBarMenuBar->Frame().Width();
expandoFrame.right = screenFrame.right - fDragRegion->Frame().Width() - 1;
}
fInlineScrollView->DetachScrollers();
fInlineScrollView->MoveTo(expandoFrame.LeftTop());
fInlineScrollView->ResizeTo(expandoFrame.Width(), fVertical
? screenFrame.bottom - expandoFrame.top : expandoFrame.bottom);
fExpandoMenuBar->ResizeTo(expandoFrame.Width(), expandoFrame.Height());
fExpandoMenuBar->MoveTo(0, 0);
fExpandoMenuBar->BuildItems();
fExpandoMenuBar->SizeWindow(0);
}
void
TBarView::GetPreferredWindowSize(BRect screenFrame, float* width,
float* height)
{
float windowHeight = 0;
float windowWidth = 0;
bool setToHiddenSize = fBarApp->Settings()->autoHide && IsHidden()
&& !fDragRegion->IsDragging();
if (setToHiddenSize) {
windowHeight = kHiddenDimension;
if (fState == kExpandoState && !fVertical) {
windowWidth = screenFrame.Width();
} else
windowWidth = kHiddenDimension;
} else if (fVertical) {
if (fState == kFullState) {
windowHeight = std::max(screenFrame.bottom, windowHeight);
} else {
if (fTrayLocation != 0)
windowHeight = fDragRegion->Frame().bottom;
else
windowHeight = fBarMenuBar->Frame().bottom;
if (fState == kExpandoState && fExpandoMenuBar != NULL) {
windowHeight += fExpandoMenuBar->Bounds().Height();
}
}
windowWidth = fBarApp->Settings()->width;
} else {
if (fState == kMiniState) {
windowHeight = fBarMenuBar->Frame().Height();
windowWidth = fDragRegion->Frame().Width()
+ fBarMenuBar->Frame().Width() + 1;
} else {
windowHeight = std::max(TeamMenuItemHeight(),
kGutter + fReplicantTray->MaxReplicantHeight() + kGutter);
windowWidth = screenFrame.Width();
}
}
*width = windowWidth;
*height = windowHeight;
}
void
TBarView::SizeWindow(BRect screenFrame)
{
float windowWidth;
float windowHeight;
GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight);
Window()->ResizeTo(windowWidth, windowHeight);
ResizeTo(windowWidth, windowHeight);
}
void
TBarView::PositionWindow(BRect screenFrame)
{
float windowWidth;
float windowHeight;
GetPreferredWindowSize(screenFrame, &windowWidth, &windowHeight);
BPoint moveLoc(0, 0);
if (!fLeft && (fVertical || fState == kMiniState))
moveLoc.x = screenFrame.right - windowWidth;
if (!fTop)
moveLoc.y = screenFrame.bottom - windowHeight;
Window()->MoveTo(moveLoc);
}
void
TBarView::CheckForScrolling()
{
if (fInlineScrollView == NULL && fExpandoMenuBar == NULL)
return;
if (fExpandoMenuBar->CheckForSizeOverrun())
fInlineScrollView->AttachScrollers();
else
fInlineScrollView->DetachScrollers();
}
void
TBarView::SaveSettings()
{
desk_settings* settings = fBarApp->Settings();
settings->vertical = fVertical;
settings->left = fLeft;
settings->top = fTop;
settings->state = fState;
fReplicantTray->SaveTimeSettings();
}
void
TBarView::UpdatePlacement()
{
ChangeState(fState, fVertical, fLeft, fTop);
}
void
TBarView::ChangeState(int32 state, bool vertical, bool left, bool top,
bool async)
{
BMessage message(kUpdateOrientation);
message.AddInt32("state", state);
message.AddBool("vertical", vertical);
message.AddBool("left", left);
message.AddBool("top", top);
if (async)
BMessenger(this).SendMessage(&message);
else
_ChangeState(&message);
}
void
TBarView::_ChangeState(BMessage* message)
{
int32 state = message->FindInt32("state");
bool vertical = message->FindBool("vertical");
bool left = message->FindBool("left");
bool top = message->FindBool("top");
bool vertSwap = (fVertical != vertical);
bool leftSwap = (fLeft != left);
bool stateChanged = (fState != state);
fState = state;
fVertical = vertical;
fLeft = left;
fTop = top;
if (stateChanged || vertSwap) {
be_app->PostMessage(kStateChanged);
TBarWindow* barWindow = dynamic_cast<TBarWindow*>(Window());
if (barWindow != NULL)
barWindow->SetSizeLimits();
if (vertSwap && fExpandoMenuBar != NULL) {
if (fVertical) {
fInlineScrollView->SetOrientation(B_VERTICAL);
fExpandoMenuBar->SetMenuLayout(B_ITEMS_IN_COLUMN);
fExpandoMenuBar->StartMonitoringWindows();
} else {
fInlineScrollView->SetOrientation(B_HORIZONTAL);
fExpandoMenuBar->SetMenuLayout(B_ITEMS_IN_ROW);
fExpandoMenuBar->StopMonitoringWindows();
}
}
}
PlaceDeskbarMenu();
PlaceTray(vertSwap, leftSwap);
PlaceApplicationBar();
}
void
TBarView::RaiseDeskbar(bool raise)
{
fIsRaised = raise;
if (raise) {
Window()->SetFeel(B_FLOATING_ALL_WINDOW_FEEL);
Window()->SetFeel(B_NORMAL_WINDOW_FEEL);
} else
Window()->SendBehind(Window());
}
void
TBarView::HideDeskbar(bool hide)
{
BRect screenFrame = (BScreen(Window())).Frame();
if (hide) {
Hide();
if (fBarWindow != NULL)
fBarWindow->SetSizeLimits();
PositionWindow(screenFrame);
SizeWindow(screenFrame);
} else {
Show();
if (fBarWindow != NULL)
fBarWindow->SetSizeLimits();
SizeWindow(screenFrame);
PositionWindow(screenFrame);
}
}
void
TBarView::CacheDragData(const BMessage* incoming)
{
if (!incoming)
return;
if (Dragging() && SpringLoadedFolderCompareMessages(incoming, fDragMessage))
return;
SpringLoadedFolderCacheDragData(incoming, &fDragMessage, &fCachedTypesList);
}
static void
init_tracking_hook(BMenuItem* item,
bool (*hookFunction)(BMenu*, void*), void* state)
{
if (!item)
return;
BMenu* windowMenu = item->Submenu();
if (windowMenu) {
windowMenu->SetTrackingHook(hookFunction, state);
}
}
status_t
TBarView::DragStart()
{
if (!Dragging())
return B_OK;
BPoint loc;
uint32 buttons;
GetMouse(&loc, &buttons);
if (fExpandoMenuBar != NULL && fExpandoMenuBar->Frame().Contains(loc)) {
ConvertToScreen(&loc);
BPoint expandoLocation = fExpandoMenuBar->ConvertFromScreen(loc);
TTeamMenuItem* item = fExpandoMenuBar->TeamItemAtPoint(expandoLocation);
if (fLastDragItem)
init_tracking_hook(fLastDragItem, NULL, NULL);
if (item != NULL) {
if (item == fLastDragItem)
return B_OK;
fLastDragItem = item;
}
}
return B_OK;
}
bool
TBarView::MenuTrackingHook(BMenu* menu, void* castToThis)
{
TrackingHookData* data = static_cast<TrackingHookData*>(castToThis);
if (!data)
return false;
TBarView* barView = dynamic_cast<TBarView*>(data->fTarget.Target(NULL));
if (!barView || !menu->LockLooper())
return false;
uint32 buttons;
BPoint location;
menu->GetMouse(&location, &buttons);
bool endMenu = true;
BRect frame(menu->Bounds());
frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin);
if (frame.Contains(location)) {
endMenu = false;
} else {
menu->ConvertToScreen(&location);
if (barView->LockLooper()) {
TExpandoMenuBar* expandoMenuBar = barView->ExpandoMenuBar();
TBarWindow* barWindow
= dynamic_cast<TBarWindow*>(barView->Window());
TDeskbarMenu* deskbarMenu = barWindow->DeskbarMenu();
if (deskbarMenu && deskbarMenu->LockLooper()) {
deskbarMenu->ConvertFromScreen(&location);
if (deskbarMenu->Frame().Contains(location))
endMenu = false;
deskbarMenu->UnlockLooper();
}
if (endMenu && expandoMenuBar) {
expandoMenuBar->ConvertFromScreen(&location);
BMenuItem* item = expandoMenuBar->TeamItemAtPoint(location);
if (item)
endMenu = false;
}
barView->UnlockLooper();
}
}
menu->UnlockLooper();
return endMenu;
}
TrackingHookData*
TBarView::GetTrackingHookData()
{
return &fTrackingHookData;
}
void
TBarView::DragStop(bool full)
{
if (!Dragging())
return;
if (fExpandoMenuBar != NULL) {
if (fLastDragItem != NULL) {
init_tracking_hook(fLastDragItem, NULL, NULL);
fLastDragItem = NULL;
}
}
if (full) {
delete fDragMessage;
fDragMessage = NULL;
delete fCachedTypesList;
fCachedTypesList = NULL;
}
}
bool
TBarView::AppCanHandleTypes(const char* signature)
{
if (modifiers() & B_CONTROL_KEY) {
return true;
}
if (!signature || strlen(signature) == 0
|| !fCachedTypesList || fCachedTypesList->CountStrings() == 0)
return false;
if (strcasecmp(signature, kTrackerSignature) == 0) {
return true;
}
entry_ref hintref;
BMimeType appmime(signature);
if (appmime.GetAppHint(&hintref) != B_OK)
return false;
BFile file(&hintref, O_RDONLY);
BAppFileInfo fileinfo(&file);
int32 count = fCachedTypesList->CountStrings();
for (int32 i = 0 ; i < count ; i++) {
if (fileinfo.IsSupportedType(fCachedTypesList->StringAt(i).String()))
return true;
}
return false;
}
void
TBarView::SetDragOverride(bool on)
{
fRefsRcvdOnly = on;
}
bool
TBarView::DragOverride()
{
return fRefsRcvdOnly;
}
status_t
TBarView::SendDragMessage(const char* signature, entry_ref* ref)
{
status_t err = B_ERROR;
if (fDragMessage != NULL) {
if (fRefsRcvdOnly) {
fDragMessage->what = B_REFS_RECEIVED;
}
BRoster roster;
if (signature != NULL && *signature != '\0'
&& roster.IsRunning(signature)) {
BMessenger messenger(signature);
err = messenger.SendMessage(fDragMessage);
} else if (ref != NULL) {
FSLaunchItem((const entry_ref*)ref, (const BMessage*)fDragMessage,
true, true);
} else if (signature != NULL && *signature != '\0')
roster.Launch(signature, fDragMessage);
}
return err;
}
bool
TBarView::InvokeItem(const char* signature)
{
if (Dragging() && AppCanHandleTypes(signature)) {
SendDragMessage(signature);
DragStop(true);
return true;
}
return false;
}
void
TBarView::HandleDeskbarMenu(BMessage* messagewithdestination)
{
if (!Dragging())
return;
if (fVertical && fState != kExpandoState) {
if (fBarMenuBar->CountItems() >= 2) {
uint32 buttons;
BPoint location;
GetMouse(&location, &buttons);
if (fBarMenuBar->ItemAt(1)->Frame().Contains(location))
return;
}
}
if (messagewithdestination) {
entry_ref ref;
if (messagewithdestination->FindRef("refs", &ref) == B_OK) {
BEntry entry(&ref, true);
if (entry.IsDirectory()) {
AddRefsToDeskbarMenu(DragMessage(), &ref);
} else
SendDragMessage(NULL, &ref);
}
} else {
AddRefsToDeskbarMenu(DragMessage(), NULL);
}
DragStop(true);
}
status_t
TBarView::ItemInfo(int32 id, const char** name, DeskbarShelf* shelf)
{
*shelf = B_DESKBAR_TRAY;
return fReplicantTray->ItemInfo(id, name);
}
status_t
TBarView::ItemInfo(const char* name, int32* id, DeskbarShelf* shelf)
{
*shelf = B_DESKBAR_TRAY;
return fReplicantTray->ItemInfo(name, id);
}
bool
TBarView::ItemExists(int32 id, DeskbarShelf)
{
return fReplicantTray->IconExists(id);
}
bool
TBarView::ItemExists(const char* name, DeskbarShelf)
{
return fReplicantTray->IconExists(name);
}
int32
TBarView::CountItems(DeskbarShelf)
{
return fReplicantTray->ReplicantCount();
}
BSize
TBarView::MaxItemSize(DeskbarShelf shelf)
{
return BSize(fReplicantTray->MaxReplicantWidth(),
fReplicantTray->MaxReplicantHeight());
}
status_t
TBarView::AddItem(BMessage* item, DeskbarShelf, int32* id)
{
return fReplicantTray->AddIcon(item, id);
}
status_t
TBarView::AddItem(BEntry* entry, DeskbarShelf, int32* id)
{
return fReplicantTray->LoadAddOn(entry, id);
}
void
TBarView::RemoveItem(int32 id)
{
fReplicantTray->RemoveIcon(id);
}
void
TBarView::RemoveItem(const char* name, DeskbarShelf)
{
fReplicantTray->RemoveIcon(name);
}
BRect
TBarView::OffsetIconFrame(BRect rect) const
{
BRect frame(Frame());
frame.left += fDragRegion->Frame().left + fReplicantTray->Frame().left
+ rect.left;
frame.top += fDragRegion->Frame().top + fReplicantTray->Frame().top
+ rect.top;
frame.right = frame.left + rect.Width();
frame.bottom = frame.top + rect.Height();
return frame;
}
BRect
TBarView::IconFrame(int32 id) const
{
return OffsetIconFrame(fReplicantTray->IconFrame(id));
}
BRect
TBarView::IconFrame(const char* name) const
{
return OffsetIconFrame(fReplicantTray->IconFrame(name));
}
float
TBarView::TeamMenuItemHeight() const
{
const int32 iconSize = fBarApp->TeamIconSize();
const float iconPadding = be_control_look->ComposeSpacing(kIconPadding);
float iconOnlyHeight = iconSize + iconPadding / 2;
const int32 large = be_control_look->ComposeIconSize(B_LARGE_ICON)
.IntegerWidth() + 1;
font_height fontHeight;
if (fExpandoMenuBar != NULL)
fExpandoMenuBar->GetFontHeight(&fontHeight);
else
GetFontHeight(&fontHeight);
float labelHeight = fontHeight.ascent + fontHeight.descent;
labelHeight = labelHeight < kMinTeamItemHeight ? kMinTeamItemHeight
: ceilf(labelHeight * 1.1f);
if (fBarApp->Settings()->hideLabels && iconSize > B_MINI_ICON) {
return iconOnlyHeight;
} else if (!fVertical || (fVertical && iconSize <= large)) {
return std::max(iconOnlyHeight, labelHeight);
} else if (fVertical && iconSize > large) {
return ceilf(iconOnlyHeight + labelHeight);
} else {
return labelHeight;
}
}