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(); } }
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); }