1
0
Fork 0
This commit is contained in:
Duncan Ogilvie 2019-11-22 04:30:52 +01:00
parent 824100eea8
commit 4ab268209d
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
30 changed files with 3122 additions and 10 deletions

2
deps

@ -1 +1 @@
Subproject commit be0d812e919272f86be3a819c986db03f1c78859
Subproject commit c395eb027c2b3b58969e60da2c40de469d167641

View File

@ -6,6 +6,7 @@
#include <QFileDialog>
#include <QMimeData>
#include <QDesktopServices>
#include <kddockwidgets/DockWidget.h>
#include "Configuration.h"
#include "SettingsDialog.h"
#include "AppearanceDialog.h"
@ -56,7 +57,7 @@
QString MainWindow::windowTitle = "";
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent),
: KDDockWidgets::MainWindow("x64dbg_MainWindow", KDDockWidgets::MainWindowOption_None, parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
@ -217,7 +218,7 @@ MainWindow::MainWindow(QWidget* parent)
// Add all widgets to the list
mWidgetList.push_back(WidgetInfo(mCpuWidget, "CPUTab"));
mWidgetList.push_back(WidgetInfo(mGraphView, "GraphTab"));
/*mWidgetList.push_back(WidgetInfo(mGraphView, "GraphTab"));
mWidgetList.push_back(WidgetInfo(mLogView, "LogTab"));
mWidgetList.push_back(WidgetInfo(mNotesManager, "NotesTab"));
mWidgetList.push_back(WidgetInfo(mBreakpointsView, "BreakpointsTab"));
@ -230,15 +231,32 @@ MainWindow::MainWindow(QWidget* parent)
mWidgetList.push_back(WidgetInfo(mReferenceManager, "ReferencesTab"));
mWidgetList.push_back(WidgetInfo(mThreadView, "ThreadsTab"));
mWidgetList.push_back(WidgetInfo(mHandlesView, "HandlesTab"));
mWidgetList.push_back(WidgetInfo(mTraceBrowser, "TraceTab"));
mWidgetList.push_back(WidgetInfo(mTraceBrowser, "TraceTab"));*/
{
KDDockWidgets::DockWidget::List dockwidgets;
for(WidgetInfo & info : mWidgetList)
{
auto dock = new KDDockWidgets::DockWidget(info.nativeName);
dock->setWidget(info.widget);
dock->setTitle(info.widget->windowTitle());
dock->show();
dockwidgets << dock;
info.widget->show();
}
addDockWidget(dockwidgets[0], KDDockWidgets::Location_None);
/*for(int i = 1; i < dockwidgets.size(); i++)
dockwidgets[i - 1]->addDockWidgetAsTab(dockwidgets[i]);*/
}
/*
// If LoadSaveTabOrder disabled, load tabs in default order
if(!ConfigBool("Gui", "LoadSaveTabOrder"))
loadTabDefaultOrder();
else
loadTabSavedOrder();
setCentralWidget(mTabWidget);
setCentralWidget(mTabWidget);*/
// Setup the command and status bars
setupCommandBar();
@ -348,7 +366,7 @@ MainWindow::MainWindow(QWidget* parent)
connect(mCpuWidget->getStackWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget()));
connect(mTabWidget, SIGNAL(tabMovedTabWidget(int, int)), this, SLOT(tabMovedSlot(int, int)));
//connect(mTabWidget, SIGNAL(tabMovedTabWidget(int, int)), this, SLOT(tabMovedSlot(int, int)));
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcuts()));
// Setup favourite tools menu
@ -378,7 +396,7 @@ MainWindow::MainWindow(QWidget* parent)
mCpuWidget->setDisasmFocus();
QTimer::singleShot(0, this, SLOT(loadWindowSettings()));
//QTimer::singleShot(0, this, SLOT(loadWindowSettings()));
}
MainWindow::~MainWindow()
@ -498,7 +516,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
duint noClose = 0;
if(bCanClose)
{
saveWindowSettings();
//saveWindowSettings();
}
if(BridgeSettingGetUint("Gui", "NoCloseDialog", &noClose) && noClose)
mCloseDialog->hide();
@ -527,6 +545,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
void MainWindow::setTab(QWidget* widget)
{
return; //TODO
// shown tabs
for(int i = 0; i < mTabWidget->count(); i++)
{
@ -947,7 +966,7 @@ void MainWindow::dropEvent(QDropEvent* pEvent)
bool MainWindow::event(QEvent* event)
{
// just make sure mTabWidget take current view as the latest
if(event->type() == QEvent::WindowActivate && this->isActiveWindow())
if(false && event->type() == QEvent::WindowActivate && this->isActiveWindow())
{
mTabWidget->setCurrentIndex(mTabWidget->currentIndex());
}
@ -1665,6 +1684,7 @@ void MainWindow::showQWidgetTab(QWidget* qWidget)
void MainWindow::closeQWidgetTab(QWidget* qWidget)
{
return;
for(int i = 0; i < mTabWidget->count(); i++)
{
if(mTabWidget->widget(i) == qWidget)
@ -1682,6 +1702,7 @@ void MainWindow::executeOnGuiThread(void* cbGuiThread, void* userdata)
void MainWindow::tabMovedSlot(int from, int to)
{
return;
for(int i = 0; i < mTabWidget->count(); i++)
{
// Remove space in widget name and append Tab to get config settings (CPUTab, MemoryMapTab, etc...)

View File

@ -2,6 +2,7 @@
#define MAINWINDOW_H
#include <QMainWindow>
#include <kddockwidgets/MainWindow.h>
#include "Imports.h"
class QDragEnterEvent;
@ -40,7 +41,7 @@ namespace Ui
class MainWindow;
}
class MainWindow : public QMainWindow
class MainWindow : public KDDockWidgets::MainWindow
{
Q_OBJECT

View File

@ -0,0 +1,144 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief Application-wide config to tune certain behaviours of the framework.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_DOCKWIDGETS_CONFIG_H
#define KD_DOCKWIDGETS_CONFIG_H
#include "docks_export.h"
class QQmlEngine;
namespace KDDockWidgets
{
class DockWidgetBase;
class FrameworkWidgetFactory;
typedef KDDockWidgets::DockWidgetBase* (*DockWidgetFactoryFunc)(const QString & name);
/**
* @brief Singleton to allow to choose certain behaviours of the framework.
*
* The setters should only be used before creating any DockWidget or MainWindow,
* preferably right after creating the QApplication.
*/
class DOCKS_EXPORT Config
{
public:
///@brief returns the singleton Config instance
static Config & self();
///@brief destructor, called at shutdown
~Config();
///@brief Flag enum to tune certain behaviours, the defaults are Flag_Default
enum Flag
{
Flag_None = 0, ///> No option set
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_Default = Flag_AeroSnapWithClientDecos ///> The defaults
};
Q_DECLARE_FLAGS(Flags, Flag)
///@brief returns the chosen flags
Flags flags() const;
///@brief setter for the flags
///@param flags the flags to set
///Not all flags are guaranteed to be set, as the OS might not supported them
///Call @ref flags() after the setter if you need to know what was really set
void setFlags(Flags flags);
/**
* @brief Registers a DockWidgetFactoryFunc.
*
* This is optional, the default is nullptr.
*
* A DockWidgetFactoryFunc is a function that receives a dock widget name
* and returns a DockWidget instance.
*
* While restoring, @ref LayoutSaver requires all dock widgets to exist.
* If a DockWidget doesn't exist then a DockWidgetFactoryFunc function is
* required, so the layout saver can ask to create the DockWidget and then
* restore it.
*/
void setDockWidgetFactoryFunc(DockWidgetFactoryFunc);
///@brief Returns the DockWidgetFactoryFunc.
///nullptr by default
DockWidgetFactoryFunc dockWidgetFactoryFunc() const;
/**
* @brief Sets the WidgetFactory.
*
* By default DefaultWidgetFactory is used, which gives you FrameWidget, TitleBarWidget,
* TabBarWidget, TabWidgetWidget etc. You can set your own factory, to supply your own variants
* of those classes, for the purposes of changing GUI appearance and such.
*
* Also potentially useful to return QtQuick classes instead of the QtWidget based ones.
* Ownership is taken.
*/
void setFrameworkWidgetFactory(FrameworkWidgetFactory*);
///@brief getter for the framework widget factory
FrameworkWidgetFactory* frameworkWidgetFactory() const;
/**
* @brief Returns the thickness of the separator.
*
* Returns the width if the separator is vertical, otherwise the height.
* If @p staticSeparator is true, then returns for the static separators.
* The static separators are the ones at the edges of the window (top, left, bottom, right).
*
* Default is 0px for static separators and 5px for normal separators.
*/
int separatorThickness(bool staticSeparator) const;
///@brief setter for @ref separatorThickness
///Note: Only use this function at startup before creating any DockWidget or MainWindow.
void setSeparatorThickness(int value, bool staticSeparator);
///@brief Sets the QQmlEngine to use. Applicable only when using QtQuick.
void setQmlEngine(QQmlEngine*);
QQmlEngine* qmlEngine() const;
private:
Q_DISABLE_COPY(Config)
Config();
class Private;
Private* const d;
};
}
Q_DECLARE_OPERATORS_FOR_FLAGS(KDDockWidgets::Config::Flags)
#endif

View File

@ -0,0 +1,74 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief Represents a dock widget.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_DOCKWIDGET_H
#define KD_DOCKWIDGET_H
#include "DockWidgetBase.h"
class QCloseEvent;
namespace KDDockWidgets
{
/**
* @brief Represents a dock widget.
*
* Most of the interface lives in DockWidgetBase, to facilitate sharing with QtQuick.
*/
class DOCKS_EXPORT DockWidget : public DockWidgetBase
{
Q_OBJECT
public:
/**
* @brief constructs a new DockWidget
* @param uniqueName Mandatory name that should be unique between all DockWidget instances.
* This name won't be user visible and just used internally for the save/restore.
* Use setTitle() for user visible text.
* @param options optional options controlling behaviour
*
* There's no parent argument. The DockWidget is either parented to FloatingWindow or MainWindow
* when visible, or stays without a parent when hidden. This allows to support docking
* to different main windows.
*/
explicit DockWidget(const QString & uniqueName, Options options = {});
///@brief destructor
~DockWidget() override;
protected:
bool event(QEvent*) override;
void closeEvent(QCloseEvent*) override;
private:
class Private;
Private* const d;
};
}
#endif

View File

@ -0,0 +1,314 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief The DockWidget base-class that's shared between QtWidgets and QtQuick stack.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_DOCKWIDGET_BASE_H
#define KD_DOCKWIDGET_BASE_H
#include "docks_export.h"
#include "KDDockWidgets.h"
#include "QWidgetAdapter.h"
#include "LayoutSaver_p.h"
#include <QVector>
#include <QWidget>
class QAction;
namespace KDDockWidgets
{
class Frame;
class FloatingWindow;
class DragController;
class Item;
class LastPosition;
class DockRegistry;
class LayoutSaver;
class TabWidget;
class TitleBar;
/**
* @brief The DockWidget base-class. DockWidget and DockWidgetBase are only
* split in two so we can share some code with the QtQuick implementation,
* which also derives from DockWidgetBase.
*
* Do not use instantiate directly in user code. Use DockWidget instead.
*/
class DOCKS_EXPORT DockWidgetBase : public QWidgetOrQuick
{
Q_OBJECT
public:
typedef QVector<DockWidgetBase*> List;
///@brief DockWidget options to pass at construction time
enum Option
{
Option_None = 0, ///< No option, the default
Option_NotClosable = 1 /// The DockWidget can't be closed on the [x], only programatically
};
Q_DECLARE_FLAGS(Options, Option)
/**
* @brief constructs a new DockWidget
* @param name the name of the dockwidget, should be unique. Use title for user visible text.
* @param options optional options controlling behaviour
*
* There's no parent argument. The DockWidget is either parented to FloatingWindow or MainWindow
* when visible, or stays without a parent when hidden.
*/
explicit DockWidgetBase(const QString & uniqueName, Options options = {});
///@brief destructor
~DockWidgetBase() override;
/**
* @param Constructs a dock widget from its serialized form.
* @internal
*/
static DockWidgetBase* deserialize(const LayoutSaver::DockWidget::Ptr &);
/**
* @param Serializes this dock widget into an intermediate form
*/
LayoutSaver::DockWidget::Ptr serialize() const;
/**
* @brief docks @p other widget into this one. Tabs will be shown if not already.
* @param other The other dock widget to dock into this one.
* @sa MainWindow::addDockWidget(), DockWidget::addDockWidgetToContainingWindow()
*/
void addDockWidgetAsTab(DockWidgetBase* other);
/**
* @brief docks @p other widget into the window that contains this one.
* Equivalent to @ref MainWindow::addDockWidge() with the difference
* that it also supports the case where the top-level window is a
* @ref FloatingWindow instead of @ref MainWindow.
*
* @param other The other dock widget to dock into the window.
* @param location The location to dock.
* @param relativeTo The dock widget that the @p location is relative to. If null then the window is considered.
* @sa MainWindow::addDockWidget(), DockWidget::addDockWidgetAsTab()
*/
void addDockWidgetToContainingWindow(DockWidgetBase* other, KDDockWidgets::Location location,
DockWidgetBase* relativeTo = nullptr);
/**
* @brief sets the widget which this dock widget hosts.
* @param widget to show inside this dock widget
*/
void setWidget(QWidget* widget);
/**
* @brief returns the widget which this dock widget hosts
*/
QWidget* widget() const;
/**
* @brief Returns whether the dock widget is floating.
* Floating means it's not docked and has a window of its own.
* Note that if you dock a floating dock widget into another floating one
* then they don't count as floating anymore, as they are
* side-by-side (or tabbed).
*/
bool isFloating() const;
/**
* @brief setter to make the dock widget float or dock.
* @param floats If true makes the dock widget float, otherwise docks it.
*/
void setFloating(bool floats);
/**
* @brief Returns the QAction that allows to hide/show the dock widget
* Useful to put in menus.
*/
QAction* toggleAction() const;
/**
* @brief the dock widget's unique name.
* @internal
*/
QString uniqueName() const;
/**
* @brief Returns the dock widget's title.
* This title is visible in title bars and tab bars.
* @sa setTitle
*/
QString title() const;
/**
* @brief setter for the dock widget's title
* @param title the dock widget's new title
* @sa setTitle
*/
void setTitle(const QString & title);
/**
* @brief Returns the dock widget's options which control behaviour
* These options were passed at construction time and are immutable.
*/
Options options() const;
/**
* @brief returns if this dock widget is tabbed into another
*
* Technically a docked DockWidget always lives in a tab widget, but from the user's prespective
* it's not tabbed when there's only 1 dock widget, as there are no tabs displayed. Unless
* the frame is using Option_AlwaysShowsTabs, in which case this method will return true regardless
* if being the single one.
*/
bool isTabbed() const;
/**
* @brief Returns true if this dock widget is the current one in the tab
* widget that contains it. If the dock widget is alone then true is
* returned, as in this case there will also be a tab widget even
* though it's invisible.
*/
bool isCurrentTab() const;
/**
* @brief Makes this dock widget current in its tab group.
*/
void setAsCurrentTab();
/**
* @brief Sets an icon to show on title bars and tab bars.
* By default none is shown.
*/
void setIcon(const QIcon & icon);
/**
* @brief Returns the dock widget's icon.
*/
QIcon icon() const;
/**
* @brief Like QWidget::close() but the hosted widget won't be asked if we
* should close.
*/
void forceClose();
/**
* @brief Returns this dock widget's title bar.
*
* Note that several dock widgets can have the same title bar, in case they are tabbed together.
* Hidden dock widgets have no associated title bar.
*/
TitleBar* titleBar() const;
Q_SIGNALS:
///@brief signal emitted when the parent changed
void parentChanged();
///@brief signal emitted when the DockWidget is shown. As in QEvent::Show.
void shown();
///@brief signal emitted when the DockWidget is hidden. As in QEvent::Hide.
void hidden();
///@brief signal emitted when the icon changed
void iconChanged();
///@brief signal emitted when the title changed
void titleChanged();
///@brief emitted when the hosted widget changed
void widgetChanged(QWidget*);
protected:
void onParentChanged();
void onShown(bool spontaneous);
void onHidden(bool spontaneous);
void onClosed(QCloseEvent* e);
#if defined(DOCKS_DEVELOPER_MODE)
public Q_SLOTS:
#else
private Q_SLOTS:
#endif
/**
* @brief Creates a FloatingWindow and adds itself into it
* @return the created FloatingWindow
*/
KDDockWidgets::FloatingWindow* morphIntoFloatingWindow();
/// @brief calls morphIntoFloatingWindow() if the dock widget is visible and is a top-level
/// This is called delayed whenever we show a floating dock widget, so we get a FloatingWindow
void maybeMorphIntoFloatingWindow();
#if defined(DOCKS_DEVELOPER_MODE)
public:
#else
private:
#endif
Q_DISABLE_COPY(DockWidgetBase)
friend class MultiSplitterLayout;
friend class Frame;
friend class DropArea;
friend class TestDocks;
friend class Item;
friend class KDDockWidgets::TabWidget;
friend class KDDockWidgets::TitleBar;
friend class KDDockWidgets::DragController;
friend class KDDockWidgets::Item;
friend class KDDockWidgets::DockRegistry;
friend class KDDockWidgets::LayoutSaver;
/**
* @brief the Frame which contains this dock widgets.
*
* A frame wraps a docked DockWidget, giving it a TabWidget so it can accept other dock widgets.
* Frame is also the actual class that goes into a MultiSplitter.
*
* It's nullptr immediately after creation.
*/
Frame* frame() const;
/**
* @brief returns the FloatingWindow this dock widget is in. If nullptr then it's in a MainWindow.
*
* Note: Being in a FloatingWindow doesn't necessarily mean @ref isFloating() returns true, as
* the dock widget might be in a floating window with other dock widgets side by side.
*/
FloatingWindow* floatingWindow() const;
///@brief adds the current layout item containing this dock widget
void addPlaceholderItem(Item*);
///@brief returns the last position, just for tests. TODO Make tests just use the d-pointer.
LastPosition* lastPosition() const;
class Private;
Private* const d;
};
}
#endif

View File

@ -0,0 +1,147 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KDDOCKWIDGETS_FRAMEWORKWIDGETFACTORY_H
#define KDDOCKWIDGETS_FRAMEWORKWIDGETFACTORY_H
#include "docks_export.h"
#include "KDDockWidgets.h"
#include "QWidgetAdapter.h"
/**
* @file
* @brief A factory class for allowing the user to customize some internal widgets.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
namespace KDDockWidgets
{
class DropIndicatorOverlayInterface;
class Separator;
class FloatingWindow;
class TabWidget;
class TitleBar;
class Frame;
class DropArea;
class Anchor;
class TabBar;
/**
* @brief A factory class for allowing the user to customize some internal widgets.
* This is optional, and if not provided, a default one will be used, @ref DefaultWidgetFactory.
*
* Deriving from @ref DefaultWidgetFactory is recommended, unless you need to override
* all methods.
*
* Sub-classing FrameworkWidgetFactory allows for fine-grained customization and
* styling of some non-public widgets, such as titlebars, dock widget frame and
* tab widgets.
*
* To set your own factory see Config::setFrameworkWidgetFactory()
*
* Will also be useful to provide a QtQuickWidget factory in the future.
*
* @sa Config::setFrameworkWidgetFactory()
*/
class DOCKS_EXPORT FrameworkWidgetFactory
{
public:
///@brief Destructor.Don't delete FrameworkWidgetFactory directly, it's owned
/// by the framework.
virtual ~FrameworkWidgetFactory();
///@brief Called internally by the framework to create a Frame class
//// Override to provide your own Frame sub-class. A frame is the
/// widget that holds the titlebar and tab-widget which holds the
/// DockWidgets.
///@param parent just forward to Frame's constructor
///@param options just forward to Frame's constructor
virtual Frame* createFrame(QWidgetOrQuick* parent = nullptr, FrameOptions = FrameOption_None) const = 0;
///@brief Called internally by the framework to create a TitleBar
/// Override to provide your own TitleBar sub-class. If overridden then
/// you also need to override the overload below.
///@param frame Just forward to TitleBar's constructor.
virtual TitleBar* createTitleBar(Frame* frame) const = 0;
///@brief Called internally by the framework to create a TitleBar
/// Override to provide your own TitleBar sub-class. If overridden then
/// you also need to override the overload above.
///@param floatingWindow Just forward to TitleBar's constructor.
virtual TitleBar* createTitleBar(FloatingWindow* floatingWindow) const = 0;
///@brief Called internally by the framework to create a TabBar
/// Override to provide your own TabBar sub-class.
///@param parent Just forward to TabBar's's constructor.
virtual TabBar* createTabBar(TabWidget* parent = nullptr) const = 0;
///@brief Called internally by the framework to create a TabWidget
/// Override to provide your own TabWidget sub-class.
///@param parent Just forward to TabWidget's constructor.
virtual TabWidget* createTabWidget(Frame* parent) const = 0;
///@brief Called internally by the framework to create a Separator
/// Override to provide your own Separator sub-class. The Separator allows
/// the user to resize nested dock widgets.
///@param anchor Just forward to Sepataror's constructor.
///@param parent Just forward to Separator's constructor.
virtual Separator* createSeparator(Anchor* anchor, QWidgetAdapter* parent = nullptr) const = 0;
///@brief Called internally by the framework to create a FloatingWindow
/// Override to provide your own FloatingWindow sub-class. If overridden then
/// you also need to override the overloads below.
///@param parent Just forward to FloatingWindow's constructor.
virtual FloatingWindow* createFloatingWindow(QWidgetOrQuick* parent = nullptr) const = 0;
///@brief Called internally by the framework to create a FloatingWindow
/// Override to provide your own FloatingWindow sub-class. If overridden then
/// you also need to override the overloads above.
///@param frame Just forward to FloatingWindow's constructor.
///@param parent Just forward to FloatingWindow's constructor.
virtual FloatingWindow* createFloatingWindow(Frame* frame, QWidgetOrQuick* parent = nullptr) const = 0;
///@brief Called internally by the framework to create a DropIndicatorOverlayInterface
/// Override to provide your own DropIndicatorOverlayInterface sub-class.
///@param dropArea Just forward to DropIndicatorOverlayInterface's constructor.
virtual DropIndicatorOverlayInterface* createDropIndicatorOverlay(DropArea* dropArea) const = 0;
};
/**
* @brief The FrameworkWidgetFactory that's used if none is specified.
*/
class DOCKS_EXPORT DefaultWidgetFactory : public FrameworkWidgetFactory
{
public:
Frame* createFrame(QWidgetOrQuick* parent, FrameOptions) const override;
TitleBar* createTitleBar(Frame*) const override;
TitleBar* createTitleBar(FloatingWindow*) const override;
TabBar* createTabBar(TabWidget* parent) const override;
TabWidget* createTabWidget(Frame* parent) const override;
Separator* createSeparator(Anchor* anchor, QWidgetAdapter* parent = nullptr) const override;
FloatingWindow* createFloatingWindow(QWidgetOrQuick* parent = nullptr) const override;
FloatingWindow* createFloatingWindow(Frame* frame, QWidgetOrQuick* parent = nullptr) const override;
DropIndicatorOverlayInterface* createDropIndicatorOverlay(DropArea*) const override;
};
}
#endif

View File

@ -0,0 +1,128 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief File with KDDockWidgets namespace-level enums and methods.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_KDDOCKWIDGETS_H
#define KD_KDDOCKWIDGETS_H
#include <QObject>
namespace KDDockWidgets
{
enum Location
{
Location_None,
Location_OnLeft, ///> Left docking location
Location_OnTop, ///> Top docking location
Location_OnRight, ///> Right docking location
Location_OnBottom ///> Bottom docking location
};
enum MainWindowOption
{
MainWindowOption_None = 0, ///> No option set
MainWindowOption_HasCentralFrame = 1 ///> Makes the MainWindow always have a central frame, for tabbing documents
};
Q_DECLARE_FLAGS(MainWindowOptions, MainWindowOption)
enum AddingOption
{
AddingOption_None = 0, ///> No option set
AddingOption_StartHidden ///< Don't show the dock widget when adding it
};
///@internal
enum FrameOption
{
FrameOption_None = 0,
FrameOption_AlwaysShowsTabs = 1,
FrameOption_IsCentralFrame = 2
};
Q_DECLARE_FLAGS(FrameOptions, FrameOption)
///@internal
inline Location oppositeLocation(Location loc)
{
switch(loc)
{
case Location_OnLeft:
return Location_OnRight;
case Location_OnTop:
return Location_OnBottom;
case Location_OnRight:
return Location_OnLeft;
case Location_OnBottom:
return Location_OnTop;
default:
Q_ASSERT(false);
return Location_None;
}
}
///@internal
inline Location adjacentLocation(Location loc)
{
switch(loc)
{
case Location_OnLeft:
return Location_OnTop;
case Location_OnTop:
return Location_OnRight;
case Location_OnRight:
return Location_OnBottom;
case Location_OnBottom:
return Location_OnLeft;
default:
Q_ASSERT(false);
return Location_None;
}
}
///@internal
inline QString locationStr(Location loc)
{
switch(loc)
{
case KDDockWidgets::Location_None:
return QStringLiteral("none");
case KDDockWidgets::Location_OnLeft:
return QStringLiteral("left");
case KDDockWidgets::Location_OnTop:
return QStringLiteral("top");
case KDDockWidgets::Location_OnRight:
return QStringLiteral("right");
case KDDockWidgets::Location_OnBottom:
return QStringLiteral("bottom");
}
return QString();
}
}
Q_DECLARE_METATYPE(KDDockWidgets::Location)
Q_DECLARE_OPERATORS_FOR_FLAGS(KDDockWidgets::FrameOptions)
#endif

View File

@ -0,0 +1,109 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_LAYOUTSAVER_H
#define KD_LAYOUTSAVER_H
/**
* @file
* @brief Class to save and restore dockwidget layouts.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#include "docks_export.h"
class QByteArray;
namespace KDDockWidgets
{
class DockWidgetBase;
class DOCKS_EXPORT LayoutSaver
{
public:
///@brief Constructor. Construction on the stack is suggested.
LayoutSaver();
///@brief Destructor.
~LayoutSaver();
///@brief returns whether a restore (@ref restoreLayout) is in progress
static bool restoreInProgress();
/**
* @brief saves the layout to disk using QSettings
*/
bool saveToDisk();
/**
* @brief restores the layout from disk using QSettings.
* @return true on success
*/
bool restoreFromDisk();
/**
* @brief saves the layout into a byte array
*/
QByteArray serializeLayout() const;
/**
* @brief restores the layout from a byte array
* All MainWindows and DockWidgets should have been created before calling
* this function.
*
* If not all DockWidgets can be created beforehand then make sure to set
* a DockWidget factory via Config::setDockWidgetFactoryFunc()
*
* @sa Config::setDockWidgetFactoryFunc()
*
* @return true on success
*/
bool restoreLayout(const QByteArray &);
/**
* @brief returns a list of dock widgets which were restored since the last
* @ref restoreLayout() or @ref restoreFromDisk()
*
* Useful since some dock widgets can be new, and hence not be included in the last saved layout.
*/
QVector<DockWidgetBase*> restoredDockWidgets() const;
struct Layout;
struct MainWindow;
struct FloatingWindow;
struct DockWidget;
struct LastPosition;
struct MultiSplitterLayout;
struct Item;
struct Anchor;
struct Frame;
struct Placeholder;
private:
friend class TestDocks;
class Private;
Private* const d;
};
}
#endif

View File

@ -0,0 +1,548 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_LAYOUTSAVER_P_H
#define KD_LAYOUTSAVER_P_H
#include "LayoutSaver.h"
#include "KDDockWidgets.h"
#include <QRect>
#include <QDataStream>
#include <QDebug>
#include <memory>
#define ANCHOR_MAGIC_MARKER "e520c60e-cf5d-4a30-b1a7-588d2c569851"
#define MULTISPLITTER_LAYOUT_MAGIC_MARKER "bac9948e-5f1b-4271-acc5-07f1708e2611"
#define KDDOCKWIDGETS_SERIALIZATION_VERSION 1
namespace KDDockWidgets
{
struct LayoutSaver::Placeholder
{
typedef QVector<LayoutSaver::Placeholder> List;
bool isFloatingWindow;
int indexOfFloatingWindow;
int itemIndex;
QString mainWindowUniqueName;
};
struct LayoutSaver::LastPosition
{
QRect lastFloatingGeometry;
int tabIndex;
bool wasFloating;
LayoutSaver::Placeholder::List placeholders;
};
struct DOCKS_EXPORT LayoutSaver::DockWidget
{
// Using shared ptr, as we need to modify shared instances
typedef std::shared_ptr<LayoutSaver::DockWidget> Ptr;
typedef QVector<Ptr> List;
static QHash<QString, Ptr> s_dockWidgets;
bool isValid() const;
static Ptr dockWidgetForName(const QString & name)
{
auto dw = s_dockWidgets.value(name);
if(dw)
return dw;
dw = Ptr(new LayoutSaver::DockWidget);
dw->uniqueName = name;
return dw;
}
QString uniqueName;
LayoutSaver::LastPosition lastPosition;
private:
DockWidget() {}
};
struct LayoutSaver::Frame
{
bool isValid() const;
bool isNull = true;
QString objectName;
QRect geometry;
int options;
int currentTabIndex;
LayoutSaver::DockWidget::List dockWidgets;
};
struct LayoutSaver::Item
{
typedef QVector<LayoutSaver::Item> List;
bool isValid(const MultiSplitterLayout &) const;
QString objectName;
bool isPlaceholder;
QRect geometry;
QSize minSize;
int indexOfLeftAnchor;
int indexOfTopAnchor;
int indexOfRightAnchor;
int indexOfBottomAnchor;
LayoutSaver::Frame frame;
};
struct LayoutSaver::Anchor
{
typedef QVector<LayoutSaver::Anchor> List;
bool isValid(const LayoutSaver::MultiSplitterLayout & layout) const;
QString objectName;
QRect geometry;
int orientation;
int type;
int indexOfFrom;
int indexOfTo;
int indexOfFollowee;
QVector<int> side1Items;
QVector<int> side2Items;
};
struct LayoutSaver::MultiSplitterLayout
{
bool isValid() const;
LayoutSaver::Anchor::List anchors;
LayoutSaver::Item::List items;
QSize minSize;
QSize size;
};
struct LayoutSaver::FloatingWindow
{
typedef QVector<LayoutSaver::FloatingWindow> List;
bool isValid() const;
LayoutSaver::MultiSplitterLayout multiSplitterLayout;
int parentIndex = -1;
QRect geometry;
bool isVisible = true;
};
struct LayoutSaver::MainWindow
{
public:
typedef QVector<LayoutSaver::MainWindow> List;
bool isValid() const;
KDDockWidgets::MainWindowOptions options;
LayoutSaver::MultiSplitterLayout multiSplitterLayout;
QString uniqueName;
QRect geometry;
bool isVisible;
};
struct LayoutSaver::Layout
{
public:
bool isValid() const;
bool fillFrom(const QByteArray & serialized);
int serializationVersion = KDDOCKWIDGETS_SERIALIZATION_VERSION;
LayoutSaver::MainWindow::List mainWindows;
LayoutSaver::FloatingWindow::List floatingWindows;
LayoutSaver::DockWidget::List closedDockWidgets;
LayoutSaver::DockWidget::List allDockWidgets;
};
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::Placeholder* p)
{
ds << p->isFloatingWindow;
if(p->isFloatingWindow)
ds << p->indexOfFloatingWindow;
else
ds << p->mainWindowUniqueName;
ds << p->itemIndex;
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::Placeholder* p)
{
ds >> p->isFloatingWindow;
if(p->isFloatingWindow)
ds >> p->indexOfFloatingWindow;
else
ds >> p->mainWindowUniqueName;
ds >> p->itemIndex;
return ds;
}
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::Anchor* a)
{
ds << QStringLiteral(ANCHOR_MAGIC_MARKER);
ds << a->objectName;
ds << a->geometry;
ds << a->orientation;
ds << a->type;
ds << a->indexOfFrom;
ds << a->indexOfTo;
ds << a->indexOfFollowee;
ds << a->side1Items;
ds << a->side2Items;
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::Anchor* a)
{
QString marker;
ds >> marker;
if(marker != QLatin1String(ANCHOR_MAGIC_MARKER))
qWarning() << Q_FUNC_INFO << "Corrupt stream";
ds >> a->objectName;
ds >> a->geometry;
ds >> a->orientation;
ds >> a->type;
ds >> a->indexOfFrom;
ds >> a->indexOfTo;
ds >> a->indexOfFollowee;
ds >> a->side1Items;
ds >> a->side2Items;
return ds;
}
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::Frame* frame)
{
ds << frame->objectName;
ds << frame->geometry;
ds << frame->options;
ds << frame->currentTabIndex;
ds << frame->dockWidgets.size();
for(auto & dock : frame->dockWidgets)
{
ds << dock->uniqueName;
}
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::Frame* frame)
{
int numDockWidgets;
frame->dockWidgets.clear();
frame->isNull = false;
ds >> frame->objectName;
ds >> frame->geometry;
ds >> frame->options;
ds >> frame->currentTabIndex;
ds >> numDockWidgets;
for(int i = 0; i < numDockWidgets; ++i)
{
QString name;
ds >> name;
auto dw = LayoutSaver::DockWidget::dockWidgetForName(name);
frame->dockWidgets.push_back(dw);
}
return ds;
}
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::Item* item)
{
ds << item->objectName;
ds << item->isPlaceholder;
ds << item->geometry;
ds << item->minSize;
ds << item->indexOfLeftAnchor;
ds << item->indexOfTopAnchor;
ds << item->indexOfRightAnchor;
ds << item->indexOfBottomAnchor;
const bool hasFrame = !item->frame.isNull;
ds << hasFrame;
if(hasFrame)
ds << &item->frame;
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::Item* item)
{
ds >> item->objectName;
ds >> item->isPlaceholder;
ds >> item->geometry;
ds >> item->minSize;
ds >> item->indexOfLeftAnchor;
ds >> item->indexOfTopAnchor;
ds >> item->indexOfRightAnchor;
ds >> item->indexOfBottomAnchor;
bool hasFrame;
ds >> hasFrame;
if(hasFrame)
{
ds >> &item->frame;
item->frame.isNull = false;
}
else
{
item->frame.isNull = true;
}
return ds;
}
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::MultiSplitterLayout* l)
{
ds << QStringLiteral(MULTISPLITTER_LAYOUT_MAGIC_MARKER);
ds << l->size;
ds << l->minSize;
ds << l->items.size();
ds << l->anchors.size();
for(auto & item : l->items)
ds << &item;
for(auto & anchor : l->anchors)
ds << &anchor;
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::MultiSplitterLayout* l)
{
int numItems;
int numAnchors;
QString marker;
ds >> marker;
if(marker != QLatin1String(MULTISPLITTER_LAYOUT_MAGIC_MARKER))
qWarning() << Q_FUNC_INFO << "Corrupt stream, invalid magic";
ds >> l->size;
ds >> l->minSize;
ds >> numItems;
ds >> numAnchors;
l->items.clear();
l->anchors.clear();
for(int i = 0 ; i < numItems; ++i)
{
LayoutSaver::Item item;
ds >> &item;
l->items.push_back(item);
}
for(int i = 0 ; i < numAnchors; ++i)
{
LayoutSaver::Anchor a;
ds >> &a;
l->anchors.push_back(a);
}
return ds;
}
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::LastPosition* lp)
{
ds << lp->placeholders.size();
for(auto & p : lp->placeholders)
{
ds << &p;
}
ds << lp->lastFloatingGeometry;
ds << lp->tabIndex;
ds << lp->wasFloating;
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::LastPosition* lp)
{
int numPlaceholders;
ds >> numPlaceholders;
lp->placeholders.clear();
for(int i = 0 ; i < numPlaceholders; ++i)
{
LayoutSaver::Placeholder p;
ds >> &p;
lp->placeholders.push_back(p);
}
ds >> lp->lastFloatingGeometry;
ds >> lp->tabIndex;
ds >> lp->wasFloating;
return ds;
}
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::FloatingWindow* fw)
{
ds << fw->parentIndex;
ds << fw->geometry;
ds << fw->isVisible;
ds << &fw->multiSplitterLayout;
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::FloatingWindow* fw)
{
ds >> fw->parentIndex;
ds >> fw->geometry;
ds >> fw->isVisible;
ds >> &fw->multiSplitterLayout;
return ds;
}
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::MainWindow* m)
{
ds << m->uniqueName;
ds << m->geometry;
ds << m->isVisible;
ds << m->options;
ds << &m->multiSplitterLayout;
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::MainWindow* m)
{
ds >> m->uniqueName;
ds >> m->geometry;
ds >> m->isVisible;
ds >> m->options;
ds >> &m->multiSplitterLayout;
return ds;
}
inline QDataStream & operator<<(QDataStream & ds, LayoutSaver::Layout* l)
{
ds << l->serializationVersion;
ds << l->mainWindows.size();
for(auto & m : l->mainWindows)
{
ds << &m;
}
ds << l->floatingWindows.size();
for(auto & fw : l->floatingWindows)
{
ds << &fw;
}
ds << l->closedDockWidgets.size();
for(auto & dw : l->closedDockWidgets)
{
ds << dw->uniqueName;
}
ds << l->allDockWidgets.size();
for(auto & dw : l->allDockWidgets)
{
ds << dw->uniqueName;
ds << &dw->lastPosition;
}
return ds;
}
inline QDataStream & operator>>(QDataStream & ds, LayoutSaver::Layout* l)
{
LayoutSaver::DockWidget::s_dockWidgets.clear();
int numMainWindows;
int numFloatingWindows;
int numClosedDockWidgets;
int numAllDockWidgets;
ds >> l->serializationVersion;
ds >> numMainWindows;
l->mainWindows.clear();
for(int i = 0; i < numMainWindows; ++i)
{
LayoutSaver::MainWindow m;
ds >> &m;
l->mainWindows.push_back(m);
}
ds >> numFloatingWindows;
l->floatingWindows.clear();
for(int i = 0; i < numFloatingWindows; ++i)
{
LayoutSaver::FloatingWindow m;
ds >> &m;
l->floatingWindows.push_back(m);
}
ds >> numClosedDockWidgets;
l->closedDockWidgets.clear();
for(int i = 0; i < numClosedDockWidgets; ++i)
{
QString name;
ds >> name;
auto dw = LayoutSaver::DockWidget::dockWidgetForName(name);
l->closedDockWidgets.push_back(dw);
}
ds >> numAllDockWidgets;
l->allDockWidgets.clear();
for(int i = 0; i < numAllDockWidgets; ++i)
{
QString name;
ds >> name;
auto dw = LayoutSaver::DockWidget::dockWidgetForName(name);
ds >> &dw->lastPosition;
l->allDockWidgets.push_back(dw);
}
return ds;
}
}
#endif

