예제 #1
0
void
TExpandoMenuBar::AddTeam(team_id team, const char* signature)
{
	int32 itemCount = CountItems();
	for (int32 i = 0; i < itemCount; i++) {
		// Only add to team menu items
		TTeamMenuItem* item = dynamic_cast<TTeamMenuItem*>(ItemAt(i));
		if (item != NULL && strcasecmp(item->Signature(), signature) == 0
			&& !(item->Teams()->HasItem((void*)(addr_t)team))) {
			item->Teams()->AddItem((void*)(addr_t)team);
			break;
		}
	}
}
예제 #2
0
void
TExpandoMenuBar::RemoveTeam(team_id team, bool partial)
{
	TWindowMenuItem* windowItem = NULL;

	for (int32 i = CountItems() - 1; i >= 0; i--) {
		TTeamMenuItem* item = dynamic_cast<TTeamMenuItem*>(ItemAt(i));
		if (item != NULL && item->Teams()->HasItem((void*)(addr_t)team)) {
			item->Teams()->RemoveItem(team);
			if (partial)
				return;

			BAutolock locker(sMonLocker);
				// make the update thread wait
			RemoveItem(i);
			if (item == fPreviousDragTargetItem)
				fPreviousDragTargetItem = NULL;

			if (item == fLastMousedOverItem)
				fLastMousedOverItem = NULL;

			if (item == fLastClickedItem)
				fLastClickedItem = NULL;

			delete item;
			while ((windowItem = dynamic_cast<TWindowMenuItem*>(
					ItemAt(i))) != NULL) {
				// Also remove window items (if there are any)
				RemoveItem(i);
				if (windowItem == fLastMousedOverItem)
					fLastMousedOverItem = NULL;

				if (windowItem == fLastClickedItem)
					fLastClickedItem = NULL;

				delete windowItem;
			}
			SizeWindow(-1);
			Window()->UpdateIfNeeded();
			return;
		}
	}
}
예제 #3
0
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;
}
예제 #4
0
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);
}
예제 #5
0
void
TExpandoMenuBar::MessageReceived(BMessage *message)
{
	int32 index;
	TTeamMenuItem *item;
	
	switch (message->what) {
		case B_SOME_APP_LAUNCHED: {
			BList *teams = NULL;
			message->FindPointer("teams", (void **)&teams);

			BBitmap *icon = NULL;
			message->FindPointer("icon", (void **)&icon);

			const char *sig;
			if (message->FindString("sig", &sig) == B_OK
				&&strcasecmp(sig, TASK_BAR_MIME_SIG) == 0) {
				delete teams;
				delete icon;
				break;
			}

			uint32 flags;
			if (message->FindInt32("flags", ((int32*) &flags)) == B_OK
				&& (flags & B_BACKGROUND_APP) != 0) {
				delete teams;
				delete icon;
				break;
			}

			const char *name = NULL;
			message->FindString("name", &name);

			AddTeam(teams, icon, strdup(name), strdup(sig));
			break;
		}
		
		case msg_AddTeam:
			AddTeam(message->FindInt32("team"), message->FindString("sig"));
			break;

		case msg_RemoveTeam:
		{
			team_id team = -1;
			message->FindInt32("team", &team);

			RemoveTeam(team, true);
			break;
		}

		case B_SOME_APP_QUIT:
		{
			team_id team = -1;
			message->FindInt32("team", &team);

			RemoveTeam(team, false);
			break;
		}
		
		case M_MINIMIZE_TEAM:
		{
			index = message->FindInt32("itemIndex");
			item = dynamic_cast<TTeamMenuItem *>(ItemAt(index));
			if (item == NULL)
				break;

			TShowHideMenuItem::TeamShowHideCommon(B_MINIMIZE_WINDOW,
				item->Teams(), 
				item->Menu()->ConvertToScreen(item->Frame()), 
				true);
			break;
		}
		
		case M_BRING_TEAM_TO_FRONT:
		{
			index = message->FindInt32("itemIndex");
			item = dynamic_cast<TTeamMenuItem *>(ItemAt(index));
			if (item == NULL)
				break;

			TShowHideMenuItem::TeamShowHideCommon(B_BRING_TO_FRONT,
				item->Teams(), 
				item->Menu()->ConvertToScreen(item->Frame()),
				true);
			break;
		}
			
		default:
			BMenuBar::MessageReceived(message);
			break;
	}
}
예제 #6
0
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);
}
예제 #7
0
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;
}
예제 #8
0
void
TExpandoMenuBar::MouseDown(BPoint where)
{
	BMessage* message = Window()->CurrentMessage();
	BMenuItem* menuItem;
	TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem);

	if (message == NULL || item == NULL || fBarView->Dragging()) {
		BMenuBar::MouseDown(where);
		return;
	}

	int32 modifiers = 0;
	message->FindInt32("modifiers", &modifiers);

	// check for three finger salute, a.k.a. Vulcan Death Grip
	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 = (addr_t)teams->ItemAt(team);
			kill_team(teamID);
			RemoveTeam(teamID, false);
				// remove the team from display immediately
		}
		return;
			// absorb the message
	}

	// 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;
			// absorb the message
	}

	// check if within expander bounds to expand window items
	if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando
		&& item->ExpanderBounds().Contains(where)) {
		// start the animation here, finish on mouse up
		fLastClickedItem = item;
		MouseDownThread<TExpandoMenuBar>::TrackMouse(this,
			&TExpandoMenuBar::_DoneTracking, &TExpandoMenuBar::_Track);
		Invalidate(item->ExpanderBounds());
		return;
			// absorb the message
	}

	// double-click on an item brings the team to front
	int32 clicks;
	if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1
		&& item == menuItem && item == fLastClickedItem) {
		be_roster->ActivateApp((addr_t)item->Teams()->ItemAt(0));
			// activate this team
		return;
			// absorb the message
	}

	fLastClickedItem = item;
	BMenuBar::MouseDown(where);
}
예제 #9
0
void
TExpandoMenuBar::MessageReceived(BMessage* message)
{
	int32 index;
	TTeamMenuItem* item;

	switch (message->what) {
		case B_SOME_APP_LAUNCHED:
		{
			BList* teams = NULL;
			message->FindPointer("teams", (void**)&teams);

			BBitmap* icon = NULL;
			message->FindPointer("icon", (void**)&icon);

			const char* signature = NULL;
			message->FindString("sig", &signature);

			uint32 flags = 0;
			message->FindInt32("flags", ((int32*) &flags));

			const char* name = NULL;
			message->FindString("name", &name);

			AddTeam(teams, icon, strdup(name), strdup(signature));
			break;
		}

		case B_MOUSE_WHEEL_CHANGED:
		{
			float deltaY = 0;
			message->FindFloat("be:wheel_delta_y", &deltaY);
			if (deltaY == 0)
				return;

			TInlineScrollView* scrollView
				= dynamic_cast<TInlineScrollView*>(Parent());
			if (scrollView == NULL)
				return;

			float largeStep;
			float smallStep;
			scrollView->GetSteps(&smallStep, &largeStep);

			// pressing the option/command/control key scrolls faster
			if (modifiers() & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY))
				deltaY *= largeStep;
			else
				deltaY *= smallStep;

			scrollView->ScrollBy(deltaY);
			break;
		}

		case kAddTeam:
			AddTeam(message->FindInt32("team"), message->FindString("sig"));
			break;

		case kRemoveTeam:
		{
			team_id team = -1;
			message->FindInt32("team", &team);

			RemoveTeam(team, true);
			break;
		}

		case B_SOME_APP_QUIT:
		{
			team_id team = -1;
			message->FindInt32("team", &team);

			RemoveTeam(team, false);
			break;
		}

		case kMinimizeTeam:
		{
			index = message->FindInt32("itemIndex");
			item = dynamic_cast<TTeamMenuItem*>(ItemAt(index));
			if (item == NULL)
				break;

			TShowHideMenuItem::TeamShowHideCommon(B_MINIMIZE_WINDOW,
				item->Teams(),
				item->Menu()->ConvertToScreen(item->Frame()),
				true);
			break;
		}

		case kBringTeamToFront:
		{
			index = message->FindInt32("itemIndex");
			item = dynamic_cast<TTeamMenuItem*>(ItemAt(index));
			if (item == NULL)
				break;

			TShowHideMenuItem::TeamShowHideCommon(B_BRING_TO_FRONT,
				item->Teams(), item->Menu()->ConvertToScreen(item->Frame()),
				true);
			break;
		}

		default:
			BMenuBar::MessageReceived(message);
			break;
	}
}