141281cf3SAxel Dörfler /*
241281cf3SAxel Dörfler Open Tracker License
341281cf3SAxel Dörfler
441281cf3SAxel Dörfler Terms and Conditions
541281cf3SAxel Dörfler
641281cf3SAxel Dörfler Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
741281cf3SAxel Dörfler
841281cf3SAxel Dörfler Permission is hereby granted, free of charge, to any person obtaining a copy of
941281cf3SAxel Dörfler this software and associated documentation files (the "Software"), to deal in
1041281cf3SAxel Dörfler the Software without restriction, including without limitation the rights to
1141281cf3SAxel Dörfler use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1241281cf3SAxel Dörfler of the Software, and to permit persons to whom the Software is furnished to do
1341281cf3SAxel Dörfler so, subject to the following conditions:
1441281cf3SAxel Dörfler
1541281cf3SAxel Dörfler The above copyright notice and this permission notice applies to all licensees
1641281cf3SAxel Dörfler and shall be included in all copies or substantial portions of the Software.
1741281cf3SAxel Dörfler
1841281cf3SAxel Dörfler THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1941281cf3SAxel Dörfler IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
2041281cf3SAxel Dörfler FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2141281cf3SAxel Dörfler BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2241281cf3SAxel Dörfler AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
2341281cf3SAxel Dörfler WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2441281cf3SAxel Dörfler
2541281cf3SAxel Dörfler Except as contained in this notice, the name of Be Incorporated shall not be
2641281cf3SAxel Dörfler used in advertising or otherwise to promote the sale, use or other dealings in
2741281cf3SAxel Dörfler this Software without prior written authorization from Be Incorporated.
2841281cf3SAxel Dörfler
294ec67d2bSFredrik Holmqvist Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
304ec67d2bSFredrik Holmqvist trademarks of Be Incorporated in the United States and other countries. Other
314ec67d2bSFredrik Holmqvist brand product names are registered trademarks or trademarks of their respective
324ec67d2bSFredrik Holmqvist holders.
3341281cf3SAxel Dörfler All rights reserved.
3441281cf3SAxel Dörfler */
3541281cf3SAxel Dörfler
361cf94bf9SStephan Aßmus
371cf94bf9SStephan Aßmus #include "BarMenuBar.h"
381cf94bf9SStephan Aßmus
39419bc0a2SAxel Dörfler #include <algorithm>
40419bc0a2SAxel Dörfler
4141281cf3SAxel Dörfler #include <Bitmap.h>
424ae3e542SJohn Scipione #include <ControlLook.h>
431cd61330SJohn Scipione #include <Debug.h>
44419bc0a2SAxel Dörfler #include <IconUtils.h>
4541281cf3SAxel Dörfler #include <NodeInfo.h>
4641281cf3SAxel Dörfler
4741281cf3SAxel Dörfler #include "icons.h"
48615d572dSJohn Scipione
494ae3e542SJohn Scipione #include "BarMenuTitle.h"
504ae3e542SJohn Scipione #include "BarView.h"
5141281cf3SAxel Dörfler #include "BarWindow.h"
52323b6546SOliver Tappe #include "DeskbarMenu.h"
53323b6546SOliver Tappe #include "DeskbarUtils.h"
5441281cf3SAxel Dörfler #include "ResourceSet.h"
550d2645e4SJohn Scipione #include "StatusView.h"
5641281cf3SAxel Dörfler #include "TeamMenu.h"
5741281cf3SAxel Dörfler
5841281cf3SAxel Dörfler
59c07e6ff2SJohn Scipione const float kSepItemWidth = 5.0f;
60c07e6ff2SJohn Scipione
610d2645e4SJohn Scipione const float kTeamIconBitmapHeight = 19.f;
620d2645e4SJohn Scipione
634ae3e542SJohn Scipione
644ae3e542SJohn Scipione // #pragma mark - TSeparatorItem
654ae3e542SJohn Scipione
664ae3e542SJohn Scipione
TSeparatorItem()674ae3e542SJohn Scipione TSeparatorItem::TSeparatorItem()
684ae3e542SJohn Scipione :
694ae3e542SJohn Scipione BSeparatorItem()
704ae3e542SJohn Scipione {
714ae3e542SJohn Scipione }
724ae3e542SJohn Scipione
734ae3e542SJohn Scipione
744ae3e542SJohn Scipione void
Draw()754ae3e542SJohn Scipione TSeparatorItem::Draw()
764ae3e542SJohn Scipione {
774ae3e542SJohn Scipione BMenu* menu = Menu();
784ae3e542SJohn Scipione if (menu == NULL)
794ae3e542SJohn Scipione return;
804ae3e542SJohn Scipione
814ae3e542SJohn Scipione BRect frame(Frame());
824ae3e542SJohn Scipione frame.right = frame.left + kSepItemWidth;
8316c10517Slooncraz rgb_color base = ui_color(B_MENU_BACKGROUND_COLOR);
844ae3e542SJohn Scipione
854ae3e542SJohn Scipione menu->PushState();
864ae3e542SJohn Scipione
874ae3e542SJohn Scipione menu->SetHighColor(tint_color(base, 1.22));
884ae3e542SJohn Scipione frame.top--;
894ae3e542SJohn Scipione // need to expand the frame for some reason
904ae3e542SJohn Scipione
914ae3e542SJohn Scipione // stroke a darker line on the left edge
924ae3e542SJohn Scipione menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
934ae3e542SJohn Scipione frame.left++;
944ae3e542SJohn Scipione
954ae3e542SJohn Scipione // fill in background
964ae3e542SJohn Scipione be_control_look->DrawButtonBackground(menu, frame, frame, base);
974ae3e542SJohn Scipione
984ae3e542SJohn Scipione menu->PopState();
994ae3e542SJohn Scipione }
1004ae3e542SJohn Scipione
1014ae3e542SJohn Scipione
1024ae3e542SJohn Scipione // #pragma mark - TBarMenuBar
1034ae3e542SJohn Scipione
1044ae3e542SJohn Scipione
TBarMenuBar(BRect frame,const char * name,TBarView * barView)1054ae3e542SJohn Scipione TBarMenuBar::TBarMenuBar(BRect frame, const char* name, TBarView* barView)
1064ae3e542SJohn Scipione :
1074ae3e542SJohn Scipione BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false),
1084ae3e542SJohn Scipione fBarView(barView),
1096c54ebe5SJohn Scipione fAppListMenuItem(NULL),
1100d2645e4SJohn Scipione fSeparatorItem(NULL),
1110d2645e4SJohn Scipione fTeamIconData(NULL),
1120d2645e4SJohn Scipione fTeamIconSize(0)
11341281cf3SAxel Dörfler {
11441281cf3SAxel Dörfler SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f);
115863bf67dSJohn Scipione SetFont(be_bold_font);
11641281cf3SAxel Dörfler
1174ae3e542SJohn Scipione TDeskbarMenu* beMenu = new TDeskbarMenu(barView);
118323b6546SOliver Tappe TBarWindow::SetDeskbarMenu(beMenu);
11941281cf3SAxel Dörfler
120419bc0a2SAxel Dörfler BBitmap* icon = NULL;
121419bc0a2SAxel Dörfler size_t dataSize;
122419bc0a2SAxel Dörfler const void* data = AppResSet()->FindResource(B_VECTOR_ICON_TYPE,
123419bc0a2SAxel Dörfler R_LeafLogoBitmap, &dataSize);
124419bc0a2SAxel Dörfler if (data != NULL) {
125863bf67dSJohn Scipione // seems valid, scale bitmap according to be_bold_font size
126863bf67dSJohn Scipione float width = std::max(63.f, ceilf(63 * be_bold_font->Size() / 12.f));
127863bf67dSJohn Scipione float height = std::max(22.f, ceilf(22 * be_bold_font->Size() / 12.f));
128419bc0a2SAxel Dörfler icon = new BBitmap(BRect(0, 0, width - 1, height - 1), B_RGBA32);
129419bc0a2SAxel Dörfler if (icon->InitCheck() != B_OK
130419bc0a2SAxel Dörfler || BIconUtils::GetVectorIcon((const uint8*)data, dataSize, icon)
131419bc0a2SAxel Dörfler != B_OK) {
132419bc0a2SAxel Dörfler delete icon;
133419bc0a2SAxel Dörfler icon = NULL;
134419bc0a2SAxel Dörfler }
135419bc0a2SAxel Dörfler }
136419bc0a2SAxel Dörfler
1370d2645e4SJohn Scipione fDeskbarMenuItem = new TBarMenuTitle(0.0f, 0.0f, icon, beMenu, fBarView);
138323b6546SOliver Tappe AddItem(fDeskbarMenuItem);
13941281cf3SAxel Dörfler }
14041281cf3SAxel Dörfler
14141281cf3SAxel Dörfler
~TBarMenuBar()14241281cf3SAxel Dörfler TBarMenuBar::~TBarMenuBar()
14341281cf3SAxel Dörfler {
14441281cf3SAxel Dörfler }
14541281cf3SAxel Dörfler
14641281cf3SAxel Dörfler
14741281cf3SAxel Dörfler void
SmartResize(float width,float height)14841281cf3SAxel Dörfler TBarMenuBar::SmartResize(float width, float height)
14941281cf3SAxel Dörfler {
1507da06231SAxel Dörfler if (width == -1.0f && height == -1.0f) {
15141281cf3SAxel Dörfler BRect frame = Frame();
15241281cf3SAxel Dörfler width = frame.Width();
15341281cf3SAxel Dörfler height = frame.Height();
15441281cf3SAxel Dörfler } else
15541281cf3SAxel Dörfler ResizeTo(width, height);
15641281cf3SAxel Dörfler
1570f10682fSJohn Scipione if (fSeparatorItem != NULL)
15803f7c11eSJohn Scipione fDeskbarMenuItem->SetContentSize(width - kSepItemWidth, height);
159c07e6ff2SJohn Scipione else {
16041281cf3SAxel Dörfler int32 count = CountItems();
161b5c9fb39SJohn Scipione if (fDeskbarMenuItem != NULL)
162b5c9fb39SJohn Scipione fDeskbarMenuItem->SetContentSize(floorf(width / count), height);
163b5c9fb39SJohn Scipione if (fAppListMenuItem != NULL)
164b5c9fb39SJohn Scipione fAppListMenuItem->SetContentSize(floorf(width / count), height);
165c07e6ff2SJohn Scipione }
16641281cf3SAxel Dörfler
16741281cf3SAxel Dörfler InvalidateLayout();
16841281cf3SAxel Dörfler }
16941281cf3SAxel Dörfler
17041281cf3SAxel Dörfler
171fc18a4f5SJohn Scipione bool
AddTeamMenu()17241281cf3SAxel Dörfler TBarMenuBar::AddTeamMenu()
17341281cf3SAxel Dörfler {
17441281cf3SAxel Dörfler if (CountItems() > 1)
175fc18a4f5SJohn Scipione return false;
17641281cf3SAxel Dörfler
17741281cf3SAxel Dörfler BRect frame(Frame());
17841281cf3SAxel Dörfler
179cb7c5f05SJohn Scipione delete fAppListMenuItem;
1800d2645e4SJohn Scipione fAppListMenuItem = new TBarMenuTitle(0.0f, 0.0f, FetchTeamIcon(),
1810d2645e4SJohn Scipione new TTeamMenu(fBarView), fBarView);
182cb7c5f05SJohn Scipione
1830d2645e4SJohn Scipione bool added = AddItem(fAppListMenuItem, fBarView->Left() ? 0 : 1);
184fc18a4f5SJohn Scipione
185fc18a4f5SJohn Scipione if (added)
18641281cf3SAxel Dörfler SmartResize(frame.Width() - 1.0f, frame.Height());
187fc18a4f5SJohn Scipione else
18811f46c6dSJohn Scipione SmartResize(frame.Width(), frame.Height());
189fc18a4f5SJohn Scipione
190fc18a4f5SJohn Scipione return added;
19141281cf3SAxel Dörfler }
19241281cf3SAxel Dörfler
19341281cf3SAxel Dörfler
194fc18a4f5SJohn Scipione bool
RemoveTeamMenu()19541281cf3SAxel Dörfler TBarMenuBar::RemoveTeamMenu()
19641281cf3SAxel Dörfler {
19741281cf3SAxel Dörfler if (CountItems() < 2)
198fc18a4f5SJohn Scipione return false;
199fc18a4f5SJohn Scipione
200fc18a4f5SJohn Scipione bool removed = false;
20141281cf3SAxel Dörfler
20208282eb4SJohn Scipione if (fAppListMenuItem != NULL && RemoveItem(fAppListMenuItem)) {
20341281cf3SAxel Dörfler delete fAppListMenuItem;
20441281cf3SAxel Dörfler fAppListMenuItem = NULL;
20511f46c6dSJohn Scipione SmartResize(-1, -1);
206fc18a4f5SJohn Scipione removed = true;
20741281cf3SAxel Dörfler }
208fc18a4f5SJohn Scipione
209fc18a4f5SJohn Scipione return removed;
21041281cf3SAxel Dörfler }
21141281cf3SAxel Dörfler
21241281cf3SAxel Dörfler
213fc18a4f5SJohn Scipione bool
AddSeparatorItem()2144ae3e542SJohn Scipione TBarMenuBar::AddSeparatorItem()
215c07e6ff2SJohn Scipione {
216c07e6ff2SJohn Scipione if (CountItems() > 1)
217fc18a4f5SJohn Scipione return false;
218c07e6ff2SJohn Scipione
219c07e6ff2SJohn Scipione BRect frame(Frame());
220c07e6ff2SJohn Scipione
221cb7c5f05SJohn Scipione delete fSeparatorItem;
2224ae3e542SJohn Scipione fSeparatorItem = new TSeparatorItem();
223cb7c5f05SJohn Scipione
224fc18a4f5SJohn Scipione bool added = AddItem(fSeparatorItem);
225fc18a4f5SJohn Scipione
226fc18a4f5SJohn Scipione if (added)
227c07e6ff2SJohn Scipione SmartResize(frame.Width() - 1.0f, frame.Height());
22811f46c6dSJohn Scipione else
22911f46c6dSJohn Scipione SmartResize(frame.Width(), frame.Height());
230fc18a4f5SJohn Scipione
231fc18a4f5SJohn Scipione return added;
232c07e6ff2SJohn Scipione }
233c07e6ff2SJohn Scipione
234c07e6ff2SJohn Scipione
235fc18a4f5SJohn Scipione bool
RemoveSeperatorItem()236c07e6ff2SJohn Scipione TBarMenuBar::RemoveSeperatorItem()
237c07e6ff2SJohn Scipione {
238c07e6ff2SJohn Scipione if (CountItems() < 2)
239fc18a4f5SJohn Scipione return false;
240fc18a4f5SJohn Scipione
241fc18a4f5SJohn Scipione bool removed = false;
242c07e6ff2SJohn Scipione
24308282eb4SJohn Scipione if (fSeparatorItem != NULL && RemoveItem(fSeparatorItem)) {
244c07e6ff2SJohn Scipione delete fSeparatorItem;
245c07e6ff2SJohn Scipione fSeparatorItem = NULL;
24611f46c6dSJohn Scipione SmartResize(-1, -1);
247fc18a4f5SJohn Scipione removed = true;
248c07e6ff2SJohn Scipione }
249fc18a4f5SJohn Scipione
250fc18a4f5SJohn Scipione return removed;
251c07e6ff2SJohn Scipione }
252c07e6ff2SJohn Scipione
253c07e6ff2SJohn Scipione
254c07e6ff2SJohn Scipione void
Draw(BRect updateRect)255d6f6b835SJohn Scipione TBarMenuBar::Draw(BRect updateRect)
25641281cf3SAxel Dörfler {
2574ae3e542SJohn Scipione // skip the fancy BMenuBar drawing code
258d6f6b835SJohn Scipione BMenu::Draw(updateRect);
25941281cf3SAxel Dörfler }
26041281cf3SAxel Dörfler
26141281cf3SAxel Dörfler
26241281cf3SAxel Dörfler void
DrawBackground(BRect updateRect)263d6f6b835SJohn Scipione TBarMenuBar::DrawBackground(BRect updateRect)
26441281cf3SAxel Dörfler {
265d6f6b835SJohn Scipione BMenu::DrawBackground(updateRect);
26641281cf3SAxel Dörfler }
26741281cf3SAxel Dörfler
26841281cf3SAxel Dörfler
26941281cf3SAxel Dörfler void
MouseMoved(BPoint where,uint32 code,const BMessage * message)27041281cf3SAxel Dörfler TBarMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
27141281cf3SAxel Dörfler {
2727da06231SAxel Dörfler // the following code parallels that in ExpandoMenuBar for DnD tracking
2737da06231SAxel Dörfler
27441281cf3SAxel Dörfler if (!message) {
27541281cf3SAxel Dörfler // force a cleanup
27641281cf3SAxel Dörfler fBarView->DragStop(true);
27741281cf3SAxel Dörfler BMenuBar::MouseMoved(where, code, message);
27841281cf3SAxel Dörfler return;
27941281cf3SAxel Dörfler }
28041281cf3SAxel Dörfler
28141281cf3SAxel Dörfler switch (code) {
28241281cf3SAxel Dörfler case B_ENTERED_VIEW:
28341281cf3SAxel Dörfler {
28441281cf3SAxel Dörfler BPoint loc;
28541281cf3SAxel Dörfler uint32 buttons;
28641281cf3SAxel Dörfler GetMouse(&loc, &buttons);
287fe624b39SJohn Scipione if (message != NULL && buttons != 0) {
2887da06231SAxel Dörfler // attempt to start DnD tracking
28941281cf3SAxel Dörfler fBarView->CacheDragData(const_cast<BMessage*>(message));
29041281cf3SAxel Dörfler MouseDown(loc);
29141281cf3SAxel Dörfler }
29241281cf3SAxel Dörfler break;
29341281cf3SAxel Dörfler }
2947da06231SAxel Dörfler }
295fe624b39SJohn Scipione
29641281cf3SAxel Dörfler BMenuBar::MouseMoved(where, code, message);
29741281cf3SAxel Dörfler }
29841281cf3SAxel Dörfler
29941281cf3SAxel Dörfler
30041281cf3SAxel Dörfler static void
init_tracking_hook(BMenuItem * item,bool (* hookFunction)(BMenu *,void *),void * state)3017da06231SAxel Dörfler init_tracking_hook(BMenuItem* item, bool (*hookFunction)(BMenu*, void*),
3027da06231SAxel Dörfler void* state)
30341281cf3SAxel Dörfler {
30441281cf3SAxel Dörfler if (!item)
30541281cf3SAxel Dörfler return;
30641281cf3SAxel Dörfler
3077da06231SAxel Dörfler BMenu* windowMenu = item->Submenu();
3084ec67d2bSFredrik Holmqvist if (windowMenu) {
30941281cf3SAxel Dörfler // have a menu, set the tracking hook
3107da06231SAxel Dörfler windowMenu->SetTrackingHook(hookFunction, state);
31141281cf3SAxel Dörfler }
3124ec67d2bSFredrik Holmqvist }
31341281cf3SAxel Dörfler
31441281cf3SAxel Dörfler
31541281cf3SAxel Dörfler void
InitTrackingHook(bool (* hookFunction)(BMenu *,void *),void * state,bool both)3167da06231SAxel Dörfler TBarMenuBar::InitTrackingHook(bool (*hookFunction)(BMenu*, void*),
3177da06231SAxel Dörfler void* state, bool both)
31841281cf3SAxel Dörfler {
31941281cf3SAxel Dörfler BPoint loc;
32041281cf3SAxel Dörfler uint32 buttons;
32141281cf3SAxel Dörfler GetMouse(&loc, &buttons);
32241281cf3SAxel Dörfler // set the hook functions for the two menus
323323b6546SOliver Tappe // will always have the deskbar menu
32441281cf3SAxel Dörfler // may have the app menu as well (mini mode)
325323b6546SOliver Tappe if (fDeskbarMenuItem->Frame().Contains(loc) || both)
326323b6546SOliver Tappe init_tracking_hook(fDeskbarMenuItem, hookFunction, state);
32741281cf3SAxel Dörfler
32841281cf3SAxel Dörfler if (fAppListMenuItem && (fAppListMenuItem->Frame().Contains(loc) || both))
3297da06231SAxel Dörfler init_tracking_hook(fAppListMenuItem, hookFunction, state);
33041281cf3SAxel Dörfler }
3310d2645e4SJohn Scipione
3320d2645e4SJohn Scipione
3330d2645e4SJohn Scipione const BBitmap*
FetchTeamIcon()3340d2645e4SJohn Scipione TBarMenuBar::FetchTeamIcon()
3350d2645e4SJohn Scipione {
3360d2645e4SJohn Scipione const BBitmap* teamIcon = NULL;
3370d2645e4SJohn Scipione
3380d2645e4SJohn Scipione if (fTeamIconData == NULL || fTeamIconSize == 0) {
3390d2645e4SJohn Scipione // we haven't fetched vector icon data yet, fetch it
3400d2645e4SJohn Scipione fTeamIconData = (const uint8*)AppResSet()->FindResource(
341*fb885767SJohn Scipione B_VECTOR_ICON_TYPE, R_TeamIcon, &fTeamIconSize);
3420d2645e4SJohn Scipione }
3430d2645e4SJohn Scipione
3440d2645e4SJohn Scipione if (fTeamIconData != NULL && fTeamIconSize > 0) {
345863bf67dSJohn Scipione // seems valid, scale bitmap according to be_bold_font size
3460d2645e4SJohn Scipione float iconHeight = std::max(kTeamIconBitmapHeight,
3470d2645e4SJohn Scipione ceilf(kTeamIconBitmapHeight * be_bold_font->Size() / 12.f));
3480d2645e4SJohn Scipione BRect iconRect = BRect(0, 0, iconHeight, iconHeight);
3490d2645e4SJohn Scipione iconRect.InsetBy(-1, -1);
3500d2645e4SJohn Scipione // grow icon by 1px so that it renders nicely at 12pt font size
3510d2645e4SJohn Scipione BBitmap* icon = new(std::nothrow) BBitmap(iconRect, B_RGBA32);
352*fb885767SJohn Scipione if (icon != NULL && icon->InitCheck() == B_OK
353*fb885767SJohn Scipione && BIconUtils::GetVectorIcon(fTeamIconData, fTeamIconSize, icon)
354*fb885767SJohn Scipione == B_OK) {
3550d2645e4SJohn Scipione // rasterize vector icon into a bitmap at the scaled size
3560d2645e4SJohn Scipione teamIcon = icon;
357*fb885767SJohn Scipione } else if (icon != NULL)
358*fb885767SJohn Scipione delete icon;
3590d2645e4SJohn Scipione }
3600d2645e4SJohn Scipione
3610d2645e4SJohn Scipione return teamIcon;
3620d2645e4SJohn Scipione }
363