View File

@ -0,0 +1,68 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief QMainWindow sub-class to enable KDDockWidgets support.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_MAINWINDOW_H
#define KD_MAINWINDOW_H
#include "MainWindowBase.h"
namespace KDDockWidgets
{
/**
* @brief The QMainwindow sub-class that the application should use to be able
* to dock KDDockWidget::DockWidget instances.
*/
class DOCKS_EXPORT MainWindow : public MainWindowBase
{
Q_OBJECT
public:
typedef QVector<MainWindow*> List;
///@brief Constructor. Use it as you would use QMainWindow.
///@param uniqueName Mandatory name that should be unique between all MainWindow instances.
/// This name won't be user visible and just used internally for the save/restore.
///@param options optional MainWindowOptions to use
///@param parent QObject *parent to pass to QMainWindow constructor.
///@param flags Window flags to pass to QMainWindow constructor.
explicit MainWindow(const QString & uniqueName, MainWindowOptions options = MainWindowOption_None,
QWidget* parent = nullptr, Qt::WindowFlags flags = {});
///@brief Destructor
~MainWindow() override;
///@internal
DropAreaWithCentralFrame* dropArea() const override;
private:
class Private;
Private* const d;
};
}
#endif

View File

@ -0,0 +1,121 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief The MainWindow base-class that's shared between QtWidgets and QtQuick stack.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_MAINWINDOW_BASE_H
#define KD_MAINWINDOW_BASE_H
#include "docks_export.h"
#include "KDDockWidgets.h"
#include "QWidgetAdapter.h"
#include "LayoutSaver_p.h"
#include <QVector>
namespace KDDockWidgets
{
class DockWidgetBase;
class Frame;
class DropArea;
class MultiSplitterLayout;
class DropAreaWithCentralFrame;
/**
* @brief The MainWindow base-class. MainWindow and MainWindowBase are only
* split in two so we can share some code with the QtQuick implementation,
* which also derives from MainWindowBase.
*
* Do not use instantiate directly in user code. Use MainWindow instead.
*/
class DOCKS_EXPORT MainWindowBase : public QMainWindowOrQuick
{
Q_OBJECT
public:
typedef QVector<MainWindowBase*> List;
explicit MainWindowBase(const QString & uniqueName, MainWindowOptions options = MainWindowOption_HasCentralFrame,
QWidgetOrQuick* parent = nullptr, Qt::WindowFlags flags = {});
~MainWindowBase() override;
/**
* @brief Docks a DockWidget into the central frame, tabbed.
* @warning Requires that the MainWindow was constructed with MainWindowOption_HasCentralFrame option.
* @param The DockWidget to dock.
*
* @sa DockWidgetBase::addDockWidgetAsTab()
*/
void addDockWidgetAsTab(DockWidgetBase* dockwidget);
/**
* @brief Docks a DockWidget into this main window.
* @param dockWidget The dock widget to add into this MainWindow
* @param location the location where to dock
* @param relativeTo In case we're docking in relation to another dock widget
* @param option AddingOptions
*/
void addDockWidget(DockWidgetBase* dockWidget,
KDDockWidgets::Location location,
DockWidgetBase* relativeTo = nullptr, AddingOption option = {});
/**
* @brief Returns the unique name that was passed via constructor.
* Used internally by the save/restore mechanism.
* @internal
*/
QString uniqueName() const;
/// @brief Returns the main window options that were passed via constructor.
MainWindowOptions options() const;
///@internal
///@brief returns the drop area.
virtual DropAreaWithCentralFrame* dropArea() const = 0;
///@internal
///@brief returns the MultiSplitterLayout.
MultiSplitterLayout* multiSplitterLayout() const;
protected:
void setUniqueName(const QString & uniqueName);
Q_SIGNALS:
void uniqueNameChanged();
private:
class Private;
Private* const d;
friend class LayoutSaver;
bool deserialize(const LayoutSaver::MainWindow &);
LayoutSaver::MainWindow serialize() const;
};
}
#endif

