bool TBarView::MenuTrackingHook(BMenu *menu, void *castToThis) { // return true if the menu should go away 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 returnvalue = true; BRect frame(menu->Bounds()); frame.InsetBy(-kMenuTrackMargin, -kMenuTrackMargin); if (frame.Contains(location)) { // if current loc is still in the menu // keep tracking returnvalue = false; } else { // see if the mouse is in the team/be menu item menu->ConvertToScreen(&location); if (barview->LockLooper()) { TExpandoMenuBar *expando = barview->ExpandoMenuBar(); TBeMenu *bemenu = (dynamic_cast<TBarWindow*>(barview->Window()))->BeMenu(); if (bemenu && bemenu->LockLooper()) { bemenu->ConvertFromScreen(&location); if (bemenu->Frame().Contains(location)) returnvalue = false; bemenu->UnlockLooper(); } if (returnvalue && expando) { expando->ConvertFromScreen(&location); TTeamMenuItem *item = expando->ItemAtPoint(location); if (item) returnvalue = false; } barview->UnlockLooper(); } } menu->UnlockLooper(); return returnvalue; }
void TWindowMenu::DetachedFromWindow() { // in expando mode the teammenu will not call DragStop, // thus, it needs to be called from here TBarView* barview = (dynamic_cast<TBarApp*>(be_app))->BarView(); if (barview && barview->Expando() && barview->Dragging() && barview->LockLooper()) { // We changed the show level in AttachedToWindow(). Undo it. Window()->Show(); barview->DragStop(); barview->UnlockLooper(); } BMenu::DetachedFromWindow(); }
void TWindowMenu::AttachedToWindow() { SetFont(be_plain_font); RemoveItems(0, CountItems(), true); int32 miniCount = 0; bool dragging = false; TBarView* barview =(static_cast<TBarApp*>(be_app))->BarView(); if (barview && barview->LockLooper()) { // 'dragging' mode set in BarView::CacheDragData // invoke in MouseEnter in ExpandoMenuBar dragging = barview->Dragging(); if (dragging) { // We don't want to show the menu when dragging, but it's not // possible to remove a submenu once it exists, so we simply hide it // Don't call BMenu::Hide(), it causes the menu to pop up every now // and then. Window()->Hide(); // if in expando (horizontal or vertical) if (barview->Expando()) { SetTrackingHook(barview->MenuTrackingHook, barview->GetTrackingHookData()); } barview->DragStart(); } barview->UnlockLooper(); } int32 parentMenuItems = 0; int32 numTeams = fTeam->CountItems(); for (int32 i = 0; i < numTeams; i++) { team_id theTeam = (team_id)fTeam->ItemAt(i); int32 count = 0; int32* tokens = get_token_list(theTeam, &count); for (int32 j = 0; j < count; j++) { client_window_info* wInfo = get_window_info(tokens[j]); if (wInfo == NULL) continue; if (WindowShouldBeListed(wInfo->feel) && (wInfo->show_hide_level <= 0 || wInfo->is_mini)) { // Don't add new items if we're expanded. We've already done // this, they've just been moved. int32 numItems = CountItems(); int32 addIndex = 0; for (; addIndex < numItems; addIndex++) if (strcasecmp(ItemAt(addIndex)->Label(), wInfo->name) > 0) break; if (!fExpanded) { TWindowMenuItem* item = new TWindowMenuItem(wInfo->name, wInfo->server_token, wInfo->is_mini, ((1 << current_workspace()) & wInfo->workspaces) != 0, dragging); // disable app's window dropping for now if (dragging) item->SetEnabled(false); AddItem(item, TWindowMenuItem::InsertIndexFor(this, 0, item)); } else { TTeamMenuItem* parentItem = static_cast<TTeamMenuItem*>(Superitem()); if (parentItem->ExpandedWindowItem(wInfo->server_token)) { TWindowMenuItem* item = parentItem->ExpandedWindowItem( wInfo->server_token); if (item == NULL) continue; item->SetTo(wInfo->name, wInfo->server_token, wInfo->is_mini, ((1 << current_workspace()) & wInfo->workspaces) != 0, dragging); parentMenuItems++; } } if (wInfo->is_mini) miniCount++; } free(wInfo); } free(tokens); } int32 itemCount = CountItems() + parentMenuItems; if (itemCount < 1) { TWindowMenuItem* noWindowsItem = new TWindowMenuItem("No windows", -1, false, false); noWindowsItem->SetEnabled(false); AddItem(noWindowsItem); // if an application has no windows, this feature makes it easy to quit // it. (but we only add this option if the application is not Tracker.) if (fApplicationSignature.ICompare(kTrackerSignature) != 0) { AddSeparatorItem(); AddItem(new TShowHideMenuItem("Quit application", fTeam, B_QUIT_REQUESTED)); } } else { // if we are in drag mode, then don't add the window controls // to the menu if (!dragging) { TShowHideMenuItem* hide = new TShowHideMenuItem("Hide all", fTeam, B_MINIMIZE_WINDOW); TShowHideMenuItem* show = new TShowHideMenuItem("Show all", fTeam, B_BRING_TO_FRONT); TShowHideMenuItem* close = new TShowHideMenuItem("Close all", fTeam, B_QUIT_REQUESTED); if (miniCount == itemCount) hide->SetEnabled(false); else if (miniCount == 0) show->SetEnabled(false); if (!parentMenuItems) AddSeparatorItem(); AddItem(hide); AddItem(show); AddItem(close); } } BMenu::AttachedToWindow(); }
void TTeamMenu::AttachedToWindow() { RemoveItems(0, CountItems(), true); // remove all items BMessenger self(this); BList teamList; TBarApp::Subscribe(self, &teamList); TBarView* barview = (dynamic_cast<TBarApp*>(be_app))->BarView(); bool dragging = barview && barview->Dragging(); int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize(); desk_settings* settings = ((TBarApp*)be_app)->Settings(); float width = sMinimumWindowWidth - iconSize - 4; if (settings->sortRunningApps) teamList.SortItems(CompareByName); int32 count = teamList.CountItems(); for (int32 i = 0; i < count; i++) { // add items back BarTeamInfo* barInfo = (BarTeamInfo*)teamList.ItemAt(i); TTeamMenuItem* item = new TTeamMenuItem(barInfo->teams, barInfo->icon, barInfo->name, barInfo->sig, width, -1, !settings->hideLabels, true); if (settings->trackerAlwaysFirst && strcmp(barInfo->sig, kTrackerSignature) == 0) { AddItem(item, 0); } else AddItem(item); if (dragging && item != NULL) { bool canhandle = (dynamic_cast<TBarApp*>(be_app))->BarView()-> AppCanHandleTypes(item->Signature()); if (item->IsEnabled() != canhandle) item->SetEnabled(canhandle); BMenu* menu = item->Submenu(); if (menu) menu->SetTrackingHook(barview->MenuTrackingHook, barview->GetTrackingHookData()); } } if (CountItems() == 0) { BMenuItem* item = new BMenuItem("no application running", NULL); item->SetEnabled(false); AddItem(item); } if (dragging && barview->LockLooper()) { SetTrackingHook(barview->MenuTrackingHook, barview->GetTrackingHookData()); barview->DragStart(); barview->UnlockLooper(); } BMenu::AttachedToWindow(); }