[krita] krita: Fix Drag&Drop of layers in tabbed mode
Dmitry Kazakov
dimula73 at gmail.com
Fri Jan 15 14:19:15 UTC 2016
Git commit b7170a05e3697419a3cd14ed905fe8428a1a94dd by Dmitry Kazakov.
Committed on 15/01/2016 at 14:18.
Pushed by dkazakov into branch 'master'.
Fix Drag&Drop of layers in tabbed mode
Now you can drag layers even when Krita works in tabbed mode. Just drag the
layer over the tab, wait for a second and it'll automatically switch to the
tab under the cursor
CC:kimageshop at kde.org
M +10 -2 krita/image/kis_signal_compressor_with_param.h
M +66 -2 krita/ui/KisMainWindow.cpp
M +3 -0 krita/ui/KisMainWindow.h
http://commits.kde.org/krita/b7170a05e3697419a3cd14ed905fe8428a1a94dd
diff --git a/krita/image/kis_signal_compressor_with_param.h b/krita/image/kis_signal_compressor_with_param.h
index 9700e72..94c751a 100644
--- a/krita/image/kis_signal_compressor_with_param.h
+++ b/krita/image/kis_signal_compressor_with_param.h
@@ -93,8 +93,8 @@ public:
using CallbackFunction = std::function<void (T)>;
public:
- KisSignalCompressorWithParam(int delay, CallbackFunction function)
- : m_compressor(delay, KisSignalCompressor::FIRST_ACTIVE),
+KisSignalCompressorWithParam(int delay, CallbackFunction function, KisSignalCompressor::Mode mode = KisSignalCompressor::FIRST_ACTIVE)
+ : m_compressor(delay, mode),
m_function(function)
{
std::function<void ()> callback(
@@ -113,6 +113,14 @@ public:
m_compressor.start();
}
+ void stop() {
+ m_compressor.stop();
+ }
+
+ bool isActive() const {
+ return m_compressor.isActive();
+ }
+
private:
void fakeSlotTimeout() {
m_function(m_currentParamValue);
diff --git a/krita/ui/KisMainWindow.cpp b/krita/ui/KisMainWindow.cpp
index c47952f..0e5f0cb 100644
--- a/krita/ui/KisMainWindow.cpp
+++ b/krita/ui/KisMainWindow.cpp
@@ -125,6 +125,7 @@
#include "kis_icon_utils.h"
#include <KisImportExportFilter.h>
#include <KisDocumentEntry.h>
+#include "kis_signal_compressor_with_param.h"
class ToolDockerFactory : public KoDockFactoryBase
{
@@ -150,7 +151,8 @@ class Q_DECL_HIDDEN KisMainWindow::Private
{
public:
Private(KisMainWindow *parent)
- : viewManager(0)
+ : q(parent)
+ , viewManager(0)
, firstTime(true)
, windowSizeDirty(false)
, readOnly(false)
@@ -198,6 +200,7 @@ public:
qDeleteAll(toolbarList);
}
+ KisMainWindow *q;
KisViewManager *viewManager;
QPointer<KisView> activeView;
@@ -269,10 +272,22 @@ public:
QByteArray lastExportedFormat;
int lastExportSpecialOutputFlag;
+ QScopedPointer<KisSignalCompressorWithParam<int> > tabSwitchCompressor;
KisActionManager * actionManager() {
return viewManager->actionManager();
}
+
+ QTabBar* findTabBarHACK() {
+ QObjectList objects = mdiArea->children();
+ Q_FOREACH (QObject *object, objects) {
+ QTabBar *bar = qobject_cast<QTabBar*>(object);
+ if (bar) {
+ return bar;
+ }
+ }
+ return 0;
+ }
};
KisMainWindow::KisMainWindow()
@@ -460,6 +475,15 @@ KisMainWindow::KisMainWindow()
d->viewManager->updateIcons();
QTimer::singleShot(1000, this, SLOT(checkSanity()));
+
+ {
+ using namespace std::placeholders; // For _1 placeholder
+ std::function<void (int)> callback(
+ std::bind(&KisMainWindow::switchTab, this, _1));
+
+ d->tabSwitchCompressor.reset(
+ new KisSignalCompressorWithParam<int>(500, callback, KisSignalCompressor::FIRST_INACTIVE));
+ }
}
void KisMainWindow::setNoCleanup(bool noCleanup)
@@ -1195,7 +1219,10 @@ void KisMainWindow::setActiveView(KisView* view)
void KisMainWindow::dragEnterEvent(QDragEnterEvent *event)
{
- if (event->mimeData()->hasUrls()) {
+ if (event->mimeData()->hasUrls() ||
+ event->mimeData()->hasFormat("application/x-krita-node") ||
+ event->mimeData()->hasFormat("application/x-qt-image")) {
+
event->accept();
}
}
@@ -1209,6 +1236,43 @@ void KisMainWindow::dropEvent(QDropEvent *event)
}
}
+void KisMainWindow::dragMoveEvent(QDragMoveEvent * event)
+{
+ QTabBar *tabBar = d->findTabBarHACK();
+
+ if (!tabBar && d->mdiArea->viewMode() == QMdiArea::TabbedView) {
+ qWarning() << "WARNING!!! Cannot find QTabBar in the main window! Looks like Qt has changed behavior. Drag & Drop between multiple tabs might not work properly (tabs will not switch automatically)!";
+ }
+
+ if (tabBar && tabBar->isVisible()) {
+ QPoint pos = tabBar->mapFromGlobal(mapToGlobal(event->pos()));
+ if (tabBar->rect().contains(pos)) {
+ const int tabIndex = tabBar->tabAt(pos);
+
+ if (tabIndex >= 0 && tabBar->currentIndex() != tabIndex) {
+ d->tabSwitchCompressor->start(tabIndex);
+ }
+ } else if (d->tabSwitchCompressor->isActive()) {
+ d->tabSwitchCompressor->stop();
+ }
+ }
+}
+
+void KisMainWindow::dragLeaveEvent(QDragLeaveEvent * event)
+{
+ if (d->tabSwitchCompressor->isActive()) {
+ d->tabSwitchCompressor->stop();
+ }
+}
+
+void KisMainWindow::switchTab(int index)
+{
+ QTabBar *tabBar = d->findTabBarHACK();
+ if (!tabBar) return;
+
+ tabBar->setCurrentIndex(index);
+}
+
void KisMainWindow::slotFileNew()
{
KisPart::instance()->showStartUpWidget(this, true /*Always show widget*/);
diff --git a/krita/ui/KisMainWindow.h b/krita/ui/KisMainWindow.h
index 8f04a7d..be776d3 100644
--- a/krita/ui/KisMainWindow.h
+++ b/krita/ui/KisMainWindow.h
@@ -368,6 +368,8 @@ protected:
// QWidget overrides
virtual void dragEnterEvent(QDragEnterEvent * event);
virtual void dropEvent(QDropEvent * event);
+ virtual void dragMoveEvent(QDragMoveEvent * event);
+ virtual void dragLeaveEvent(QDragLeaveEvent * event);
void setToolbarList(QList<QAction*> toolbarList);
@@ -443,6 +445,7 @@ protected:
private Q_SLOTS:
void initializeGeometry();
void showManual();
+ void switchTab(int index);
private:
class Private;
More information about the kimageshop
mailing list