View File

@ -0,0 +1,46 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KDDOCKWIDGETS_QWIDGETADAPTER_H
#define KDDOCKWIDGETS_QWIDGETADAPTER_H
#if !defined(KDDOCKWIDGETS_QTWIDGETS) && !defined(KDDOCKWIDGETS_QTQUICK)
# define KDDOCKWIDGETS_QTWIDGETS
#endif
/**
* @file
* @brief Abstraction for supporting both QtWidgets and QtQuick.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifdef KDDOCKWIDGETS_QTWIDGETS
# include "private/widgets/QWidgetAdapter_widgets_p.h"
#include <QMainWindow>
typedef QWidget QWidgetOrQuick;
typedef QMainWindow QMainWindowOrQuick;
#else
# include "quick/QWidgetAdapter_quick_p.h"
typedef KDDockWidgets::QWidgetAdapter QWidgetOrQuick;
typedef QWidgetOrQuick QMainWindowOrQuick;
#endif
#endif

View File

@ -0,0 +1,63 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_DOCKS_EXPORT_H
#define KD_DOCKS_EXPORT_H
#include <QtCore/QtGlobal>
#if QT_VERSION < QT_VERSION_CHECK(5,7,0)
#include <QFlags>
#include <QDataStream>
// this adds const to non-const objects (like std::as_const)
template <typename T>
Q_DECL_CONSTEXPR typename std::add_const<T>::type & qAsConst(T & t) Q_DECL_NOTHROW { return t; }
// prevent rvalue arguments:
template <typename T>
void qAsConst(const T &&) Q_DECL_EQ_DELETE;
template<class Enum>
inline QDataStream & operator>>(QDataStream & ds, QFlags<Enum> & qenum)
{
int i = 0;
ds >> i;
qenum = QFlags<Enum>(static_cast<Enum>(i));
return ds;
}
#endif
#if defined(BUILDING_DOCKS_LIBRARY)
# define DOCKS_EXPORT Q_DECL_EXPORT
# if defined(DOCKS_DEVELOPER_MODE)
# define DOCKS_EXPORT_FOR_UNIT_TESTS Q_DECL_EXPORT
# else
# define DOCKS_EXPORT_FOR_UNIT_TESTS
# endif
#else
# define DOCKS_EXPORT Q_DECL_IMPORT
# if defined(DOCKS_DEVELOPER_MODE)
# define DOCKS_EXPORT_FOR_UNIT_TESTS Q_DECL_IMPORT
# else
# define DOCKS_EXPORT_FOR_UNIT_TESTS Q_DECL_IMPORT
# endif
#endif
#endif

View File

@ -0,0 +1,76 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_DRAGGABLE_P_H
#define KD_DRAGGABLE_P_H
#include "QWidgetAdapter.h"
#include <QVector>
#include <memory>
namespace KDDockWidgets
{
class FloatingWindow;
class WidgetResizeHandler;
struct WindowBeingDragged;
/**
* @brief Represents something that can be dragged.
*
* Like a tab, a docked title bar, and even a FloatingWindow if it has a native OS title bar
*
* \internal
*/
class DOCKS_EXPORT Draggable
{
public:
typedef QVector<Draggable*> List;
explicit Draggable(QWidgetOrQuick* thisObject, bool enabled = true);
virtual ~Draggable();
QWidgetOrQuick* asWidget() const;
/**
* If this draggable is already a window, do nothing.
* Otherwise it should make it a window. As that's what dragging does.
*/
virtual std::unique_ptr<WindowBeingDragged> makeWindow() = 0;
/**
* @brief Returns whether point @p p is draggable.
*
* Because simply inheriting from Draggable doesn't mean you can click anywhere to drag.
*/
virtual bool isPositionDraggable(QPoint p) const { Q_UNUSED(p) return true; }
WidgetResizeHandler* widgetResizeHandler() const;
void setWidgetResizeHandler(WidgetResizeHandler* w);
private:
class Private;
Private* const d;
Q_DISABLE_COPY(Draggable)
};
}
#endif

