Commit b4591229 authored by Pablo Rauzy's avatar Pablo Rauzy
Browse files

implements intuitive movements around split views

parent e796092e
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE gui SYSTEM "kpartgui.dtd">
<gui name="kate" version="96" translationDomain="kate">
<gui name="kate" version="97" translationDomain="kate">
<MenuBar>
<Menu name="file" noMerge="1">
<text>&amp;File</text>
......@@ -76,6 +76,11 @@
<Action name="go_prev_split_view"/>
<Action name="go_next_split_view"/>
<Separator/>
<Action name="go_left_split_view"/>
<Action name="go_right_split_view"/>
<Action name="go_upward_split_view"/>
<Action name="go_downward_split_view"/>
<Separator/>
<Action name="view_split_vert"/>
<Action name="view_split_horiz"/>
<Action name="view_split_vert_move_doc"/>
......
......@@ -176,6 +176,7 @@ void KateViewManager::setupActions()
goNext = m_mainWindow->actionCollection()->addAction(QStringLiteral("go_next_split_view"));
goNext->setText(i18n("Next Split View"));
goNext->setIcon(QIcon::fromTheme(QStringLiteral("go-next-view")));
m_mainWindow->actionCollection()->setDefaultShortcut(goNext, Qt::Key_F8);
connect(goNext, &QAction::triggered, this, &KateViewManager::activateNextView);
......@@ -183,11 +184,44 @@ void KateViewManager::setupActions()
goPrev = m_mainWindow->actionCollection()->addAction(QStringLiteral("go_prev_split_view"));
goPrev->setText(i18n("Previous Split View"));
goPrev->setIcon(QIcon::fromTheme(QStringLiteral("go-previous-view")));
m_mainWindow->actionCollection()->setDefaultShortcut(goPrev, Qt::SHIFT | Qt::Key_F8);
connect(goPrev, &QAction::triggered, this, &KateViewManager::activatePrevView);
goPrev->setWhatsThis(i18n("Make the previous split view the active one."));
goLeft = m_mainWindow->actionCollection()->addAction(QStringLiteral("go_left_split_view"));
goLeft->setText(i18n("Left Split View"));
goLeft->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left")));
// m_mainWindow->actionCollection()->setDefaultShortcut(goLeft, Qt::ALT | Qt::Key_Left);
connect(goLeft, &QAction::triggered, this, &KateViewManager::activateLeftView);
goLeft->setWhatsThis(i18n("Make the split view intuitively on the left the active one."));
goRight = m_mainWindow->actionCollection()->addAction(QStringLiteral("go_right_split_view"));
goRight->setText(i18n("Right Split View"));
goRight->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right")));
// m_mainWindow->actionCollection()->setDefaultShortcut(goRight, Qt::ALT | Qt::Key_Right);
connect(goRight, &QAction::triggered, this, &KateViewManager::activateRightView);
goRight->setWhatsThis(i18n("Make the split view intuitively on the right the active one."));
goUp = m_mainWindow->actionCollection()->addAction(QStringLiteral("go_upward_split_view"));
goUp->setText(i18n("Upward Split View"));
goUp->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
// m_mainWindow->actionCollection()->setDefaultShortcut(goUp, Qt::ALT | Qt::Key_Up);
connect(goUp, &QAction::triggered, this, &KateViewManager::activateUpwardView);
goUp->setWhatsThis(i18n("Make the split view intuitively upward the active one."));
goDown = m_mainWindow->actionCollection()->addAction(QStringLiteral("go_downward_split_view"));
goDown->setText(i18n("Downward Split View"));
goDown->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
// m_mainWindow->actionCollection()->setDefaultShortcut(goDown, Qt::ALT | Qt::Key_Down);
connect(goDown, &QAction::triggered, this, &KateViewManager::activateDownwardView);
goDown->setWhatsThis(i18n("Make the split view intuitively downward the active one."));
QAction *a = m_mainWindow->actionCollection()->addAction(QStringLiteral("view_split_move_right"));
a->setText(i18n("Move Splitter Right"));
connect(a, &QAction::triggered, this, &KateViewManager::moveSplitterRight);
......@@ -775,6 +809,90 @@ void KateViewManager::activatePrevView()
activateView((*it)->currentView());
}
void KateViewManager::activateLeftView()
{
activateIntuitiveNeighborView(Qt::Horizontal, 0);
}
void KateViewManager::activateRightView()
{
activateIntuitiveNeighborView(Qt::Horizontal, 1);
}
void KateViewManager::activateUpwardView()
{
activateIntuitiveNeighborView(Qt::Vertical, 0);
}
void KateViewManager::activateDownwardView()
{
activateIntuitiveNeighborView(Qt::Vertical, 1);
}
void KateViewManager::activateIntuitiveNeighborView(Qt::Orientation o, int dir)
{
KateViewSpace *currentViewSpace = activeViewSpace();
if (!currentViewSpace) {
return;
}
KateViewSpace *target = findIntuitiveNeighborView(qobject_cast<KateSplitter *>(currentViewSpace->parentWidget()), currentViewSpace, o, dir);
if (target) {
setActiveSpace(target);
activateView(target->currentView());
}
}
KateViewSpace *KateViewManager::findIntuitiveNeighborView(KateSplitter *splitter, QWidget *widget, Qt::Orientation o, int dir)
{
Q_ASSERT(dir == 0 || dir == 1); // 0 for right or up ; 1 for left or down: 1
if (!splitter) {
return nullptr;
}
if (splitter->count() == 1) { // root view space, nothing to do
return nullptr;
}
int widgetIndex = splitter->indexOf(widget);
// if the orientation is the same as the desired move, maybe we can move in the current splitter
if (splitter->orientation() == o && ((dir == 1 && widgetIndex == 0) || (dir == 0 && widgetIndex == 1))) {
// make our move
QWidget *target = splitter->widget(dir);
// try to see if we are next to a view space and move to it
KateViewSpace *targetViewSpace = qobject_cast<KateViewSpace *>(target);
if (targetViewSpace) {
return targetViewSpace;
}
// otherwise we found a splitter and need to go down the splitter tree to the desired view space
KateSplitter *targetSplitter = qobject_cast<KateSplitter *>(target);
// we already made our move so we need to go down to the opposite direction :
// e.g.: [ active | [ [ x | y ] | z ] ] going right we find a splitter and want to go to x
int childIndex = 1 - dir;
QWidget *targetChild = nullptr;
while (targetSplitter) {
if (targetSplitter->orientation() == o) { // as long as the orientation is the same we move down in the desired direction
targetChild = targetSplitter->widget(childIndex);
} else { // otherwise we need to find in which of the two child to go based on the cursor position
QPoint cursorCoord = activeViewSpace()->mapToGlobal(QPoint(0, 0)) + activeView()->cursorPositionCoordinates();
QPoint targetSplitterCoord = targetSplitter->widget(0)->mapToGlobal(QPoint(0, 0));
if ((o == Qt::Horizontal && (targetSplitterCoord.y() + targetSplitter->sizes()[0] > cursorCoord.y()))
|| (o == Qt::Vertical && (targetSplitterCoord.x() + targetSplitter->sizes()[0] > cursorCoord.x()))) {
targetChild = targetSplitter->widget(0);
} else {
targetChild = targetSplitter->widget(1);
}
}
// if we found a view space we're done!
targetViewSpace = qobject_cast<KateViewSpace *>(targetChild);
if (targetViewSpace) {
return targetViewSpace;
}
// otherwise continue
targetSplitter = qobject_cast<KateSplitter *>(targetChild);
}
}
// otherwise try to go up in the splitter tree
return findIntuitiveNeighborView(qobject_cast<KateSplitter *>(splitter->parentWidget()), splitter, o, dir);
}
void KateViewManager::documentWillBeDeleted(KTextEditor::Document *doc)
{
/**
......
......@@ -95,6 +95,14 @@ public Q_SLOTS:
void activateNextView();
void activatePrevView();
void activateLeftView();
void activateRightView();
void activateUpwardView();
void activateDownwardView();
private:
void activateIntuitiveNeighborView(Qt::Orientation o, int dir);
KateViewSpace *findIntuitiveNeighborView(KateSplitter *splitter, QWidget *widget, Qt::Orientation o, int dir);
Q_SIGNALS:
void viewChanged(KTextEditor::View *);
......@@ -307,6 +315,10 @@ private:
QAction *m_hideOtherViews = nullptr;
QAction *goNext = nullptr;
QAction *goPrev = nullptr;
QAction *goLeft = nullptr;
QAction *goRight = nullptr;
QAction *goUp = nullptr;
QAction *goDown = nullptr;
std::vector<KateViewSpace *> m_viewSpaceList;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment