Improved icons for all button, adjusted size of dock marker

This commit is contained in:
Uwe Kindler 2019-05-14 15:32:50 +02:00
parent a012af2aac
commit e98fd5bcb3
11 changed files with 239 additions and 59 deletions

View File

@ -282,7 +282,7 @@ CMainWindow::CMainWindow(QWidget *parent) :
d->createContent();
// Default window geometry
resize(800, 600);
resize(1280, 720);
d->restoreState();
d->restorePerspectives();

View File

@ -238,7 +238,7 @@ CFloatingDockContainer* CDockAreaTabBar::makeAreaFloating(const QPoint& Offset,
{
QSize Size = d->DockArea->size();
CFloatingDockContainer* FloatingWidget = new CFloatingDockContainer(d->DockArea);
FloatingWidget->startFloating(Offset, Size, DragState);
FloatingWidget->startFloating(Offset, Size, DragState, nullptr);
auto TopLevelDockWidget = FloatingWidget->topLevelDockWidget();
if (TopLevelDockWidget)
{

View File

@ -97,6 +97,23 @@ struct DockAreaTitleBarPrivate
{
return DockArea->dockManager()->configFlags().testFlag(Flag);
}
/**
* Helper class to set title bar burron icons depending on operating system
* and to avoid duplicated code
*/
void setTitleBarButtonIcon(tTileBarButton* Button, QStyle::StandardPixmap StandarPixmap)
{
#ifdef Q_OS_LINUX
Button->setIcon(_this->style()->standardIcon(StandarPixmap));
#else
QIcon Icon;
QPixmap normalPixmap = _this->style()->standardPixmap(StandarPixmap, 0, Button);
Icon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
Icon.addPixmap(normalPixmap, QIcon::Normal);
Button->setIcon(Icon);
#endif
}
};// struct DockAreaTitleBarPrivate
@ -112,18 +129,12 @@ DockAreaTitleBarPrivate::DockAreaTitleBarPrivate(CDockAreaTitleBar* _public) :
//============================================================================
void DockAreaTitleBarPrivate::createButtons()
{
// Tabs menu button
TabsMenuButton = new tTileBarButton();
TabsMenuButton->setObjectName("tabsMenuButton");
TabsMenuButton->setAutoRaise(true);
TabsMenuButton->setPopupMode(QToolButton::InstantPopup);
QIcon MenuIcon;
QPixmap normalPixmap = _this->style()->standardPixmap(
QStyle::SP_TitleBarUnshadeButton, 0, TabsMenuButton);
MenuIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
MenuIcon.addPixmap(normalPixmap, QIcon::Normal);
TabsMenuButton->setIcon(MenuIcon);
setTitleBarButtonIcon(TabsMenuButton, QStyle::SP_TitleBarUnshadeButton);
QMenu* TabsMenu = new QMenu(TabsMenuButton);
#ifndef QT_NO_TOOLTIP
TabsMenu->setToolTipsVisible(true);
@ -138,6 +149,7 @@ void DockAreaTitleBarPrivate::createButtons()
_this->connect(TabsMenuButton->menu(), SIGNAL(triggered(QAction*)),
SLOT(onTabsMenuActionTriggered(QAction*)));
// Undock button
UndockButton = new tTileBarButton();
UndockButton->setObjectName("undockButton");
@ -145,26 +157,17 @@ void DockAreaTitleBarPrivate::createButtons()
#ifndef QT_NO_TOOLTIP
UndockButton->setToolTip(QObject::tr("Detach Group"));
#endif
QIcon UndockIcon;
normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarNormalButton, 0, UndockButton);
UndockIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
UndockIcon.addPixmap(normalPixmap, QIcon::Normal);
UndockButton->setIcon(UndockIcon);
setTitleBarButtonIcon(UndockButton, QStyle::SP_TitleBarNormalButton);
UndockButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
TopLayout->addWidget(UndockButton, 0);
_this->connect(UndockButton, SIGNAL(clicked()), SLOT(onUndockButtonClicked()));
// Close button
CloseButton = new tTileBarButton();
CloseButton->setObjectName("closeButton");
CloseButton->setAutoRaise(true);
// The standard icons does not look good on high DPI screens
QIcon CloseIcon;// = _this->style()->standardIcon(QStyle::SP_TitleBarCloseButton);
normalPixmap = _this->style()->standardPixmap(QStyle::SP_TitleBarCloseButton, 0, CloseButton);
CloseIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
CloseIcon.addPixmap(normalPixmap, QIcon::Normal);
CloseButton->setIcon(CloseIcon);
setTitleBarButtonIcon(CloseButton, QStyle::SP_TitleBarCloseButton);
#ifndef QT_NO_TOOLTIP
if (testConfigFlag(CDockManager::DockAreaCloseButtonClosesTab))
{

View File

@ -145,7 +145,11 @@ DockManagerPrivate::DockManagerPrivate(CDockManager* _public) :
void DockManagerPrivate::loadStylesheet()
{
QString Result;
#ifdef Q_OS_LINUX
QFile StyleSheetFile(":ads/stylesheets/default_linux.css");
#else
QFile StyleSheetFile(":ads/stylesheets/default.css");
#endif
StyleSheetFile.open(QIODevice::ReadOnly);
QTextStream StyleSheetStream(&StyleSheetFile);
Result = StyleSheetStream.readAll();

View File

@ -132,6 +132,20 @@ struct DockOverlayCrossPrivate
return Color;
}
//============================================================================
/**
* Helper function that returns the drop indicator width depending on the
* operating system
*/
qreal dropIndicatiorWidth() const
{
#ifdef Q_OS_LINUX
return 40;
#else
return static_cast<qreal>(l->fontMetrics().height()) * 3.f;
#endif
}
//============================================================================
QWidget* createDropIndicatorWidget(DockWidgetArea DockWidgetArea,
@ -140,7 +154,7 @@ struct DockOverlayCrossPrivate
QLabel* l = new QLabel();
l->setObjectName("DockWidgetAreaLabel");
const qreal metric = static_cast<qreal>(l->fontMetrics().height()) * 3.f;
const qreal metric = dropIndicatiorWidth();
const QSizeF size(metric, metric);
l->setPixmap(createHighDpiDropIndicatorPixmap(size, DockWidgetArea, Mode));
@ -154,7 +168,7 @@ struct DockOverlayCrossPrivate
void updateDropIndicatorIcon(QWidget* DropIndicatorWidget)
{
QLabel* l = qobject_cast<QLabel*>(DropIndicatorWidget);
const qreal metric = static_cast<qreal>(l->fontMetrics().height()) * 3.f;
const qreal metric = dropIndicatiorWidth();
const QSizeF size(metric, metric);
int Area = l->property("dockWidgetArea").toInt();

View File

@ -151,6 +151,7 @@ void DockWidgetTabPrivate::createLayout()
CloseIcon.addPixmap(normalPixmap, QIcon::Normal);
CloseIcon.addPixmap(internal::createTransparentPixmap(normalPixmap, 0.25), QIcon::Disabled);
CloseButton->setIcon(CloseIcon);
CloseButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
CloseButton->setVisible(false);
#ifndef QT_NO_TOOLTIP
@ -223,7 +224,7 @@ bool DockWidgetTabPrivate::startFloating(eDragState DraggingState)
if (DraggingFloatingWidget == DraggingState)
{
FloatingWidget->startDragging(DragStartMousePosition, Size);
FloatingWidget->startDragging(DragStartMousePosition, Size, _this);
auto Overlay = DockWidget->dockManager()->containerOverlay();
Overlay->setAllowedAreas(OuterDockAreas);
this->FloatingWidget = FloatingWidget;

View File

@ -38,6 +38,8 @@
#include <QDebug>
#include <QAbstractButton>
#include <QElapsedTimer>
#include <QTime>
#include <QAbstractEventDispatcher>
#include "DockContainerWidget.h"
#include "DockAreaWidget.h"
@ -45,7 +47,12 @@
#include "DockWidget.h"
#include "DockOverlay.h"
#ifdef Q_OS_LINUX
#include "FloatingWidgetTitleBar.h"
#endif
#include <iostream>
#include <xcb/xcb.h>
namespace ads
{
@ -63,6 +70,8 @@ struct FloatingDockContainerPrivate
QPoint DragStartMousePosition;
CDockContainerWidget* DropContainer = nullptr;
CDockAreaWidget* SingleDockArea = nullptr;
QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr;
/**
* Private data constructor
@ -84,6 +93,15 @@ struct FloatingDockContainerPrivate
{
DraggingState = StateId;
}
void setWindowTitle(const QString& Text)
{
#ifdef Q_OS_LINUX
TitleBar->setTitle(Text);
#else
_this->setWindowTitle(Text);
#endif
}
};
// struct FloatingDockContainerPrivate
@ -216,22 +234,33 @@ void FloatingDockContainerPrivate::updateDropOverlays(const QPoint& GlobalPos)
//============================================================================
CFloatingDockContainer::CFloatingDockContainer(CDockManager* DockManager) :
QWidget(DockManager, Qt::Window),
tFloatingWidgetBase(DockManager),
d(new FloatingDockContainerPrivate(this))
{
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
d->DockManager = DockManager;
d->DockContainer = new CDockContainerWidget(DockManager, this);
connect(d->DockContainer, SIGNAL(dockAreasAdded()), this, SLOT(onDockAreasAddedOrRemoved()));
connect(d->DockContainer, SIGNAL(dockAreasRemoved()), this, SLOT(onDockAreasAddedOrRemoved()));
#ifdef Q_OS_LINUX
d->TitleBar = new CFloatingWidgetTitleBar(this);
setWindowFlag(Qt::Tool);
QDockWidget::setWidget(d->DockContainer);
QDockWidget::setFloating(true);
QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
setTitleBarWidget(d->TitleBar);
connect(d->TitleBar, SIGNAL(closeRequested()), SLOT(close()));
#else
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
QBoxLayout* l = new QBoxLayout(QBoxLayout::TopToBottom);
l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(0);
setLayout(l);
#endif
d->DockContainer = new CDockContainerWidget(DockManager, this);
connect(d->DockContainer, SIGNAL(dockAreasAdded()), this, SLOT(onDockAreasAddedOrRemoved()));
connect(d->DockContainer, SIGNAL(dockAreasRemoved()), this, SLOT(onDockAreasAddedOrRemoved()));
l->addWidget(d->DockContainer);
DockManager->registerFloatingWidget(this);
// We install an event filter to detect mouse release events because we
// do not receive mouse release event if the floating widget is behind
// the drop overlay cross
@ -244,6 +273,9 @@ CFloatingDockContainer::CFloatingDockContainer(CDockAreaWidget* DockArea) :
CFloatingDockContainer(DockArea->dockManager())
{
d->DockContainer->addDockArea(DockArea);
#ifdef Q_OS_LINUX
d->TitleBar->enableCloseButton(isClosable());
#endif
}
@ -252,6 +284,9 @@ CFloatingDockContainer::CFloatingDockContainer(CDockWidget* DockWidget) :
CFloatingDockContainer(DockWidget->dockManager())
{
d->DockContainer->addDockWidget(CenterDockWidgetArea, DockWidget);
#ifdef Q_OS_LINUX
d->TitleBar->enableCloseButton(isClosable());
#endif
}
//============================================================================
@ -323,11 +358,15 @@ void CFloatingDockContainer::closeEvent(QCloseEvent *event)
// Starting from Qt version 5.12.2 this seems to work again. But
// now the QEvent::NonClientAreaMouseButtonPress function returns always
// Qt::RightButton even if the left button was pressed
#ifndef Q_OS_LINUX
#if (QT_VERSION > QT_VERSION_CHECK(5, 9, 2) && QT_VERSION < QT_VERSION_CHECK(5, 12, 2))
event->ignore();
this->hide();
#else
Super::closeEvent(event);
#endif
#else // Q_OS_LINUX
Super::closeEvent(event);
#endif
}
else
@ -442,6 +481,7 @@ bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
if (event->type() == QEvent::MouseButtonRelease && d->isState(DraggingFloatingWidget))
{
qDebug() << "FloatingWidget::eventFilter QEvent::MouseButtonRelease";
finishDragging();
d->titleMouseReleaseEvent();
}
@ -451,11 +491,23 @@ bool CFloatingDockContainer::eventFilter(QObject *watched, QEvent *event)
//============================================================================
void CFloatingDockContainer::startFloating(const QPoint& DragStartMousePos, const QSize& Size,
eDragState DragState)
eDragState DragState, QWidget* MouseEventHandler)
{
resize(Size);
d->setState(DragState);
d->DragStartMousePosition = DragStartMousePos;
#ifdef Q_OS_LINUX
if (DraggingFloatingWidget == DragState)
{
setAttribute(Qt::WA_X11NetWmWindowTypeDock, true);
setWindowOpacity(0.6);
d->MouseEventHandler = MouseEventHandler;
if (d->MouseEventHandler)
{
d->MouseEventHandler->grabMouse();
}
}
#endif
moveFloating();
show();
@ -486,7 +538,7 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
if (TopLevelDockArea)
{
d->SingleDockArea = TopLevelDockArea;
this->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
d->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
connect(d->SingleDockArea, SIGNAL(currentChanged(int)), this,
SLOT(onDockAreaCurrentChanged(int)));
}
@ -498,7 +550,7 @@ void CFloatingDockContainer::onDockAreasAddedOrRemoved()
SLOT(onDockAreaCurrentChanged(int)));
d->SingleDockArea = nullptr;
}
this->setWindowTitle(qApp->applicationDisplayName());
d->setWindowTitle(qApp->applicationDisplayName());
}
}
@ -509,11 +561,11 @@ void CFloatingDockContainer::updateWindowTitle()
auto TopLevelDockArea = d->DockContainer->topLevelDockArea();
if (TopLevelDockArea)
{
this->setWindowTitle(TopLevelDockArea->currentDockWidget()->windowTitle());
d->setWindowTitle(TopLevelDockArea->currentDockWidget()->windowTitle());
}
else
{
this->setWindowTitle(qApp->applicationDisplayName());
d->setWindowTitle(qApp->applicationDisplayName());
}
}
@ -522,7 +574,7 @@ void CFloatingDockContainer::updateWindowTitle()
void CFloatingDockContainer::onDockAreaCurrentChanged(int Index)
{
Q_UNUSED(Index);
this->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
d->setWindowTitle(d->SingleDockArea->currentDockWidget()->windowTitle());
}
@ -560,6 +612,24 @@ QList<CDockWidget*> CFloatingDockContainer::dockWidgets() const
}
//============================================================================
void CFloatingDockContainer::finishDragging()
{
std::cout << "CFloatingDockContainer::finishDragging" << std::endl;
#ifdef Q_OS_LINUX
setAttribute(Qt::WA_X11NetWmWindowTypeDock, false);
setWindowOpacity(1);
activateWindow();
if (d->MouseEventHandler)
{
d->MouseEventHandler->releaseMouse();
d->MouseEventHandler = nullptr;
}
#endif
}
} // namespace ads
//---------------------------------------------------------------------------

View File

@ -29,10 +29,16 @@
//============================================================================
// INCLUDES
//============================================================================
#include <QWidget>
#include "ads_globals.h"
#ifdef Q_OS_LINUX
#include <QDockWidget>
#define tFloatingWidgetBase QDockWidget
#else
#include <QWidget>
#define tFloatingWidgetBase QWidget
#endif
class QXmlStreamReader;
namespace ads
@ -49,13 +55,14 @@ class CDockWidgetTab;
struct DockWidgetTabPrivate;
class CDockAreaTitleBar;
struct DockAreaTitleBarPrivate;
class CFloatingWidgetTitleBar;
/**
* This implements a floating widget that is a dock container that accepts
* docking of dock widgets like the main window and that can be docked into
* another dock container
*/
class ADS_EXPORT CFloatingDockContainer : public QWidget
class ADS_EXPORT CFloatingDockContainer : public tFloatingWidgetBase
{
Q_OBJECT
private:
@ -70,6 +77,7 @@ private:
friend struct DockAreaTitleBarPrivate;
friend class CDockWidget;
friend class CDockAreaWidget;
friend class CFloatingWidgetTitleBar;
private slots:
void onDockAreasAddedOrRemoved();
@ -82,23 +90,30 @@ protected:
* depending on the start position given in Pos parameter
*/
void startFloating(const QPoint& DragStartMousePos, const QSize& Size,
eDragState DragState);
eDragState DragState, QWidget* MouseEventHandler);
/**
* Call this function to start dragging the floating widget
*/
void startDragging(const QPoint& DragStartMousePos, const QSize& Size)
void startDragging(const QPoint& DragStartMousePos, const QSize& Size,
QWidget* MouseEventHandler)
{
startFloating(DragStartMousePos, Size, DraggingFloatingWidget);
startFloating(DragStartMousePos, Size, DraggingFloatingWidget, MouseEventHandler);
}
/**
* Call this function if you explecitely want to signal that dragging has
* finished
*/
void finishDragging();
/**
* Call this function if you just want to initialize the position
* and size of the floating widget
*/
void initFloatingGeometry(const QPoint& DragStartMousePos, const QSize& Size)
{
startFloating(DragStartMousePos, Size, DraggingInactive);
startFloating(DragStartMousePos, Size, DraggingInactive, nullptr);
}
/**

View File

@ -0,0 +1,68 @@
#ifndef FLOATINGWIDGETTITLEBAR_H
#define FLOATINGWIDGETTITLEBAR_H
/*******************************************************************************
** Qt Advanced Docking System
** Copyright (C) 2017 Uwe Kindler
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library 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
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
//============================================================================
/// \file FloatingWidgetTitleBar.h
/// \author Uwe Kindler
/// \date 13.05.2019
/// \brief Declaration of CFloatingWidgetTitleBar class
//============================================================================
//============================================================================
// INCLUDES
//============================================================================
#include <QWidget>
namespace ads
{
class CFloatingDockContainer;
struct FloatingWidgetTitleBarPrivate;
class CFloatingWidgetTitleBar : public QWidget
{
Q_OBJECT
private:
FloatingWidgetTitleBarPrivate* d; ///< private data (pimpl)
protected:
virtual void mousePressEvent(QMouseEvent* ev) override;
virtual void mouseReleaseEvent(QMouseEvent* ev) override;
virtual void mouseMoveEvent(QMouseEvent* ev) override;
public:
using Super = QWidget;
explicit CFloatingWidgetTitleBar (CFloatingDockContainer *parent = nullptr);
/**
* Virtual Destructor
*/
virtual ~CFloatingWidgetTitleBar();
void enableCloseButton(bool Enable);
void setTitle(const QString& Text);
signals:
void closeRequested();
};
} // namespace ads
#endif // FLOATINGWIDGETTITLEBAR_H

View File

@ -3,5 +3,6 @@
<file>stylesheets/default.css</file>
<file>images/close-button.svg</file>
<file>images/close-button-disabled.svg</file>
<file>stylesheets/default_linux.css</file>
</qresource>
</RCC>

View File

@ -40,7 +40,8 @@ HEADERS += \
DockOverlay.h \
DockSplitter.h \
DockAreaTitleBar.h \
ElidingLabel.h
ElidingLabel.h \
FloatingWidgetTitleBar.h
@ -56,7 +57,8 @@ SOURCES += \
DockOverlay.cpp \
DockSplitter.cpp \
DockAreaTitleBar.cpp \
ElidingLabel.cpp
ElidingLabel.cpp \
FloatingWidgetTitleBar.cpp
isEmpty(PREFIX){
PREFIX=..\installed
@ -66,3 +68,5 @@ headers.path=$$PREFIX/include
headers.files=$$HEADERS
target.path=$$PREFIX/lib
INSTALLS += headers target
DISTFILES +=