View File

@ -0,0 +1,93 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_DROPINDICATOROVERLAYINTERFACE_P_H
#define KD_DROPINDICATOROVERLAYINTERFACE_P_H
#include "docks_export.h"
#include "QWidgetAdapter.h"
#include "Frame_p.h"
#include "KDDockWidgets.h"
namespace KDDockWidgets
{
class FloatingWindow;
class DropArea;
class DOCKS_EXPORT_FOR_UNIT_TESTS DropIndicatorOverlayInterface : public QWidgetAdapter
{
Q_OBJECT
public:
enum Type
{
TypeNone = 0,
TypeClassic = 1,
TypeAnimated = 2
};
Q_ENUM(Type)
enum DropLocation
{
DropLocation_None = 0,
DropLocation_Left,
DropLocation_Top,
DropLocation_Right,
DropLocation_Bottom,
DropLocation_Center,
DropLocation_OutterLeft,
DropLocation_OutterTop,
DropLocation_OutterRight,
DropLocation_OutterBottom
};
Q_ENUM(DropLocation)
explicit DropIndicatorOverlayInterface(DropArea* dropArea);
void setHoveredFrame(Frame*);
void setWindowBeingDragged(const FloatingWindow*);
bool isHovered() const;
DropLocation currentDropLocation() const { return m_currentDropLocation; }
Frame* hoveredFrame() const { return m_hoveredFrame; }
void setCurrentDropLocation(DropIndicatorOverlayInterface::DropLocation location);
virtual Type indicatorType() const = 0;
virtual void hover(QPoint globalPos) = 0;
virtual QPoint posForIndicator(DropLocation) const = 0; // Used by unit-tests only
static KDDockWidgets::Location multisplitterLocationFor(DropLocation);
Q_SIGNALS:
void hoveredFrameChanged(KDDockWidgets::Frame*);
private:
void onFrameDestroyed();
protected:
virtual void onHoveredFrameChanged(Frame*);
virtual void updateVisibility() = 0;
Frame* m_hoveredFrame = nullptr;
DropLocation m_currentDropLocation = DropLocation_None;
QPointer<const FloatingWindow> m_windowBeingDragged;
DropArea* const m_dropArea;
};
}
#endif

