void
SATGroup::_SplitGroupIfNecessary(WindowArea* removedArea)
{
	// if there are windows stacked in the area we don't need to split
	if (!removedArea || removedArea->WindowList().CountItems() > 1)
		return;

	WindowAreaList neighbourWindows;

	_FillNeighbourList(neighbourWindows, removedArea);

	bool ownGroupProcessed = false;
	WindowAreaList newGroup;
	while (_FindConnectedGroup(neighbourWindows, removedArea, newGroup)) {
		STRACE_SAT("Connected group found; %i window(s)\n",
			(int)newGroup.CountItems());
		if (newGroup.CountItems() == 1
			&& newGroup.ItemAt(0)->WindowList().CountItems() == 1) {
			SATWindow* window = newGroup.ItemAt(0)->WindowList().ItemAt(0);
			RemoveWindow(window);
			_EnsureGroupIsOnScreen(window->GetGroup());
		} else if (ownGroupProcessed)
			_SpawnNewGroup(newGroup);
		else {
			_EnsureGroupIsOnScreen(this);
			ownGroupProcessed = true;
		}

		newGroup.MakeEmpty();
	}
}
Esempio n. 2
0
void
SATGroup::_FollowSeed(WindowArea* area, WindowArea* veto,
	WindowAreaList& seedList, WindowAreaList& newGroup)
{
	WindowAreaList neighbours;
	_FillNeighbourList(neighbours, area);
	for (int i = 0; i < neighbours.CountItems(); i++) {
		WindowArea* currentArea = neighbours.ItemAt(i);
		if (currentArea != veto && !newGroup.HasItem(currentArea)) {
			newGroup.AddItem(currentArea);
			// if we get a area from the seed list it is not a seed any more
			seedList.RemoveItem(currentArea);
		} else {
			// don't _FollowSeed of invalid areas
			neighbours.RemoveItemAt(i);
			i--;
		}
	}

	for (int i = 0; i < neighbours.CountItems(); i++)
		_FollowSeed(neighbours.ItemAt(i), veto, seedList, newGroup);
}
void
SATGroup::_SpawnNewGroup(const WindowAreaList& newGroup)
{
	STRACE_SAT("SATGroup::_SpawnNewGroup\n");
	SATGroup* group = new (std::nothrow)SATGroup;
	if (!group)
		return;
	BReference<SATGroup> groupRef;
	groupRef.SetTo(group, true);

	for (int i = 0; i < newGroup.CountItems(); i++)
		newGroup.ItemAt(i)->PropagateToGroup(group);

	_EnsureGroupIsOnScreen(group);
}