diff --git a/Changelog b/Changelog new file mode 100644 index 000000000..e3635780b --- /dev/null +++ b/Changelog @@ -0,0 +1,6 @@ +* v1.0 (November 4th, 2019) + - Initial Release + +* v1.1 (, 2020) + - Fix dock widgets not filling their complete available space + - Allow tab re-ordering with mouse, via KDDockWidgets::Config::Flag_AllowReorderTabs. diff --git a/examples/dockwidgets/main.cpp b/examples/dockwidgets/main.cpp index 6643d8616..ae6a00cff 100644 --- a/examples/dockwidgets/main.cpp +++ b/examples/dockwidgets/main.cpp @@ -49,6 +49,9 @@ int main(int argc, char **argv) QCommandLineOption customStyle("p", QCoreApplication::translate("main", "Shows how to style framework internals via FrameworkWidgetFactory")); parser.addOption(customStyle); + QCommandLineOption reorderTabsOption("r", QCoreApplication::translate("main", "Support re-ordering tabs with mouse")); + parser.addOption(reorderTabsOption); + QCommandLineOption noTitleBars("t", QCoreApplication::translate("main", "Never show titlebars")); parser.addOption(noTitleBars); @@ -72,8 +75,14 @@ int main(int argc, char **argv) : MainWindowOption_HasCentralFrame; #endif + auto flags = KDDockWidgets::Config::self().flags(); if (parser.isSet(noTitleBars)) - KDDockWidgets::Config::self().setFlags(KDDockWidgets::Config::Flags() | KDDockWidgets::Config::Flag_HideTitleBarWhenTabsVisible | KDDockWidgets::Config::Flag_AlwaysShowTabs); + flags |= KDDockWidgets::Config::Flag_HideTitleBarWhenTabsVisible | KDDockWidgets::Config::Flag_AlwaysShowTabs; + + if (parser.isSet(reorderTabsOption)) + flags |= KDDockWidgets::Config::Flag_AllowReorderTabs; + + KDDockWidgets::Config::self().setFlags(flags); MyMainWindow mainWindow(options); mainWindow.resize(1200, 1200); diff --git a/src/Config.h b/src/Config.h index c44a986a4..2e4205e9c 100644 --- a/src/Config.h +++ b/src/Config.h @@ -64,7 +64,8 @@ class DOCKS_EXPORT Config Flag_NativeTitleBar = 1, ///> Enables the Native OS title bar on OSes that support it (Windows 10, macOS), ignored otherwise. This is mutually exclusive with Flag_AeroSnap Flag_AeroSnapWithClientDecos = 2, ///> Enables AeroSnap even if we're not using the native title bar. Only supported on Windows 10. Flag_HideTitleBarWhenTabsVisible = 8, ///> Hides the title bar if there's tabs visible. The empty space in the tab bar becomes draggable. - Flag_AlwaysShowTabs = 16, ///> Always show tabs, even if there's only one + Flag_AlwaysShowTabs = 16, ///> Always show tabs, even if there's only one, + Flag_AllowReorderTabs = 32, /// Allows user to re-order tabs by dragging them Flag_Default = Flag_AeroSnapWithClientDecos ///> The defaults }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/src/private/DragController.cpp b/src/private/DragController.cpp index 8644a48f6..2ddc5162e 100644 --- a/src/private/DragController.cpp +++ b/src/private/DragController.cpp @@ -155,17 +155,17 @@ bool StatePreDrag::handleMouseMove(QPoint globalPos) { if (q->m_draggable->dragCanStart(q->m_pressPos, globalPos)) { Q_EMIT q->manhattanLengthMove(); + return true; } - return true; + return false; } bool StatePreDrag::handleMouseButtonRelease(QPoint) { Q_EMIT q->dragCanceled(); - return true; + return false; } - StateDragging::StateDragging(DragController *parent) : StateBase(parent) { diff --git a/src/private/widgets/TabBarWidget.cpp b/src/private/widgets/TabBarWidget.cpp index e88afd9be..bd4162c99 100644 --- a/src/private/widgets/TabBarWidget.cpp +++ b/src/private/widgets/TabBarWidget.cpp @@ -27,8 +27,10 @@ */ #include "TabBarWidget_p.h" +#include "Config.h" #include +#include using namespace KDDockWidgets; @@ -36,6 +38,7 @@ TabBarWidget::TabBarWidget(TabWidget *parent) : QTabBar(parent->asWidget()) , TabBar(this, parent) { + setMovable(Config::self().flags() & Config::Flag_AllowReorderTabs); } int TabBarWidget::numDockWidgets() const @@ -53,3 +56,36 @@ void TabBarWidget::mousePressEvent(QMouseEvent *e) onMousePress(e->pos()); QTabBar::mousePressEvent(e); } + +bool TabBarWidget::dragCanStart(QPoint pressPos, QPoint pos) const +{ + // Here we allow the user to re-order tabs instead of dragging them off. + // To do that we just return false here, and QTabBar will handle the mouse event, assuming QTabBar::isMovable. + + const bool defaultResult = Draggable::dragCanStart(pressPos, pos); + + if (!defaultResult || !isMovable()) { + // Nothing more to do. If the drag wouldn't start anyway, return false. + // And if the tabs aren't movable, just return the default result, which just considers + // QApplication::startDragDistances + return defaultResult; + } + + const int index = tabAt(mapFromGlobal(pos)); + if (index == -1) + return defaultResult; + + const int deltaX = qAbs(pos.x() - pressPos.x()); + const int deltaY = qAbs(pos.y() - pressPos.y()); + + if (deltaY > 5 * QApplication::startDragDistance()) { + // Moving up or down too much results in a detach. No tab re-ordering allowed. + return true; + } else if (deltaY > QApplication::startDragDistance() && deltaX < QApplication::startDragDistance()) { + // Moved a bit up or down, but not left/right, then detach too. + // Only if it's going considerably left/right we allow to re-order tabs. + return true; + } + + return false; +} diff --git a/src/private/widgets/TabBarWidget_p.h b/src/private/widgets/TabBarWidget_p.h index 172b9216e..960a0b799 100644 --- a/src/private/widgets/TabBarWidget_p.h +++ b/src/private/widgets/TabBarWidget_p.h @@ -50,6 +50,7 @@ class DOCKS_EXPORT TabBarWidget : public QTabBar, public TabBar int numDockWidgets() const override; int tabAt(QPoint localPos) const override; protected: + bool dragCanStart(QPoint pressPos, QPoint pos) const override; void mousePressEvent(QMouseEvent *) override; };