View File

@ -0,0 +1,134 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_FLOATING_WINDOW_P_H
#define KD_FLOATING_WINDOW_P_H
#include "docks_export.h"
#include "Frame_p.h"
#include "Draggable_p.h"
#include "QWidgetAdapter.h"
#include "LayoutSaver_p.h"
class QAbstractNativeEventFilter;
namespace KDDockWidgets
{
class DropArea;
class Frame;
class MultiSplitterLayout;
class DOCKS_EXPORT FloatingWindow : public QWidgetAdapter
, public Draggable
{
Q_OBJECT
public:
explicit FloatingWindow(QWidgetOrQuick* parent = nullptr);
explicit FloatingWindow(Frame* frame, QWidgetOrQuick* parent = nullptr);
~FloatingWindow() override;
bool deserialize(const LayoutSaver::FloatingWindow &);
LayoutSaver::FloatingWindow serialize() const;
// Draggable:
std::unique_ptr<WindowBeingDragged> makeWindow() override;
const Frame::List frames() const;
DropArea* dropArea() const { return m_dropArea; }
/**
* @brief Returns the title bar.
*
* This TitleBar is hidden if we're using a native title bar.
*/
TitleBar* titleBar() const { return m_titleBar; }
bool anyNonClosable() const;
/**
* @brief checks if this FloatingWindow only has one frame.
* If true it means there's no side-by-side dock widgets here. There's only 1 frame.
* Note that despite having only 1 frame it can still have multiple DockWidgets,
* as they can be tabbed into the single frame.
* @return true if this FloatingWindow has a single frame.
*/
bool hasSingleFrame() const;
/**
* @brief checks if this FloatingWindow only has one dockwidget.
* This is a more specific case than hasSingleFrame(), it implies not only a single frame,
* but that frame must only have 1 dock widget.
* @return true if this FloatingWindow only has one dockwidget.
*/
bool hasSingleDockWidget() const;
/**
* @brief Returns whether a deleteLater has already been issued
*/
bool beingDeleted() const;
/**
* @brief Equivalent to deleteLater() but sets beingDeleted() to true
*/
void scheduleDeleteLater();
/**
* @brief Returns the MultiSplitterLayout
*/
MultiSplitterLayout* multiSplitterLayout() const;
/**
* @brief Returns whether @p globalPoint is inside the title bar
*/
bool isInTitleBar(QPoint globalPoint) const;
///@brief For tests-only. Returns the number of Frame instances in the whole application.
static int dbg_numFrames();
///@brief updates the title and the icon
void updateTitleAndIcon();
void updateTitleBarVisibility();
Q_SIGNALS:
void numFramesChanged();
protected:
#ifdef Q_OS_WIN
bool nativeEvent(const QByteArray & eventType, void* message, long* result) override;
#endif
void onCloseEvent(QCloseEvent*) override;
TitleBar* const m_titleBar;
DropArea* const m_dropArea;
private:
Q_DISABLE_COPY(FloatingWindow)
void maybeCreateResizeHandler();
void onFrameCountChanged(int count);
void onVisibleFrameCountChanged(int count);
bool m_disableSetVisible = false;
bool m_beingDeleted = false;
QMetaObject::Connection m_layoutDestroyedConnection;
QAbstractNativeEventFilter* m_nchittestFilter = nullptr;
};
}
#endif

