From 10802dad9c9e20d0eef521324afcba9f30b2aaf5 Mon Sep 17 00:00:00 2001 From: Rasmus Karlsson Date: Sat, 7 Apr 2018 12:43:28 +0200 Subject: [PATCH] Closing splits now tries to focus a neighbouring split Fixes #176 --- src/widgets/splitcontainer.cpp | 67 +++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/widgets/splitcontainer.cpp b/src/widgets/splitcontainer.cpp index f7d6f6894..265625c9f 100644 --- a/src/widgets/splitcontainer.cpp +++ b/src/widgets/splitcontainer.cpp @@ -74,30 +74,77 @@ std::pair SplitContainer::removeFromLayout(Split *widget) this->refreshTitle(); } - // remove from box and return location + Split *neighbouringSplit = nullptr; + + // Position the split was found at + int positionX = -1, positionY = -1; + + bool removed = false; + + QVBoxLayout *layoutToRemove = nullptr; + + // Find widget in box, remove it, return its position for (int i = 0; i < this->ui.hbox.count(); ++i) { auto vbox = static_cast(this->ui.hbox.itemAt(i)); - for (int j = 0; j < vbox->count(); ++j) { + auto vboxCount = vbox->count(); + + for (int j = 0; j < vboxCount; ++j) { if (vbox->itemAt(j)->widget() != widget) { + neighbouringSplit = dynamic_cast(vbox->itemAt(j)->widget()); + + if (removed && neighbouringSplit != nullptr) { + // The widget we searched for has been found, and we have a split to switch + // focus to + break; + } + continue; } + removed = true; + positionX = i; + + // Remove split from box widget->setParent(nullptr); - bool isLastItem = vbox->count() == 0; - - if (isLastItem) { - this->ui.hbox.removeItem(vbox); - - delete vbox; + if (vbox->count() == 0) { + // The split was the last item remaining in the vbox + // Remove the vbox once all iteration is done + layoutToRemove = vbox; + positionY = -1; + break; } - return std::pair(i, isLastItem ? -1 : j); + // Don't break here yet, we want to keep iterating this vbox if possible to find the + // closest still-alive neighbour that we can switch focus to + positionY = j; + + --j; + --vboxCount; + } + + if (removed && neighbouringSplit != nullptr) { + // The widget we searched for has been found, and we have a split to switch focus to + break; } } - return std::pair(-1, -1); + if (removed) { + if (layoutToRemove != nullptr) { + // The split we removed was the last split in its box. Remove the box + // We delay the removing of the box so we can keep iterating over hbox safely + this->ui.hbox.removeItem(layoutToRemove); + delete layoutToRemove; + } + + if (neighbouringSplit != nullptr) { + // We found a neighbour split we can switch focus to + neighbouringSplit->giveFocus(Qt::MouseFocusReason); + } + } + + return std::make_pair(positionX, positionY); } void SplitContainer::addToLayout(Split *widget, std::pair position)