Beispiel #1
0
void
TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
{
	if (!message) {
		// force a cleanup
		_FinishedDrag();
		BMenuBar::MouseMoved(where, code, message);
		return;
	}

	uint32 buttons;
	if (!(Window()->CurrentMessage())
		|| Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons)
		< B_OK)
		buttons = 0;

	if (buttons == 0)
		return;

	switch (code) {
		case B_ENTERED_VIEW:
			// fPreviousDragTargetItem should always be NULL here anyways.
			if (fPreviousDragTargetItem)
				_FinishedDrag();

			fBarView->CacheDragData(message);
			fPreviousDragTargetItem = NULL;
			break;

		case B_OUTSIDE_VIEW:
			// NOTE: Should not be here, but for the sake of defensive
			// programming...
		case B_EXITED_VIEW:
			_FinishedDrag();
			break;

		case B_INSIDE_VIEW:
			if (fBarView->Dragging()) {
				TTeamMenuItem* item = NULL;
				for (int32 i = 0; i < CountItems(); 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;
	}
}
Beispiel #2
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;
		}
	}
}
Beispiel #3
0
void
TExpandoMenuBar::CheckItemSizes(int32 delta)
{
	float width = Frame().Width();
	int32 count = CountItems();
	bool reset = false;
	float newWidth = 0;
	float fullWidth = (sMinimumWindowWidth * count);

	if (!fBarView->Vertical()) {
		// in this case there are 2 extra items:
		//   - The Be Menu
		//   - The little separator item
		fullWidth = fullWidth - (sMinimumWindowWidth * 2)
			+ (fBeMenuWidth + kSepItemWidth);
		width -= (fBeMenuWidth + kSepItemWidth);
		count -= 2;
	}

	if (delta >= 0 && fullWidth > width) {
		fOverflow = true;
		reset = true;
		newWidth = floorf(width / count);
	} else if (delta < 0 && fOverflow) {
		reset = true;
		if (fullWidth > width)
			newWidth = floorf(width / count);
		else
			newWidth = sMinimumWindowWidth;
	}
	if (newWidth > sMinimumWindowWidth)
		newWidth = sMinimumWindowWidth;

	if (reset) {
		SetMaxContentWidth(newWidth);
		if (newWidth == sMinimumWindowWidth)
			fOverflow = false;
		InvalidateLayout();

		for (int32 index = fFirstApp; ; index++) {
			TTeamMenuItem* item = (TTeamMenuItem*)ItemAt(index);
			if (!item)
				break;
			item->SetOverrideWidth(newWidth);
		}

		Invalidate();
		Window()->UpdateIfNeeded();
	}
}
Beispiel #4
0
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
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());
	}
}
Beispiel #6
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;
		}
	}
}
Beispiel #7
0
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();
}
Beispiel #8
0
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());
}
Beispiel #9
0
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());
}
Beispiel #10
0
void
TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
{
	if (message == NULL) {
		// force a cleanup
		_FinishedDrag();

		switch (code) {
			case B_ENTERED_VIEW:
			case B_INSIDE_VIEW:
			{
				TTeamMenuItem* item = TeamItemAtPoint(where);
				if (item == NULL) {
					// item is NULL, break out
					fLastMousedOverItem = NULL;
					break;
				}

				if (item->HasLabel()) {
					// item has a visible label, set the item and break out
					fLastMousedOverItem = item;
					break;
				}

				if (item == fLastMousedOverItem) {
					// already set the tooltip for this item, break out
					break;
				}

				// new item, update the tooltip with the item name
				SetToolTip(item->Name());

				// save the current item for the next MouseMoved() call
				fLastMousedOverItem = item;

				break;
			}

			case B_OUTSIDE_VIEW:
			case B_EXITED_VIEW:
				fLastMousedOverItem = NULL;
				break;
		}

		BMenuBar::MouseMoved(where, code, message);
		return;
	}

	uint32 buttons;
	if (Window()->CurrentMessage() == NULL
		|| Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons)
			< B_OK) {
		buttons = 0;
	}

	if (buttons == 0)
		return;

	switch (code) {
		case B_ENTERED_VIEW:
			// fPreviousDragTargetItem should always be NULL here anyways.
			if (fPreviousDragTargetItem)
				_FinishedDrag();

			fBarView->CacheDragData(message);
			fPreviousDragTargetItem = NULL;
			break;

		case B_OUTSIDE_VIEW:
			// NOTE: Should not be here, but for the sake of defensive
			// programming...
		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;
	}
}
Beispiel #11
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;
	}
}
Beispiel #12
0
void
TExpandoMenuBar::CheckItemSizes(int32 delta)
{
	if (fBarView->Vertical())
		return;

	int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize();
	float maxContentWidth = sMinimumWindowWidth + iconSize - kMinimumIconSize;

	// There are 2 extra items:
	//     The Be Menu
	//     The little separator item
	int32 count = CountItems() - 2;
	float maxWidth = Frame().Width() - fDeskbarMenuWidth - kSepItemWidth * 2;
	float fullWidth = maxContentWidth * count + fDeskbarMenuWidth
		+ kSepItemWidth;
	float iconOnlyWidth = kIconPadding + iconSize + kIconPadding;

	bool reset = false;
	float newWidth = 0.0f;

	if (delta >= 0 && fullWidth > maxWidth) {
		fOverflow = true;
		reset = true;
		if (fDrawLabel)
			newWidth = floorf(maxWidth / count);
		else
			newWidth = iconOnlyWidth;
	} else if (delta < 0 && fOverflow) {
		reset = true;
		if (fullWidth > maxWidth) {
			if (fDrawLabel)
				newWidth = floorf(maxWidth / count);
			else
				newWidth = iconOnlyWidth;
		} else
			newWidth = maxContentWidth;
	}

	if (newWidth > maxContentWidth)
		newWidth = maxContentWidth;

	if (reset) {
		SetMaxContentWidth(newWidth);
		if (newWidth == maxContentWidth)
			fOverflow = false;
		InvalidateLayout();

		for (int32 index = fFirstApp; ; index++) {
			TTeamMenuItem* item = (TTeamMenuItem*)ItemAt(index);
			if (!item)
				break;

			if (!fDrawLabel && newWidth > iconOnlyWidth) {
				item->SetOverrideWidth(iconOnlyWidth);
			} else {
				item->SetOverrideWidth(newWidth);
			}
		}

		Invalidate();
		Window()->UpdateIfNeeded();
	}
}
Beispiel #13
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);
}
Beispiel #14
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);
}
Beispiel #15
0
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;
	}
}
Beispiel #16
0
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();
}
Beispiel #17
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;
}
Beispiel #18
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);
}
Beispiel #19
0
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();
}
Beispiel #20
0
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();
}
Beispiel #21
0
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;
}
Beispiel #22
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;
	}
}
Beispiel #23
0
void
TExpandoMenuBar::CheckItemSizes(int32 delta)
{
	if (fBarView->Vertical())
		return;

	bool drawLabels = !static_cast<TBarApp*>(be_app)->Settings()->hideLabels;

	float maxWidth = fBarView->DragRegion()->Frame().left
		- fDeskbarMenuWidth - kSepItemWidth;
	int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize();
	float iconOnlyWidth = kIconPadding + iconSize + kIconPadding;
	float minItemWidth = drawLabels
		? iconOnlyWidth + kMinMenuItemWidth
		: iconOnlyWidth - kIconPadding;
	float maxItemWidth = drawLabels
		? gMinimumWindowWidth + iconSize - kMinimumIconSize
		: iconOnlyWidth;
	float menuWidth = maxItemWidth * CountItems() + fDeskbarMenuWidth
		+ kSepItemWidth;

	bool reset = false;
	float newWidth = -1.0f;

	if (delta >= 0 && menuWidth > maxWidth) {
		fOverflow = true;
		reset = true;
		newWidth = floorf(maxWidth / CountItems());
	} else if (delta < 0 && fOverflow) {
		reset = true;
		if (menuWidth > maxWidth)
			newWidth = floorf(maxWidth / CountItems());
		else
			newWidth = maxItemWidth;
	}

	if (reset) {
		if (newWidth > maxItemWidth)
			newWidth = maxItemWidth;
		else if (newWidth < minItemWidth)
			newWidth = minItemWidth;

		SetMaxContentWidth(newWidth);
		if (newWidth == maxItemWidth)
			fOverflow = false;

		InvalidateLayout();

		for (int32 index = 0; ; index++) {
			TTeamMenuItem* item = (TTeamMenuItem*)ItemAt(index);
			if (item == NULL)
				break;

			item->SetOverrideWidth(newWidth);
		}

		Invalidate();
		Window()->UpdateIfNeeded();
		fBarView->CheckForScrolling();
	}
}
Beispiel #24
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;
}
Beispiel #25
0
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();
}