View File

@ -0,0 +1,247 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief A DockWidget wrapper that adds a QTabWidget and a TitleBar.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_FRAME_P_H
#define KD_FRAME_P_H
#include "docks_export.h"
#include "QWidgetAdapter.h"
#include "LayoutSaver_p.h"
#include <QWidget>
#include <QVector>
#include <QDebug>
#include <QPointer>
namespace KDDockWidgets
{
class TitleBar;
class TabWidget;
class DropArea;
class DockWidgetBase;
class Item;
class FloatingWindow;
/**
* @brief A DockWidget wrapper that adds a QTabWidget and a TitleBar
*
* Frame is the actual widget that goes into the MultiSplitter. It provides a TitleBar which you
* can use to detach, and also a QTabWidget so you can tab dock widgets together.
*
* This class doesn't actually add window frames and it's never a top-level widget. A Frame is always
* inside a MultiSplitter (DropArea). Be it a MultiSplitter belonging to a MainWindow or belonging
* to a FloatingWindow.
*/
class DOCKS_EXPORT Frame : public QWidgetAdapter
{
Q_OBJECT
Q_PROPERTY(KDDockWidgets::TitleBar* titleBar READ titleBar CONSTANT)
public:
typedef QList<Frame*> List;
explicit Frame(QWidgetOrQuick* parent = nullptr, FrameOptions = FrameOption_None);
~Frame() override;
static Frame* deserialize(const LayoutSaver::Frame &);
LayoutSaver::Frame serialize() const;
///@brief Adds a widget into the Frame's TabWidget
void addWidget(DockWidgetBase*);
///@overload
void addWidget(Frame*);
///@overload
void addWidget(FloatingWindow* floatingWindow);
///@brief Inserts a widget into the Frame's TabWidget at @p index
void insertWidget(DockWidgetBase*, int index);
///@brief removes a dockwidget from the frame
void removeWidget(DockWidgetBase*);
void updateTitleAndIcon();
void updateTitleBarVisibility();
bool containsMouse(QPoint globalPos) const;
TitleBar* titleBar() const;
TitleBar* actualTitleBar() const;
TabWidget* tabWidget() const;
QString title() const;
QIcon icon() const;
const QVector<DockWidgetBase*> dockWidgets() const;
DockWidgetBase* dockWidgetAt(int index) const;
void setDropArea(DropArea*);
bool isTheOnlyFrame() const;
/**
* @brief Returns whether this frame is floating. A floating frame isn't attached to any other MainWindow,
* and if it's attached to a FloatingWindow then it's considered floating if it's the only frame in that Window.
* A floating frame can have multiple dock widgets (tabbed), in which case each DockWidget::isFloating() returns false,
* in which case you can use isInFloatingWindow() which would still return true
*/
bool isFloating() const;
/**
* @brief Returns whether this frame is in a FloatingWindow, as opposed to MainWindow.
*
* After setup it's equivalent to !isInMainWindow().
*/
bool isInFloatingWindow() const;
/**
* @brief Returns whether this frame is docked inside a MainWindow.
*/
bool isInMainWindow() const;
/**
* @brief returns if this widget is the central frame
* MainWindow supports a mode where the middle frame is persistent even if no dock widget is there.
*
* @return whether this widget is the central frame in a main window
*/
bool isCentralFrame() const { return m_options & FrameOption_IsCentralFrame; }
/**
* @brief whether the tab widget will always show tabs, even if there's only 1 dock widget
*
* While technically a non-floating dock widget is always tabbed, the user won't see the tabs
* as in most cases there's only 1 widget tabbed. But for the main window central frame it's
* often wanted to see tabs even if there's only 1 widget, where each widget represents a "document".
*
* @return whether the tab widget will always show tabs, even if there's only 1 dock widget
*/
bool alwaysShowsTabs() const { return m_options & FrameOption_AlwaysShowsTabs; }
/// @brief returns the number of dock widgets inside the frame
int dockWidgetCount() const;
/// @brief returns whether the dockwidget @p w is inside this frame
bool contains(DockWidgetBase* w) const;
///@brief returns the FloatingWindow this frame is in, if any
FloatingWindow* floatingWindow() const;
/**
* @brief Puts the Frame back in its previous main window position
*
* Usually DockWidget::Private::restoreToPreviousPosition() is used, but
* when we have a floating frame with tabs we just reuse the frame instead of
* moving the tabbed dock widgets one by one.
*/
void restoreToPreviousPosition();
void onCloseEvent(QCloseEvent* e) override;
int currentTabIndex() const;
void setCurrentTabIndex(int);
DockWidgetBase* currentDockWidget() const;
FrameOptions options() const { return m_options; }
bool anyNonClosable() const;
///@brief returns whether there's 0 dock widgets. If not persistent then the Frame will delete itself.
bool isEmpty() const { return dockWidgetCount() == 0; }
///@brief returns whether there's only 1 dock widget.
bool hasSingleDockWidget() const { return dockWidgetCount() == 1; }
///@brief Called when a dock widget child @p w is shown
void onDockWidgetShown(DockWidgetBase* w);
///@brief Called when a dock widget child @p w is hidden
void onDockWidgetHidden(DockWidgetBase* w);
///@brief sets the layout item that either contains this Frame in the layout or is a placeholder
void setLayoutItem(Item* item);
///@brief returns the layout item that either contains this Frame in the layout or is a placeholder
Item* layoutItem() const;
///@brief For tests-only. Returns the number of Frame instances in the whole application.
static int dbg_numFrames();
///@brief for debug only, prints some debug information
void dumpDebug();
/**
* @brief Returns whether a deleteLater has already been issued
*/
bool beingDeletedLater() const;
/**
* @brief returns true if tabs are visible
*
* @sa hasTabsVisibleChanged()
**/
bool hasTabsVisible() const;
Q_SIGNALS:
void currentDockWidgetChanged(KDDockWidgets::DockWidgetBase*);
void numDockWidgetsChanged();
void hasTabsVisibleChanged();
void layoutInvalidated();
private:
Q_DISABLE_COPY(Frame)
friend class TestDocks;
friend class TabWidget;
void onDockWidgetCountChanged();
void onCurrentTabChanged(int index);
void scheduleDeleteLater();
bool event(QEvent*) override;
TabWidget* const m_tabWidget;
TitleBar* const m_titleBar;
DropArea* m_dropArea = nullptr;
const FrameOptions m_options;
QPointer<Item> m_layoutItem;
bool m_beingDeleted = false;
};
}
inline QDebug operator<< (QDebug d, KDDockWidgets::Frame* frame)
{
if(frame)
{
d << static_cast<QObject*>(frame);
d << "; window=" << frame->window();
d << "; options=" << frame->options();
d << "; dockwidgets=" << frame->dockWidgets();
}
else
{
d << "nullptr";
}
return d;
}
#endif

