void TExpandoMenuBar::AddTeam(BList* team, BBitmap* icon, char* name, char* signature) { float itemWidth = fVertical ? fBarView->Bounds().Width() : sMinimumWindowWidth; float itemHeight = -1.0f; desk_settings* settings = ((TBarApp*)be_app)->Settings(); TTeamMenuItem* item = new TTeamMenuItem(team, icon, name, signature, itemWidth, itemHeight, fDrawLabel, fVertical); if (settings->trackerAlwaysFirst && !strcmp(signature, kTrackerSignature)) { AddItem(item, fFirstApp); } else if (settings->sortRunningApps) { TTeamMenuItem* teamItem = dynamic_cast<TTeamMenuItem*>(ItemAt(fFirstApp)); int32 firstApp = fFirstApp; // if Tracker should always be the first item, we need to skip it // when sorting in the current item if (settings->trackerAlwaysFirst && teamItem != NULL && !strcmp(teamItem->Signature(), kTrackerSignature)) { firstApp++; } int32 count = CountItems(), i; for (i = firstApp; i < count; i++) { teamItem = dynamic_cast<TTeamMenuItem*>(ItemAt(i)); if (teamItem != NULL && strcasecmp(teamItem->Name(), name) > 0) { AddItem(item, i); break; } } // was the item added to the list yet? if (i == count) AddItem(item); } else AddItem(item); if (fVertical) { if (item && fShowTeamExpander && fExpandNewTeams) item->ToggleExpandState(false); fBarView->SizeWindow(BScreen(Window()).Frame()); } else CheckItemSizes(1); Window()->UpdateIfNeeded(); }
void TExpandoMenuBar::_DoneTracking(BPoint point) { TTeamMenuItem* lastItem = dynamic_cast<TTeamMenuItem*>(fLastClickedItem); if (lastItem == NULL) return; if (!lastItem->ExpanderBounds().Contains(point)) return; lastItem->ToggleExpandState(true); lastItem->SetArrowDirection(lastItem->IsExpanded() ? BControlLook::B_DOWN_ARROW : BControlLook::B_RIGHT_ARROW); Invalidate(lastItem->ExpanderBounds()); }
void TBarView::ExpandItems() { if (fExpandoMenuBar == NULL || !fVertical || fState != kExpandoState || !fBarApp->Settings()->superExpando || fExpandedItems.CountItems() <= 0) { return; } // Start at the 'bottom' of the list working up. // Prevents being thrown off by expanding items. for (int32 i = fExpandoMenuBar->CountItems() - 1; i >= 0; i--) { TTeamMenuItem* teamItem = dynamic_cast<TTeamMenuItem*>(fExpandoMenuBar->ItemAt(i)); if (teamItem != NULL) { // Start at the 'bottom' of the fExpandedItems list working up // matching the order of the fExpandoMenuBar list in the outer loop. for (int32 j = fExpandedItems.CountItems() - 1; j >= 0; j--) { BString* itemSig = static_cast<BString*>(fExpandedItems.ItemAt(j)); if (itemSig->Compare(teamItem->Signature()) == 0) { // Found it, expand the item and delete signature from // the list so that we don't consider it for later items. teamItem->ToggleExpandState(false); fExpandedItems.RemoveItem(j); delete itemSig; break; } } } } // Clean up the expanded items list RemoveExpandedItems(); }
void TExpandoMenuBar::MouseDown(BPoint where) { BMessage *message = Window()->CurrentMessage(); // check for three finger salute, a.k.a. Vulcan Death Grip if (message != NULL) { int32 modifiers = 0; message->FindInt32("modifiers", &modifiers); if ((modifiers & B_COMMAND_KEY) != 0 && (modifiers & B_OPTION_KEY) != 0 && (modifiers & B_SHIFT_KEY) != 0 && !fBarView->Dragging()) { TTeamMenuItem *item = ItemAtPoint(where); if (item) { const BList *teams = item->Teams(); int32 teamCount = teams->CountItems(); team_id teamID; for (int32 team = 0; team < teamCount; team++) { teamID = (team_id)teams->ItemAt(team); kill_team(teamID); // remove the team immediately // from display RemoveTeam(teamID, false); } return; } } } const int32 count = CountItems(); // This feature is broken because the menu bar never receives // the second click #ifdef DOUBLECLICKBRINGSTOFRONT // doubleclick on an item brings all to front for (int32 i = fFirstApp; i < count; i++) { TTeamMenuItem *item = (TTeamMenuItem *)ItemAt(i); if (item->Frame().Contains(where)) { bigtime_t clickSpeed = 0; get_click_speed(&clickSpeed); if ( (fLastClickItem == i) && (clickSpeed > (system_time() - fLastClickTime)) ) { // bring this team's window to the front BMessage showMessage(M_BRING_TEAM_TO_FRONT); showMessage.AddInt32("itemIndex", i); Window()->PostMessage(&showMessage, this); return; } fLastClickItem = i; fLastClickTime = system_time(); break; } } #endif // control click - show all/hide all shortcut if (message != NULL) { int32 modifiers = 0; message->FindInt32("modifiers", &modifiers); if ((modifiers & B_CONTROL_KEY) != 0 && ! fBarView->Dragging()) { int32 lastApp = -1; // find the clicked item for (int32 i = fFirstApp; i < count; i++) { const TTeamMenuItem *item = (TTeamMenuItem *)ItemAt(i); // check if this item is really a team item (what a cruel way...) // "lastApp" will always point to the last application in // the list - the other entries might be windows (due to the team expander) if (item->Submenu()) lastApp = i; if (item->Frame().Contains(where)) { // show/hide item's teams BMessage showMessage((modifiers & B_SHIFT_KEY) != 0 ? M_MINIMIZE_TEAM : M_BRING_TEAM_TO_FRONT); showMessage.AddInt32("itemIndex", lastApp); Window()->PostMessage(&showMessage, this); return; } } } } // Check the bounds of the expand Team icon if (fShowTeamExpander && fVertical && !fBarView->Dragging()) { TTeamMenuItem *item = ItemAtPoint(where); if (item->Submenu()){ BRect expanderRect = item->ExpanderBounds(); if (expanderRect.Contains(where)) { item->ToggleExpandState(true); item->Draw(); // Absorb the message. return; } } } BMenuBar::MouseDown(where); }
void TExpandoMenuBar::MouseDown(BPoint where) { BMessage* message = Window()->CurrentMessage(); BMenuItem* menuItem; TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); // check for three finger salute, a.k.a. Vulcan Death Grip if (message != NULL && item != NULL && !fBarView->Dragging()) { int32 modifiers = 0; message->FindInt32("modifiers", &modifiers); if ((modifiers & B_COMMAND_KEY) != 0 && (modifiers & B_CONTROL_KEY) != 0 && (modifiers & B_SHIFT_KEY) != 0) { const BList* teams = item->Teams(); int32 teamCount = teams->CountItems(); team_id teamID; for (int32 team = 0; team < teamCount; team++) { teamID = (team_id)teams->ItemAt(team); kill_team(teamID); // remove the team immediately from display RemoveTeam(teamID, false); } return; } // control click - show all/hide all shortcut if ((modifiers & B_CONTROL_KEY) != 0) { // show/hide item's teams BMessage showMessage((modifiers & B_SHIFT_KEY) != 0 ? kMinimizeTeam : kBringTeamToFront); showMessage.AddInt32("itemIndex", IndexOf(item)); Window()->PostMessage(&showMessage, this); return; } // Check the bounds of the expand Team icon if (fShowTeamExpander && fVertical) { BRect expanderRect = item->ExpanderBounds(); if (expanderRect.Contains(where)) { // Let the update thread wait... BAutolock locker(sMonLocker); // Toggle the item item->ToggleExpandState(true); item->Draw(); // Absorb the message. return; } } // double-click on an item brings the team to front int32 clicks; if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1 && item == menuItem && item == fLastClickItem) { // activate this team be_roster->ActivateApp((team_id)item->Teams()->ItemAt(0)); return; } fLastClickItem = item; } BMenuBar::MouseDown(where); }
void TExpandoMenuBar::AddTeam(BList* team, BBitmap* icon, char* name, char* signature) { int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize(); desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings(); float itemWidth = -1.0f; if (fVertical) itemWidth = fBarView->Bounds().Width(); else { itemWidth = iconSize; if (!settings->hideLabels) itemWidth += gMinimumWindowWidth - kMinimumIconSize; else itemWidth += kIconPadding * 2; } float itemHeight = -1.0f; TTeamMenuItem* item = new TTeamMenuItem(team, icon, name, signature, itemWidth, itemHeight); if (settings->trackerAlwaysFirst && strcasecmp(signature, kTrackerSignature) == 0) { AddItem(item, 0); } else if (settings->sortRunningApps) { TTeamMenuItem* teamItem = dynamic_cast<TTeamMenuItem*>(ItemAt(0)); int32 firstApp = 0; // if Tracker should always be the first item, we need to skip it // when sorting in the current item if (settings->trackerAlwaysFirst && teamItem != NULL && strcasecmp(teamItem->Signature(), kTrackerSignature) == 0) { firstApp++; } BCollator collator; BLocale::Default()->GetCollator(&collator); int32 i = firstApp; int32 itemCount = CountItems(); while (i < itemCount) { teamItem = dynamic_cast<TTeamMenuItem*>(ItemAt(i)); if (teamItem != NULL && collator.Compare(teamItem->Label(), name) > 0) { AddItem(item, i); break; } i++; } // was the item added to the list yet? if (i == itemCount) AddItem(item); } else AddItem(item); if (fVertical && settings->superExpando && settings->expandNewTeams) item->ToggleExpandState(false); SizeWindow(1); Window()->UpdateIfNeeded(); }
void TExpandoMenuBar::BuildItems() { BMessenger self(this); TBarApp::Subscribe(self, &fTeamList); int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize(); desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings(); float itemWidth = -1.0f; if (fVertical) itemWidth = Frame().Width(); else { itemWidth = iconSize; if (!settings->hideLabels) itemWidth += gMinimumWindowWidth - kMinimumIconSize; else itemWidth += kIconPadding * 2; } float itemHeight = -1.0f; TeamMenuItemMap items; int32 itemCount = CountItems(); BList itemList(itemCount); for (int32 i = 0; i < itemCount; i++) { BMenuItem* menuItem = RemoveItem((int32)0); itemList.AddItem(menuItem); TTeamMenuItem* item = dynamic_cast<TTeamMenuItem*>(menuItem); if (item != NULL) items[BString(item->Signature()).ToLower()] = item; } if (settings->sortRunningApps) fTeamList.SortItems(TTeamMenu::CompareByName); int32 teamCount = fTeamList.CountItems(); for (int32 i = 0; i < teamCount; i++) { BarTeamInfo* barInfo = (BarTeamInfo*)fTeamList.ItemAt(i); TeamMenuItemMap::const_iterator iter = items.find(BString(barInfo->sig).ToLower()); if (iter == items.end()) { // new team TTeamMenuItem* item = new TTeamMenuItem(barInfo->teams, barInfo->icon, barInfo->name, barInfo->sig, itemWidth, itemHeight); if (settings->trackerAlwaysFirst && strcasecmp(barInfo->sig, kTrackerSignature) == 0) { AddItem(item, 0); } else AddItem(item); if (fFirstBuild && fVertical && settings->expandNewTeams) item->ToggleExpandState(true); } else { // existing team, update info and add it TTeamMenuItem* item = iter->second; item->SetIcon(barInfo->icon); item->SetOverrideWidth(itemWidth); item->SetOverrideHeight(itemHeight); if (settings->trackerAlwaysFirst && strcasecmp(barInfo->sig, kTrackerSignature) == 0) { AddItem(item, 0); } else AddItem(item); // add window items back int32 index = itemList.IndexOf(item); TWindowMenuItem* windowItem; TWindowMenu* submenu = dynamic_cast<TWindowMenu*>(item->Submenu()); bool hasWindowItems = false; while ((windowItem = dynamic_cast<TWindowMenuItem*>( (BMenuItem*)(itemList.ItemAt(++index)))) != NULL) { if (fVertical) AddItem(windowItem); else { delete windowItem; hasWindowItems = submenu != NULL; } } // unexpand if turn off show team expander if (fVertical && !settings->superExpando && item->IsExpanded()) item->ToggleExpandState(false); if (hasWindowItems) { // add (new) window items in submenu submenu->SetExpanded(false, 0); submenu->AttachedToWindow(); } } } if (CountItems() == 0) { // If we're empty, BMenuBar::AttachedToWindow() resizes us to some // weird value - we just override it again ResizeTo(itemWidth, 0); } fFirstBuild = false; }
void TBarView::ChangeState(int32 state, bool vertical, bool left, bool top) { bool vertSwap = (fVertical != vertical); bool leftSwap = (fLeft != left); fState = state; fVertical = vertical; fLeft = left; fTop = top; BRect screenFrame = (BScreen(Window())).Frame(); PlaceBeMenu(); if (fVertical){ #if SA_CLOCK PlaceClock(); // tray dependent on clock location #endif PlaceTray(vertSwap, leftSwap, screenFrame); } else { PlaceTray(vertSwap, leftSwap, screenFrame); #if SA_CLOCK PlaceClock(); // clock is dependent on tray location #endif } // We need to keep track of what apps are expanded. BList expandedItems; BString *signature = NULL; if (fVertical && Expando() && static_cast<TBarApp *>(be_app)->Settings()->superExpando) { // Get a list of the Signatures of expanded apps - Can't use team_id because // there can be more than one team per application if (fVertical && Expando() && vertical && fExpando) { for (int index = 0; index < fExpando->CountItems(); index++) { TTeamMenuItem *item = dynamic_cast<TTeamMenuItem *>(fExpando->ItemAt(index)); if (item != NULL && item->IsExpanded()) { signature = new BString(item->Signature()); expandedItems.AddItem((void *)signature); } } } } PlaceApplicationBar(screenFrame); SizeWindow(screenFrame); PositionWindow(screenFrame); Window()->UpdateIfNeeded(); // Re-expand those apps. if (expandedItems.CountItems() > 0) { for (int sigIndex = expandedItems.CountItems(); sigIndex-- > 0;) { signature = static_cast<BString *>(expandedItems.ItemAt(sigIndex)); if (signature == NULL) continue; // Start at the 'bottom' of the list working up. // Prevents being thrown off by expanding items. for (int teamIndex = fExpando->CountItems(); teamIndex-- > 0;) { TTeamMenuItem *item = dynamic_cast<TTeamMenuItem *>(fExpando->ItemAt(teamIndex)); if (item != NULL && !signature->Compare(item->Signature())) { item->ToggleExpandState(false); break; } } } // Clean up expanded signature list. while (!expandedItems.IsEmpty()) { delete static_cast<BString *>(expandedItems.RemoveItem((int32)0)); } fExpando->SizeWindow(); } Invalidate(); }