Animate the expander arrow

On MouseDown draw a diagonal arrow, on MouseUp complete the animation and
expand. If you hold down the button it will stay diagonal until you MouseUp
and either return to normal or animate and expand if over the arrow.

Reformatted ExpandoMenuBar.h and TeamMenuItem.h
Renamed fLastClickItem to fLastClickedItem
Added a DrawExpanderArrow() method
Renamed private InitData() method to _InitData() and moved it to the bottom
This commit is contained in:
John Scipione
2013-04-07 03:02:05 -04:00
parent 1b41173c8a
commit 5b0fd10d23
4 changed files with 283 additions and 295 deletions
+90 -27
View File
@@ -88,7 +88,8 @@ TExpandoMenuBar::TExpandoMenuBar(BRect frame, const char* name, bool vertical)
fDeskbarMenuWidth(kMinMenuItemWidth), fDeskbarMenuWidth(kMinMenuItemWidth),
fBarView(NULL), fBarView(NULL),
fPreviousDragTargetItem(NULL), fPreviousDragTargetItem(NULL),
fLastClickItem(NULL) fLastClickedItem(NULL),
fClickedExpander(false)
{ {
SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f); SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f);
SetFont(be_plain_font); SetFont(be_plain_font);
@@ -282,6 +283,9 @@ TExpandoMenuBar::MessageReceived(BMessage* message)
void void
TExpandoMenuBar::MouseDown(BPoint where) TExpandoMenuBar::MouseDown(BPoint where)
{ {
fClickedExpander = false;
// in case MouseUp() wasn't called
BMessage* message = Window()->CurrentMessage(); BMessage* message = Window()->CurrentMessage();
BMenuItem* menuItem; BMenuItem* menuItem;
TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem);
@@ -322,30 +326,31 @@ TExpandoMenuBar::MouseDown(BPoint where)
// absorb the message // absorb the message
} }
// Check the bounds of the expand Team icon int32 buttons = 0;
if (fVertical && fShowTeamExpander) { // check if within expander bounds to expand window items
if (item->ExpanderBounds().Contains(where)) { if (fVertical && fShowTeamExpander
BAutolock locker(sMonLocker); && item->ExpanderBounds().Contains(where)
// let the update thread wait... && message->FindInt32("buttons", &buttons) == B_OK
item->ToggleExpandState(true); && buttons == B_PRIMARY_MOUSE_BUTTON) {
// toggle the item // start the animation here, finish on mouse up
item->Draw(); fLastClickedItem = item;
return; fClickedExpander = true;
// absorb the message item->DrawExpanderArrow(BControlLook::B_RIGHT_DOWN_ARROW);
} return;
// absorb the message
} }
// double-click on an item brings the team to front // double-click on an item brings the team to front
int32 clicks; int32 clicks;
if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1 if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1
&& item == menuItem && item == fLastClickItem) { && item == menuItem && item == fLastClickedItem) {
be_roster->ActivateApp((addr_t)item->Teams()->ItemAt(0)); be_roster->ActivateApp((addr_t)item->Teams()->ItemAt(0));
// activate this team // activate this team
return; return;
// absorb the message // absorb the message
} }
fLastClickItem = item; fLastClickedItem = item;
BMenuBar::MouseDown(where); BMenuBar::MouseDown(where);
} }
@@ -353,18 +358,39 @@ TExpandoMenuBar::MouseDown(BPoint where)
void void
TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
{ {
int32 buttons;
BMessage* currentMessage = Window()->CurrentMessage();
if (currentMessage == NULL
|| currentMessage->FindInt32("buttons", &buttons) != B_OK) {
buttons = 0;
}
if (message == NULL) { if (message == NULL) {
// force a cleanup // force a cleanup
_FinishedDrag(); _FinishedDrag();
switch (code) { switch (code) {
case B_ENTERED_VIEW: case B_ENTERED_VIEW:
{
TTeamMenuItem* lastItem
= dynamic_cast<TTeamMenuItem*>(fLastClickedItem);
if (fVertical && fShowTeamExpander && fClickedExpander
&& lastItem != NULL && buttons == B_PRIMARY_MOUSE_BUTTON) {
// Started expander animation, exited view then entered
// again, redraw the expanded arrow
int32 arrowDirection = BControlLook::B_RIGHT_DOWN_ARROW;
lastItem->DrawExpanderArrow(arrowDirection);
}
break;
}
case B_INSIDE_VIEW: case B_INSIDE_VIEW:
{ {
BMenuItem* menuItem; BMenuItem* menuItem;
TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem);
TWindowMenuItem* windowMenuItem TWindowMenuItem* windowMenuItem
= dynamic_cast<TWindowMenuItem*>(menuItem); = dynamic_cast<TWindowMenuItem*>(menuItem);
if (item == NULL || menuItem == NULL) { if (item == NULL || menuItem == NULL) {
// item is NULL, remove the tooltip and break out // item is NULL, remove the tooltip and break out
fLastMousedOverItem = NULL; fLastMousedOverItem = NULL;
@@ -405,19 +431,32 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
break; break;
} }
case B_OUTSIDE_VIEW:
// NOTE: Should not be here, but for the sake of defensive
// programming... fall-through
case B_EXITED_VIEW:
{
TTeamMenuItem* lastItem
= dynamic_cast<TTeamMenuItem*>(fLastClickedItem);
if (fVertical && fShowTeamExpander && fClickedExpander
&& lastItem != NULL) {
// Started expander animation, then exited view,
// since we can't track outside mouse movements
// redraw the original expander arrow
int32 arrowDirection = lastItem->IsExpanded()
? BControlLook::B_DOWN_ARROW
: BControlLook::B_RIGHT_ARROW;
lastItem->DrawExpanderArrow(arrowDirection);
}
break;
}
} }
BMenuBar::MouseMoved(where, code, message); BMenuBar::MouseMoved(where, code, message);
return; return;
} }
uint32 buttons;
if (Window()->CurrentMessage() == NULL
|| Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons)
< B_OK) {
buttons = 0;
}
if (buttons == 0) if (buttons == 0)
return; return;
@@ -433,7 +472,7 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
case B_OUTSIDE_VIEW: case B_OUTSIDE_VIEW:
// NOTE: Should not be here, but for the sake of defensive // NOTE: Should not be here, but for the sake of defensive
// programming... // programming... fall-through
case B_EXITED_VIEW: case B_EXITED_VIEW:
_FinishedDrag(); _FinishedDrag();
break; break;
@@ -465,12 +504,36 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
void void
TExpandoMenuBar::MouseUp(BPoint where) TExpandoMenuBar::MouseUp(BPoint where)
{ {
if (!fBarView->Dragging()) { bool clickedExpander = fClickedExpander;
BMenuBar::MouseUp(where); fClickedExpander = false;
if (fBarView->Dragging()) {
_FinishedDrag(true);
return; return;
// absorb the message
} }
_FinishedDrag(true); TTeamMenuItem* item = TeamItemAtPoint(where, NULL);
TTeamMenuItem* lastItem = dynamic_cast<TTeamMenuItem*>(fLastClickedItem);
if (fVertical && fShowTeamExpander && clickedExpander) {
if (item != NULL && lastItem != NULL && item == lastItem
&& item->ExpanderBounds().Contains(where)) {
// Toggle the expanded state
BAutolock locker(sMonLocker);
// let the update thread wait...
item->ToggleExpandState(true);
item->Draw();
return;
// absorb the message
} else if (lastItem != NULL) {
// User changed their mind, redraw the original expander arrow
int32 arrowDirection = lastItem->IsExpanded()
? BControlLook::B_DOWN_ARROW : BControlLook::B_RIGHT_ARROW;
lastItem->DrawExpanderArrow(arrowDirection);
}
}
BMenuBar::MouseUp(where);
} }
@@ -677,8 +740,8 @@ TExpandoMenuBar::RemoveTeam(team_id team, bool partial)
return; return;
#ifdef DOUBLECLICKBRINGSTOFRONT #ifdef DOUBLECLICKBRINGSTOFRONT
if (fLastClickItem == i) if (fLastClickedItem == i)
fLastClickItem = -1; fLastClickedItem = -1;
#endif #endif
BAutolock locker(sMonLocker); BAutolock locker(sMonLocker);
+46 -43
View File
@@ -60,64 +60,67 @@ enum drag_and_drop_selection {
}; };
class TExpandoMenuBar : public BMenuBar { class TExpandoMenuBar : public BMenuBar {
public: public:
TExpandoMenuBar(BRect frame, const char* name, bool vertical); TExpandoMenuBar(BRect frame, const char* name,
bool vertical);
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
virtual void Draw(BRect update); virtual void Draw(BRect update);
virtual void DrawBackground(BRect update); virtual void DrawBackground(BRect update);
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual void MouseDown(BPoint where); virtual void MouseDown(BPoint where);
virtual void MouseMoved(BPoint where, uint32 code, const BMessage*); virtual void MouseMoved(BPoint where, uint32 code,
virtual void MouseUp(BPoint where); const BMessage* message);
virtual void MouseUp(BPoint where);
void BuildItems(); void BuildItems();
TTeamMenuItem* TeamItemAtPoint(BPoint location, TTeamMenuItem* TeamItemAtPoint(BPoint location,
BMenuItem** _item = NULL); BMenuItem** _item = NULL);
bool InDeskbarMenu(BPoint) const; bool InDeskbarMenu(BPoint) const;
void CheckItemSizes(int32 delta); void CheckItemSizes(int32 delta);
menu_layout MenuLayout() const; menu_layout MenuLayout() const;
void SizeWindow(int32 delta); void SizeWindow(int32 delta);
bool CheckForSizeOverrun(); bool CheckForSizeOverrun();
private: private:
static int CompareByName(const void* first, const void* second); static int CompareByName(const void* first,
static int32 monitor_team_windows(void* arg); const void* second);
static int32 monitor_team_windows(void* arg);
void AddTeam(BList* team, BBitmap* icon, char* name, char* signature); void AddTeam(BList* team, BBitmap* icon, char* name,
void AddTeam(team_id team, const char* signature); char* signature);
void RemoveTeam(team_id team, bool partial); void AddTeam(team_id team, const char* signature);
void RemoveTeam(team_id team, bool partial);
void _FinishedDrag(bool invoke = false); void _FinishedDrag(bool invoke = false);
bool fVertical : 1; private:
bool fOverflow : 1; bool fVertical : 1;
bool fDrawLabel : 1; bool fOverflow : 1;
bool fShowTeamExpander : 1; bool fDrawLabel : 1;
bool fExpandNewTeams : 1; bool fShowTeamExpander : 1;
bool fExpandNewTeams : 1;
float fDeskbarMenuWidth; float fDeskbarMenuWidth;
TBarView* fBarView;
TTeamMenuItem* fPreviousDragTargetItem;
BMenuItem* fLastMousedOverItem;
BMenuItem* fLastClickedItem;
bool fClickedExpander;
BList fTeamList;
TBarView* fBarView; static bool sDoMonitor;
static thread_id sMonThread;
TTeamMenuItem* fPreviousDragTargetItem; static BLocker sMonLocker;
BMenuItem* fLastMousedOverItem;
BMenuItem* fLastClickItem;
BList fTeamList;
static bool sDoMonitor;
static thread_id sMonThread;
static BLocker sMonLocker;
}; };
#endif /* EXPANDO_MENU_BAR_H */ #endif // EXPANDO_MENU_BAR_H
+94 -179
View File
@@ -68,52 +68,18 @@ TTeamMenuItem::TTeamMenuItem(BList* team, BBitmap* icon, char* name, char* sig,
float width, float height, bool drawLabel, bool vertical) float width, float height, bool drawLabel, bool vertical)
: BMenuItem(new TWindowMenu(team, sig)) : BMenuItem(new TWindowMenu(team, sig))
{ {
InitData(team, icon, name, sig, width, height, drawLabel, vertical); _InitData(team, icon, name, sig, width, height, drawLabel, vertical);
} }
TTeamMenuItem::TTeamMenuItem(float width, float height, bool vertical) TTeamMenuItem::TTeamMenuItem(float width, float height, bool vertical)
: BMenuItem("", NULL) : BMenuItem("", NULL)
{ {
InitData(NULL, NULL, strdup(""), strdup(""), width, height, false, _InitData(NULL, NULL, strdup(""), strdup(""), width, height, false,
vertical); vertical);
} }
void
TTeamMenuItem::InitData(BList* team, BBitmap* icon, char* name, char* sig,
float width, float height, bool drawLabel, bool vertical)
{
fTeam = team;
fIcon = icon;
fName = name;
fSig = sig;
if (fName == NULL) {
char temp[32];
snprintf(temp, sizeof(temp), "team %ld", (addr_t)team->ItemAt(0));
fName = strdup(temp);
}
SetLabel(fName);
BFont font(be_plain_font);
fLabelWidth = ceilf(font.StringWidth(fName));
font_height fontHeight;
font.GetHeight(&fontHeight);
fLabelAscent = ceilf(fontHeight.ascent);
fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading);
fOverrideWidth = width;
fOverrideHeight = height;
fOverriddenSelected = false;
fVertical = vertical;
fDrawLabel = drawLabel;
fExpanded = false;
}
TTeamMenuItem::~TTeamMenuItem() TTeamMenuItem::~TTeamMenuItem()
{ {
delete fTeam; delete fTeam;
@@ -253,98 +219,38 @@ TTeamMenuItem::Draw()
BRect frame(Frame()); BRect frame(Frame());
BMenu* menu = Menu(); BMenu* menu = Menu();
menu->PushState(); menu->PushState();
rgb_color menuColor = menu->LowColor(); rgb_color menuColor = menu->LowColor();
TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView(); TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
bool canHandle = !barView->Dragging() bool canHandle = !barView->Dragging()
|| barView->AppCanHandleTypes(Signature()); || barView->AppCanHandleTypes(Signature());
uint32 flags = 0;
if (_IsSelected() && canHandle)
flags |= BControlLook::B_ACTIVATED;
if (be_control_look != NULL) { uint32 borders = BControlLook::B_TOP_BORDER;
uint32 flags = 0; if (fVertical) {
if (_IsSelected() && canHandle) menu->SetHighColor(tint_color(menuColor, B_DARKEN_1_TINT));
flags |= BControlLook::B_ACTIVATED; borders |= BControlLook::B_LEFT_BORDER
| BControlLook::B_RIGHT_BORDER;
menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
frame.bottom--;
uint32 borders = BControlLook::B_TOP_BORDER; be_control_look->DrawMenuBarBackground(menu, frame, frame,
if (fVertical) { menuColor, flags, borders);
menu->SetHighColor(tint_color(menuColor, B_DARKEN_1_TINT)); } else {
borders |= BControlLook::B_LEFT_BORDER if (flags & BControlLook::B_ACTIVATED)
| BControlLook::B_RIGHT_BORDER; menu->SetHighColor(tint_color(menuColor, B_DARKEN_3_TINT));
menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
frame.bottom--;
be_control_look->DrawMenuBarBackground(menu, frame, frame,
menuColor, flags, borders);
} else {
if (flags & BControlLook::B_ACTIVATED)
menu->SetHighColor(tint_color(menuColor, B_DARKEN_3_TINT));
else
menu->SetHighColor(tint_color(menuColor, 1.22));
borders |= BControlLook::B_BOTTOM_BORDER;
menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
frame.left++;
be_control_look->DrawButtonBackground(menu, frame, frame,
menuColor, flags, borders);
}
menu->MovePenTo(ContentLocation());
DrawContent();
menu->PopState();
return;
}
// if not selected or being tracked on, fill with gray
if ((!_IsSelected() && !menu->IsRedrawAfterSticky()) || !canHandle
|| !IsEnabled()) {
frame.InsetBy(1, 1);
menu->SetHighColor(menuColor);
menu->FillRect(frame);
}
// draw the gray, unselected item, border
if (!_IsSelected() || !IsEnabled()) {
rgb_color shadow = tint_color(menuColor, B_DARKEN_1_TINT);
rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT);
frame = Frame();
menu->SetHighColor(shadow);
if (fVertical)
menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
else else
menu->StrokeLine(frame.LeftBottom() + BPoint(1, 0), menu->SetHighColor(tint_color(menuColor, 1.22));
frame.RightBottom()); borders |= BControlLook::B_BOTTOM_BORDER;
menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
frame.left++;
menu->StrokeLine(frame.RightBottom(), frame.RightTop()); be_control_look->DrawButtonBackground(menu, frame, frame,
menuColor, flags, borders);
menu->SetHighColor(light);
menu->StrokeLine(frame.RightTop() + BPoint(-1, 0), frame.LeftTop());
if (fVertical)
menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()
+ BPoint(0, -1));
else
menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
} }
// if selected or being tracked on, fill with the hilite gray color
if (IsEnabled() && _IsSelected() && !menu->IsRedrawAfterSticky()
&& canHandle) {
// fill
menu->SetHighColor(tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT));
menu->FillRect(frame);
// these continue the dark grey border on the left or top edge
menu->SetHighColor(tint_color(menuColor, B_DARKEN_4_TINT));
if (fVertical) {
// dark line at top
menu->StrokeLine(frame.LeftTop(), frame.RightTop());
} else {
// dark line on the left
menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
}
} else
menu->SetLowColor(menuColor);
menu->MovePenTo(ContentLocation()); menu->MovePenTo(ContentLocation());
DrawContent(); DrawContent();
menu->PopState(); menu->PopState();
@@ -405,64 +311,9 @@ TTeamMenuItem::DrawContent()
DrawContentLabel(); DrawContentLabel();
} }
// Draw the expandable icon. int32 arrowDirection = fExpanded ? BControlLook::B_DOWN_ARROW
TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView(); : BControlLook::B_RIGHT_ARROW;
if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando DrawExpanderArrow(arrowDirection);
&& barView->ExpandoState()) {
BRect frame(Frame());
BRect rect(0, 0, kSwitchWidth, 10);
rect.OffsetTo(BPoint(frame.right - rect.Width(),
ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
if (be_control_look != NULL) {
uint32 arrowDirection = fExpanded ? BControlLook::B_DOWN_ARROW
: BControlLook::B_RIGHT_ARROW;
be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(),
arrowDirection, 0, B_DARKEN_3_TINT);
} else {
rgb_color outlineColor = {80, 80, 80, 255};
rgb_color middleColor = {200, 200, 200, 255};
menu->SetDrawingMode(B_OP_OVER);
if (!fExpanded) {
menu->BeginLineArray(6);
menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
BPoint(rect.left + 7, rect.top + 5), outlineColor);
menu->AddLine(BPoint(rect.left + 7, rect.top + 5),
BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
menu->AddLine(BPoint(rect.left + 4, rect.top + 3),
BPoint(rect.left + 4, rect.bottom - 3), middleColor);
menu->AddLine(BPoint(rect.left + 5, rect.top + 4),
BPoint(rect.left + 5, rect.bottom - 4), middleColor);
menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
BPoint(rect.left + 6, rect.top + 5), middleColor);
menu->EndLineArray();
} else {
// expanded state
menu->BeginLineArray(6);
menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
BPoint(rect.right - 3, rect.top + 3), outlineColor);
menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
BPoint(rect.left + 5, rect.top + 7), outlineColor);
menu->AddLine(BPoint(rect.left + 5, rect.top + 7),
BPoint(rect.right - 3, rect.top + 3), outlineColor);
menu->AddLine(BPoint(rect.left + 3, rect.top + 4),
BPoint(rect.right - 5, rect.top + 4), middleColor);
menu->AddLine(BPoint(rect.left + 4, rect.top + 5),
BPoint(rect.right - 6, rect.top + 5), middleColor);
menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
BPoint(rect.left + 5, rect.top + 6), middleColor);
menu->EndLineArray();
}
}
}
} }
@@ -521,6 +372,34 @@ TTeamMenuItem::DrawContentLabel()
} }
void
TTeamMenuItem::DrawExpanderArrow(int32 arrowDirection)
{
TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
bool canHandle = !barView->Dragging()
|| barView->AppCanHandleTypes(Signature());
uint32 flags = 0;
if (_IsSelected() && canHandle)
flags |= BControlLook::B_ACTIVATED;
if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando
&& barView->ExpandoState()) {
BMenu* menu = Menu();
BRect frame(Frame());
BRect rect(0, 0, kSwitchWidth, 10);
rect.OffsetTo(BPoint(frame.right - rect.Width(),
ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
if (flags == 0) {
menu->SetHighColor(menu->LowColor());
menu->FillRect(rect);
}
be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(),
arrowDirection, 0, B_DARKEN_3_TINT);
}
}
bool bool
TTeamMenuItem::IsExpanded() TTeamMenuItem::IsExpanded()
{ {
@@ -536,7 +415,7 @@ TTeamMenuItem::ToggleExpandState(bool resizeWindow)
if (fExpanded) { if (fExpanded) {
// Populate Menu() with the stuff from SubMenu(). // Populate Menu() with the stuff from SubMenu().
TWindowMenu* sub = (static_cast<TWindowMenu*>(Submenu())); TWindowMenu* sub = (static_cast<TWindowMenu*>(Submenu()));
if (sub) { if (sub != NULL) {
// force the menu to update it's contents. // force the menu to update it's contents.
bool locked = sub->LockLooper(); bool locked = sub->LockLooper();
// if locking the looper failed, the menu is just not visible // if locking the looper failed, the menu is just not visible
@@ -567,8 +446,7 @@ TTeamMenuItem::ToggleExpandState(bool resizeWindow)
} else { } else {
// Remove the goodies from the Menu() that should be in the SubMenu(); // Remove the goodies from the Menu() that should be in the SubMenu();
TWindowMenu* sub = static_cast<TWindowMenu*>(Submenu()); TWindowMenu* sub = static_cast<TWindowMenu*>(Submenu());
if (sub != NULL) {
if (sub) {
TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu()); TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
TWindowMenuItem* windowItem = NULL; TWindowMenuItem* windowItem = NULL;
@@ -622,6 +500,43 @@ TTeamMenuItem::ExpanderBounds() const
} }
// #pragma mark - Private methods
void
TTeamMenuItem::_InitData(BList* team, BBitmap* icon, char* name, char* sig,
float width, float height, bool drawLabel, bool vertical)
{
fTeam = team;
fIcon = icon;
fName = name;
fSig = sig;
if (fName == NULL) {
char temp[32];
snprintf(temp, sizeof(temp), "team %ld", (addr_t)team->ItemAt(0));
fName = strdup(temp);
}
SetLabel(fName);
BFont font(be_plain_font);
fLabelWidth = ceilf(font.StringWidth(fName));
font_height fontHeight;
font.GetHeight(&fontHeight);
fLabelAscent = ceilf(fontHeight.ascent);
fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading);
fOverrideWidth = width;
fOverrideHeight = height;
fOverriddenSelected = false;
fVertical = vertical;
fDrawLabel = drawLabel;
fExpanded = false;
}
bool bool
TTeamMenuItem::_IsSelected() const TTeamMenuItem::_IsSelected() const
{ {
+53 -46
View File
@@ -50,63 +50,70 @@ All rights reserved.
class BBitmap; class BBitmap;
class TTeamMenuItem : public BMenuItem { class TTeamMenuItem : public BMenuItem {
public: public:
TTeamMenuItem(BList* team, BBitmap* icon, char* name, char* sig, TTeamMenuItem(BList* team, BBitmap* icon,
float width = -1.0f, float height = -1.0f, char* name, char* sig,
bool drawLabel = true, bool vertical = true); float width = -1.0f, float height = -1.0f,
TTeamMenuItem(float width = -1.0f, float height = -1.0f, bool drawLabel = true,
bool vertical = true); bool vertical = true);
virtual ~TTeamMenuItem(); TTeamMenuItem(float width = -1.0f,
float height = -1.0f,
bool vertical = true);
virtual ~TTeamMenuItem();
status_t Invoke(BMessage* msg = NULL); status_t Invoke(BMessage* msg = NULL);
void SetOverrideWidth(float width); void SetOverrideWidth(float width);
void SetOverrideHeight(float height); void SetOverrideHeight(float height);
void SetOverrideSelected(bool selected); void SetOverrideSelected(bool selected);
bool HasLabel() const; bool HasLabel() const;
void SetHasLabel(bool drawLabel); void SetHasLabel(bool drawLabel);
bool IsExpanded(); bool IsExpanded();
void ToggleExpandState(bool resizeWindow); void ToggleExpandState(bool resizeWindow);
BRect ExpanderBounds() const; BRect ExpanderBounds() const;
TWindowMenuItem* ExpandedWindowItem(int32 id); TWindowMenuItem* ExpandedWindowItem(int32 id);
float LabelWidth() const; float LabelWidth() const;
BList* Teams() const; BList* Teams() const;
const char* Signature() const; const char* Signature() const;
const char* Name() const; const char* Name() const;
protected: protected:
void GetContentSize(float* width, float* height); void GetContentSize(float* width, float* height);
void Draw(); void Draw();
void DrawContent(); void DrawContent();
void DrawContentLabel(); void DrawContentLabel();
void DrawExpanderArrow(int32 arrowDirection);
private: private:
friend class TExpandoMenuBar; friend class TExpandoMenuBar;
void InitData(BList* team, BBitmap* icon, char* name, char* sig, void _InitData(BList* team, BBitmap* icon,
float width = -1.0f, float height = -1.0f, char* name, char* sig,
bool drawLabel = true, bool vertical = true); float width = -1.0f, float height = -1.0f,
bool drawLabel = true,
bool vertical = true);
bool _IsSelected() const; bool _IsSelected() const;
BList* fTeam; private:
BBitmap* fIcon; BList* fTeam;
char* fName; BBitmap* fIcon;
char* fSig; char* fName;
float fLabelWidth; char* fSig;
float fLabelAscent; float fLabelWidth;
float fLabelDescent; float fLabelAscent;
float fOverrideWidth; float fLabelDescent;
float fOverrideHeight; float fOverrideWidth;
float fOverrideHeight;
bool fDrawLabel; bool fDrawLabel;
bool fVertical; bool fVertical;
bool fExpanded; bool fExpanded;
bool fOverriddenSelected; bool fOverriddenSelected;
}; };
#endif /* TEAMMENUITEM_H */ #endif // TEAMMENUITEM_H