View File

@ -0,0 +1,191 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief Implements a QTabWidget derived class with support for docking and undocking
* KDockWidget::DockWidget as tabs .
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_TAB_WIDGET_P_H
#define KD_TAB_WIDGET_P_H
#include "docks_export.h"
#include "Draggable_p.h"
#include "Frame_p.h"
#include "DockWidgetBase.h"
#include <QTabBar>
#include <QVector>
#include <memory>
namespace KDDockWidgets
{
class DockWidgetBase;
class TabWidget;
///@brief a QTabBar derived class to be used by KDDockWidgets::TabWidget
class DOCKS_EXPORT TabBar : public Draggable
{
public:
/**
* @brief Constructs a new TabBar
* @param parent The parent TabWidget
*/
explicit TabBar(QWidgetOrQuick* thisWidget, TabWidget* parent = nullptr);
/**
* @brief returns the dock widgets at tab number @p index
* @param index the tab number from which we want the dock widget
* @return the dock widget at tab number @p index
*/
DockWidgetBase* dockWidgetAt(int index) const;
///@overload
DockWidgetBase* dockWidgetAt(QPoint localPos) const;
// Draggable
std::unique_ptr<WindowBeingDragged> makeWindow() override;
/**
* @brief detaches a dock widget and shows it as a floating dock widget
* The dock widget is morphed into a FloatingWindow for convenience.
* @param dockWidget the dock widget to detach
* @returns the created FloatingWindow
*/
FloatingWindow* detachTab(DockWidgetBase* dockWidget);
void onMousePress(QPoint localPos);
///@brief returns whether there's only 1 tab
bool hasSingleDockWidget() const;
virtual int numDockWidgets() const = 0;
virtual int tabAt(QPoint localPos) const = 0;
/**
* @brief Returns this class as a QWidget (if using QtWidgets) or QQuickItem
*/
QWidgetOrQuick* asWidget() const;
private:
TabWidget* const m_tabWidget;
QPointer<DockWidgetBase> m_lastPressedDockWidget = nullptr;
QWidgetOrQuick* const m_thisWidget;
};
class DOCKS_EXPORT TabWidget : public Draggable
{
public:
/**
* @brief Constructs a new TabWidget, with @p frame as a parent
*/
explicit TabWidget(QWidgetOrQuick* thisWidget, Frame* frame);
/**
* @brief returns the number of dock widgets in this TabWidget
*/
virtual int numDockWidgets() const = 0;
/**
* @brief Removes a dock widget from the TabWidget
*/
virtual void removeDockWidget(DockWidgetBase*) = 0;
/**
* @brief Returns the index of the dock widget, or -1 if it doesn't exist
*/
virtual int indexOfDockWidget(DockWidgetBase*) const = 0;
/**
* @brief Sets the current dock widget index
*/
virtual void setCurrentDockWidget(int index) = 0;
void setCurrentDockWidget(DockWidgetBase*);
virtual void insertDockWidget(int index, DockWidgetBase*, const QIcon &, const QString & title) = 0;
virtual void setTabBarAutoHide(bool) = 0;
/**
* @brief Returns the current index
*/
virtual int currentIndex() const = 0;
///@brief appends a dock widget into this TabWidget
void addDockWidget(DockWidgetBase*);
/**
* @brief Returns the dock widget tabbed at index @p index
*/
virtual DockWidgetBase* dockwidgetAt(int index) const = 0;
/**
* @brief detaches a dock widget and shows it as a floating dock widget
* @param dockWidget the dock widget to detach
*/
virtual void detachTab(DockWidgetBase* dockWidget) = 0;
/**
* @brief inserts @p dockwidget into the TabWidget, at @p index
* @param dockwidget the dockwidget to insert
* @param index The index to where to put it
*/
void insertDockWidget(DockWidgetBase* dockwidget, int index);
/**
* @brief Returns whether dockwidget @p dw is contained in this tab widget
* Equivalent to indexOf(dw) != -1
*/
bool contains(DockWidgetBase* dw) const;
/**
* @brief Returns the tab bar
*/
virtual TabBar* tabBar() const = 0;
/**
* @brief Returns this class as a QWidget (if using QtWidgets) or QQuickItem
*/
QWidgetOrQuick* asWidget() const;
///@brief getter for the frame
Frame* frame() const;
// Draggable interface
std::unique_ptr<WindowBeingDragged> makeWindow() override;
protected:
void onTabInserted();
void onTabRemoved();
private:
Frame* const m_frame;
QWidgetOrQuick* const m_thisWidget;
Q_DISABLE_COPY(TabWidget)
};
}
#endif

View File

@ -0,0 +1,119 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_TITLEBAR_P_H
#define KD_TITLEBAR_P_H
#include "docks_export.h"
#include "QWidgetAdapter.h"
#include "Draggable_p.h"
#include "Frame_p.h"
#include "DockWidgetBase.h"
#include <QVector>
#include <QIcon>
class QHBoxLayout;
class QLabel;
namespace KDDockWidgets
{
class DockWidgetBase;
class Frame;
class Button;
class DOCKS_EXPORT TitleBar : public QWidgetAdapter
, public Draggable
{
Q_OBJECT
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(bool hasIcon READ hasIcon NOTIFY iconChanged)
public:
typedef QVector<TitleBar*> List;
explicit TitleBar(Frame* parent);
explicit TitleBar(FloatingWindow* parent);
~TitleBar() override;
void setTitle(const QString & title);
QString title() const { return m_title; }
void setIcon(const QIcon & icon);
std::unique_ptr<WindowBeingDragged> makeWindow() override;
///@brief Returns true if the dock widget which has this title bar is floating
bool isFloating() const;
///@brief the list of dockwidgets under this TitleBar.
/// There should always be at least 1. If more than 1 then they are tabbed.
DockWidgetBase::List dockWidgets() const;
///@brief returns whether this title bar supports a floating/unfloating button
bool supportsFloatingButton() const;
///@brief returns whether this title bar has an icon
bool hasIcon() const;
///@brief the icon
QIcon icon() const;
///@brief toggle floating
bool onDoubleClicked();
///@brief getter for m_frame
const Frame* frame() const { return m_frame; }
///@brief getter for m_floatingWindow
const FloatingWindow* floatingWindow() const { return m_floatingWindow; }
Q_SIGNALS:
void titleChanged();
void iconChanged();
protected:
void onCloseClicked();
void onFloatClicked();
virtual void updateFloatButton() {}
virtual void updateCloseButton() {}
// The following are needed for the unit-tests
virtual bool isCloseButtonVisible() const { return true; }
virtual bool isCloseButtonEnabled() const { return true; }
virtual bool isFloatButtonVisible() const { return true; }
virtual bool isFloatButtonEnabled() const { return true; }
private:
friend class TestDocks;
void init();
QPoint m_pressPos;
QString m_title;
QIcon m_icon;
Frame* const m_frame;
FloatingWindow* const m_floatingWindow;
};
}
#endif

View File

