void TBarView::SaveExpandedItems() { if (fExpando == NULL || fExpando->CountItems() <= 0) return; // Get a list of the signatures of expanded apps. Can't use // team_id because there can be more than one team per application for (int32 i = 0; i < fExpando->CountItems(); i++) { TTeamMenuItem* teamItem = dynamic_cast<TTeamMenuItem*>(fExpando->ItemAt(i)); if (teamItem != NULL && teamItem->IsExpanded()) AddExpandedItem(teamItem->Signature()); } }
void TExpandoMenuBar::_Track(BPoint point, uint32) { TTeamMenuItem* lastItem = dynamic_cast<TTeamMenuItem*>(fLastClickedItem); if (lastItem == NULL) return; if (lastItem->ExpanderBounds().Contains(point)) lastItem->SetArrowDirection(BControlLook::B_RIGHT_DOWN_ARROW); else { lastItem->SetArrowDirection(lastItem->IsExpanded() ? BControlLook::B_DOWN_ARROW : BControlLook::B_RIGHT_ARROW); } Invalidate(lastItem->ExpanderBounds()); }
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()); }
int32 TExpandoMenuBar::monitor_team_windows(void *arg) { TExpandoMenuBar *teamMenu = (TExpandoMenuBar *)arg; int32 totalItems = 0; bool itemModified = false; TWindowMenuItem *item = NULL; TTeamMenuItem *teamItem = NULL; int32 *tokens = NULL; while (teamMenu->sDoMonitor) { totalItems = teamMenu->CountItems(); // Set all WindowMenuItems to require an update. item = NULL; for (int32 i = 0; i < totalItems; i++) { if (!teamMenu->SubmenuAt(i)){ item = static_cast<TWindowMenuItem *>(teamMenu->ItemAt(i)); item->SetRequireUpdate(); } } // Perform SetTo() on all the items that still exist as well as add new items. itemModified = false; teamItem = NULL; for (int32 i = 0; i < totalItems; i++) { if (teamMenu->SubmenuAt(i)){ teamItem = static_cast<TTeamMenuItem *>(teamMenu->ItemAt(i)); if (teamItem->IsExpanded()) { int32 teamCount = teamItem->Teams()->CountItems(); for (int32 j = 0; j < teamCount; j++) { // The following code is almost a copy/paste from // WindowMenu.cpp team_id theTeam = (team_id)teamItem->Teams()->ItemAt(j); int32 count = 0; tokens = get_token_list(theTeam, &count); for (int32 k = 0; k < count; k++) { window_info *wInfo = get_window_info(tokens[k]); if (wInfo == NULL) continue; if (TWindowMenu::WindowShouldBeListed(wInfo->w_type) && (wInfo->show_hide_level <= 0 || wInfo->is_mini)) { // Check if we have a matching window item... item = teamItem->ExpandedWindowItem(wInfo->id); if (item) { // Lock the window, changing workspaces will fry this. item->SetTo(wInfo->name, wInfo->id, wInfo->is_mini, ((1 << current_workspace()) & wInfo->workspaces) != 0); if (strcmp(wInfo->name, item->Label()) != 0) item->SetLabel(wInfo->name); if (item->ChangedState()) itemModified = true; } else if (teamItem->IsExpanded()) { // Add the item item = new TWindowMenuItem(wInfo->name, wInfo->id, wInfo->is_mini, ((1 << current_workspace()) & wInfo->workspaces) != 0, false); item->ExpandedItem(true); teamMenu->AddItem(item, i + 1); itemModified = true; teamMenu->Window()->Lock(); teamMenu->SizeWindow(); teamMenu->Window()->Unlock(); } } free(wInfo); } free(tokens); } } } } // Remove any remaining items which require an update. for (int32 i = 0; i < totalItems; i++) { if (!teamMenu->SubmenuAt(i)){ item = static_cast<TWindowMenuItem *>(teamMenu->ItemAt(i)); if (item && item->RequiresUpdate()) { item = static_cast<TWindowMenuItem *>(teamMenu->RemoveItem(i)); delete item; totalItems--; teamMenu->Window()->Lock(); teamMenu->SizeWindow(); teamMenu->Window()->Unlock(); } } } // If any of the WindowMenuItems changed state, we need to force a repaint. if (itemModified) { teamMenu->Window()->Lock(); teamMenu->Invalidate(); teamMenu->Window()->Unlock(); } // sleep for a bit... snooze(150000); } return B_OK; }
int32 TExpandoMenuBar::monitor_team_windows(void* arg) { TExpandoMenuBar* teamMenu = (TExpandoMenuBar*)arg; while (teamMenu->sDoMonitor) { sMonLocker.Lock(); if (teamMenu->Window()->LockWithTimeout(50000) == B_OK) { int32 totalItems = teamMenu->CountItems(); // Set all WindowMenuItems to require an update. TWindowMenuItem* item = NULL; for (int32 i = 0; i < totalItems; i++) { if (!teamMenu->SubmenuAt(i)) { item = static_cast<TWindowMenuItem*>(teamMenu->ItemAt(i)); item->SetRequireUpdate(true); } } // Perform SetTo() on all the items that still exist as well as add // new items. bool itemModified = false; bool resize = false; TTeamMenuItem* teamItem = NULL; for (int32 i = 0; i < totalItems; i++) { if (teamMenu->SubmenuAt(i) == NULL) continue; teamItem = static_cast<TTeamMenuItem*>(teamMenu->ItemAt(i)); if (teamItem->IsExpanded()) { int32 teamCount = teamItem->Teams()->CountItems(); for (int32 j = 0; j < teamCount; j++) { // The following code is almost a copy/paste from // WindowMenu.cpp team_id theTeam = (addr_t)teamItem->Teams()->ItemAt(j); int32 count = 0; int32* tokens = get_token_list(theTeam, &count); for (int32 k = 0; k < count; k++) { client_window_info* wInfo = get_window_info(tokens[k]); if (wInfo == NULL) continue; if (TWindowMenu::WindowShouldBeListed(wInfo)) { // Check if we have a matching window item... item = teamItem->ExpandedWindowItem( wInfo->server_token); if (item != NULL) { item->SetTo(wInfo->name, wInfo->server_token, wInfo->is_mini, ((1 << current_workspace()) & wInfo->workspaces) != 0); if (strcasecmp(item->Label(), wInfo->name) > 0) item->SetLabel(wInfo->name); if (item->Modified()) itemModified = true; } else if (teamItem->IsExpanded()) { // Add the item item = new TWindowMenuItem(wInfo->name, wInfo->server_token, wInfo->is_mini, ((1 << current_workspace()) & wInfo->workspaces) != 0, false); item->SetExpanded(true); teamMenu->AddItem(item, TWindowMenuItem::InsertIndexFor( teamMenu, i + 1, item)); resize = true; } } free(wInfo); } free(tokens); } } } // Remove any remaining items which require an update. for (int32 i = 0; i < totalItems; i++) { if (!teamMenu->SubmenuAt(i)) { item = static_cast<TWindowMenuItem*>(teamMenu->ItemAt(i)); if (item && item->RequiresUpdate()) { item = static_cast<TWindowMenuItem*> (teamMenu->RemoveItem(i)); delete item; totalItems--; resize = true; } } } // If any of the WindowMenuItems changed state, we need to force a // repaint. if (itemModified || resize) { teamMenu->Invalidate(); if (resize) teamMenu->SizeWindow(1); } teamMenu->Window()->Unlock(); } sMonLocker.Unlock(); // sleep for a bit... snooze(150000); } return B_OK; }
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 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) { // force a cleanup _FinishedDrag(); switch (code) { case B_INSIDE_VIEW: { BMenuItem* menuItem; TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); TWindowMenuItem* windowMenuItem = dynamic_cast<TWindowMenuItem*>(menuItem); if (item == NULL || menuItem == NULL) { // item is NULL, remove the tooltip and break out fLastMousedOverItem = NULL; SetToolTip((const char*)NULL); break; } if (menuItem == fLastMousedOverItem) { // already set the tooltip for this item, break out break; } if (windowMenuItem != NULL && fBarView->Vertical() && fBarView->ExpandoState() && item->IsExpanded()) { // expando mode window menu item fLastMousedOverItem = menuItem; if (strcasecmp(windowMenuItem->TruncatedLabel(), windowMenuItem->Label()) > 0) { // label is truncated, set tooltip SetToolTip(windowMenuItem->Label()); } else SetToolTip((const char*)NULL); break; } if (!dynamic_cast<TBarApp*>(be_app)->Settings()->hideLabels) { // item has a visible label, set tool tip if truncated fLastMousedOverItem = menuItem; if (strcasecmp(item->TruncatedLabel(), item->Label()) > 0) { // label is truncated, set tooltip SetToolTip(item->Label()); } else SetToolTip((const char*)NULL); break; } SetToolTip(item->Label()); // new item, set the tooltip to the item label fLastMousedOverItem = menuItem; // save the current menuitem for the next MouseMoved() call break; } } BMenuBar::MouseMoved(where, code, message); return; } if (buttons == 0) return; switch (code) { case B_ENTERED_VIEW: // fPreviousDragTargetItem should always be NULL here anyways. if (fPreviousDragTargetItem != NULL) _FinishedDrag(); fBarView->CacheDragData(message); fPreviousDragTargetItem = NULL; break; case B_OUTSIDE_VIEW: // NOTE: Should not be here, but for the sake of defensive // programming... fall-through case B_EXITED_VIEW: _FinishedDrag(); break; case B_INSIDE_VIEW: if (fBarView->Dragging()) { TTeamMenuItem* item = NULL; int32 itemCount = CountItems(); for (int32 i = 0; i < itemCount; i++) { BMenuItem* _item = ItemAt(i); if (_item->Frame().Contains(where)) { item = dynamic_cast<TTeamMenuItem*>(_item); break; } } if (item == fPreviousDragTargetItem) break; if (fPreviousDragTargetItem != NULL) fPreviousDragTargetItem->SetOverrideSelected(false); if (item != NULL) item->SetOverrideSelected(true); fPreviousDragTargetItem = item; } break; } }
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(); }