@ -0,0 +1,48 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_FLOATING_WINDOWWIDGET_P_H
#define KD_FLOATING_WINDOWWIDGET_P_H
#include "FloatingWindow_p.h"
class QVBoxLayout;
namespace KDDockWidgets
{
class DOCKS_EXPORT FloatingWindowWidget : public FloatingWindow
{
Q_OBJECT
public:
explicit FloatingWindowWidget(QWidget* parent = nullptr);
explicit FloatingWindowWidget(Frame* frame, QWidget* parent = nullptr);
protected:
void paintEvent(QPaintEvent*) override;
private:
void init();
Q_DISABLE_COPY(FloatingWindowWidget)
QVBoxLayout* const m_vlayout;
};
}
#endif

View File

@ -0,0 +1,48 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_FRAME_WIDGET_P_H
#define KD_FRAME_WIDGET_P_H
#include "../Frame_p.h"
class QTabBar;
namespace KDDockWidgets
{
/**
* @brief The GUI counterpart of Frame. Inherits Frame and implements paintEvent().
*/
class DOCKS_EXPORT FrameWidget : public Frame
{
Q_OBJECT
public:
explicit FrameWidget(QWidget* parent = nullptr, FrameOptions = FrameOption_None);
QTabBar* tabBar() const;
protected:
void paintEvent(QPaintEvent*) override;
};
}
#endif

View File

@ -0,0 +1,73 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief A class that is QWidget when building for QtWidgets, and QObject when building for QtQuick.
*
* Allows to have the same code base supporting both stacks.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KDDOCKWIDGETS_QWIDGETADAPTERWIDGETS_P_H
#define KDDOCKWIDGETS_QWIDGETADAPTERWIDGETS_P_H
#include "../../docks_export.h"
#include <QWidget>
namespace KDDockWidgets
{
class FloatingWindow;
class DOCKS_EXPORT QWidgetAdapter : public QWidget
{
Q_OBJECT
public:
explicit QWidgetAdapter(QWidget* parent = nullptr, Qt::WindowFlags f = {});
~QWidgetAdapter() override;
///@brief returns the FloatingWindow this widget is in, otherwise nullptr
FloatingWindow* floatingWindow() const;
void setFlag(Qt::WindowType, bool on = true);
protected:
void raiseAndActivate();
bool event(QEvent* e) override;
void resizeEvent(QResizeEvent*) override;
void mousePressEvent(QMouseEvent*) override;
void mouseMoveEvent(QMouseEvent*) override;
void mouseReleaseEvent(QMouseEvent*) override;
void closeEvent(QCloseEvent*) override;
virtual bool onResize(QSize newSize);
virtual void onLayoutRequest();
virtual void onMousePress();
virtual void onMouseMove(QPoint globalPos);
virtual void onMouseRelease();
virtual void onCloseEvent(QCloseEvent*);
};
}
#endif

View File

@ -0,0 +1,45 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_MULTISPLITTER_SEPARATORWIDGET_P_H
#define KD_MULTISPLITTER_SEPARATORWIDGET_P_H
#include "multisplitter/Separator_p.h"
class QPaintEvent;
namespace KDDockWidgets
{
class DOCKS_EXPORT SeparatorWidget : public Separator
{
Q_OBJECT
public:
explicit SeparatorWidget(Anchor* anchor, QWidgetAdapter* parent = nullptr);
protected:
void paintEvent(QPaintEvent*) override;
void enterEvent(QEvent*) override;
void leaveEvent(QEvent*) override;
};
}
#endif

View File

@ -0,0 +1,57 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief Implements a QTabWidget derived class with support for docking and undocking
* KDockWidget::DockWidget as tabs .
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KD_TABBAR_WIDGET_P_H
#define KD_TABBAR_WIDGET_P_H
#include "TabWidget_p.h"
#include <QTabBar>
class QMouseEvent;
namespace KDDockWidgets
{
class DockWidget;
class TabWidget;
class DOCKS_EXPORT TabBarWidget : public QTabBar, public TabBar
{
Q_OBJECT
public:
explicit TabBarWidget(TabWidget* parent = nullptr);
int numDockWidgets() const override;
int tabAt(QPoint localPos) const override;
protected:
void mousePressEvent(QMouseEvent*) override;
};
}
#endif

View File

@ -0,0 +1,71 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* @brief The QWidget counter part of TabWidgetWidget. Handles GUI while TabWidget handles state.
*
* @author Sérgio Martins \<sergio.martins@kdab.com\>
*/
#ifndef KDTABWIDGETWIDGET_P_H
#define KDTABWIDGETWIDGET_P_H
#include "../TabWidget_p.h"
#include <QTabWidget>
namespace KDDockWidgets
{
class Frame;
class TabBar;
class DOCKS_EXPORT TabWidgetWidget : public QTabWidget, public TabWidget
{
Q_OBJECT
public:
explicit TabWidgetWidget(Frame* parent);
TabBar* tabBar() const override;
int numDockWidgets() const override;
void removeDockWidget(DockWidgetBase*) override;
int indexOfDockWidget(DockWidgetBase*) const override;
protected:
void paintEvent(QPaintEvent*) override;
void tabInserted(int index) override;
void tabRemoved(int index) override;
bool isPositionDraggable(QPoint p) const override;
void setCurrentDockWidget(int index) override;
void insertDockWidget(int index, DockWidgetBase*, const QIcon &, const QString & title) override;
void setTabBarAutoHide(bool) override;
void detachTab(DockWidgetBase* dockWidget) override;
DockWidgetBase* dockwidgetAt(int index) const override;
int currentIndex() const override;
private:
Q_DISABLE_COPY(TabWidgetWidget)
TabBar* const m_tabBar;
};
}
#endif

View File

@ -0,0 +1,123 @@
/*
This file is part of KDDockWidgets.
Copyright (C) 2018-2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
Author: Sérgio Martins <sergio.martins@kdab.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KD_TITLEBARWIDGET_P_H
#define KD_TITLEBARWIDGET_P_H
#include "../../docks_export.h"
#include "../TitleBar_p.h"
#include <QPainter>
#include <QToolButton>
#include <QStyle>
#include <QWidget>
#include <QVector>
#include <QStyleOptionToolButton>
class QHBoxLayout;
class QLabel;
namespace KDDockWidgets
{
class DockWidget;
class Frame;
class DOCKS_EXPORT TitleBarWidget : public TitleBar
{
Q_OBJECT
public:
explicit TitleBarWidget(Frame* parent);
explicit TitleBarWidget(FloatingWindow* parent);
~TitleBarWidget() override;
///@brief getter for the close button
QWidget* closeButton() const;
static QAbstractButton* createButton(QWidget* parent, const QIcon & icon);
protected:
void paintEvent(QPaintEvent*) override;
void mouseDoubleClickEvent(QMouseEvent*) override;
void updateFloatButton() override;
void updateCloseButton() override;
// The following are needed for the unit-tests
bool isCloseButtonVisible() const override;
bool isCloseButtonEnabled() const override;
bool isFloatButtonVisible() const override;
bool isFloatButtonEnabled() const override;
private:
void init();
int buttonAreaWidth() const;
QRect iconRect() const;
QHBoxLayout* const m_layout;
QAbstractButton* m_closeButton = nullptr;
QAbstractButton* m_floatButton = nullptr;
QLabel* m_dockWidgetIcon = nullptr;
};
class Button : public QToolButton
{
Q_OBJECT
public:
explicit Button(QWidget* parent)
: QToolButton(parent)
{
//const int margin = style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, nullptr, this) * 2;
QSize sz = /*QSize(margin, margin) + */ QSize(16, 16);
setFixedSize(sz);
}
~Button() override;
void paintEvent(QPaintEvent*) override
{
QPainter p(this);
QStyleOptionToolButton opt;
opt.init(this);
if(isEnabled() && underMouse())
{
if(isDown())
{
opt.state |= QStyle::State_Sunken;
}
else
{
opt.state |= QStyle::State_Raised;
}
style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &p, this);
}
opt.subControls = QStyle::SC_None;
opt.features = QStyleOptionToolButton::None;
opt.icon = icon();
opt.iconSize = size();
style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this);
}
};
}
#endif

View File

@ -66,6 +66,7 @@ INCLUDEPATH += \
Src/Global \
Src/Utils \
Src/ThirdPartyLibs/ldconvert \
Src/ThirdPartyLibs/KDDockWidgets/include \
../zydis_wrapper \
../zydis_wrapper/zydis/include
@ -353,10 +354,12 @@ LIBS += -luser32 -ladvapi32 -lwinmm -lshell32
# Windows x86 (32bit) specific build
LIBS += -L"$$PWD/../zydis_wrapper/bin/x32$${DIR_SUFFIX}" -lzydis_wrapper
LIBS += -L"$$PWD/Src/ThirdPartyLibs/ldconvert" -lldconvert_x86
LIBS += -L"$$PWD/Src/ThirdPartyLibs/KDDockWidgets/lib" -lkddockwidgets_x86
LIBS += -L"$${X64_BIN_DIR}" -lx32bridge
} else {
# Windows x64 (64bit) specific build
LIBS += -L"$$PWD/../zydis_wrapper/bin/x64$${DIR_SUFFIX}" -lzydis_wrapper
LIBS += -L"$$PWD/Src/ThirdPartyLibs/ldconvert" -lldconvert_x64
LIBS += -L"$$PWD/Src/ThirdPartyLibs/KDDockWidgets/lib" -lkddockwidgets_x64
LIBS += -L"$${X64_BIN_DIR}" -lx64bridge
}