qml: Show 4 proper indicators when dragging in a floating window

They don't do much yet, but at least appear.
This commit is contained in:
Sergio Martins
2020-08-11 01:29:36 +01:00
parent 5ccf15b9ed
commit 2c917dcd7c
11 changed files with 176 additions and 62 deletions

View File

@@ -20,10 +20,17 @@
using namespace KDDockWidgets;
static IndicatorWindow* createIndicatorWindow(ClassicIndicators *classicIndicators)
{
auto window = new IndicatorWindow(classicIndicators);
window->setObjectName(QStringLiteral("_docks_IndicatorWindow_Overlay"));
return window;
}
ClassicIndicators::ClassicIndicators(DropArea *dropArea)
: DropIndicatorOverlayInterface(dropArea) // Is parented on the drop-area, not a toplevel.
, m_rubberBand(Config::self().frameworkWidgetFactory()->createRubberBand(dropArea))
, m_indicatorWindow(new IndicatorWindow(this))
, m_indicatorWindow(createIndicatorWindow(this))
{
setVisible(false);
}
@@ -59,6 +66,7 @@ void ClassicIndicators::updateVisibility()
if (isHovered()) {
m_indicatorWindow->updatePositions();
m_indicatorWindow->setVisible(true);
updateWindowPosition();
m_indicatorWindow->updateIndicatorVisibility(true);
raiseIndicators();
} else {
@@ -145,3 +153,11 @@ void ClassicIndicators::setDropLocation(ClassicIndicators::DropLocation location
m_rubberBand->setGeometry(rect);
m_rubberBand->setVisible(true);
}
void ClassicIndicators::updateWindowPosition()
{
QRect rect = this->rect();
QPoint pos = mapToGlobal(QPoint(0, 0));
rect.moveTo(pos);
m_indicatorWindow->setGeometry(rect);
}

View File

@@ -15,42 +15,16 @@
using namespace KDDockWidgets;
#ifdef KDDOCKWIDGETS_QTWIDGETS
#include <QPainter>
#define INDICATOR_WIDTH 40
#define OUTTER_INDICATOR_MARGIN 10
void Indicator::paintEvent(QPaintEvent *)
namespace KDDockWidgets
{
QPainter p(this);
if (m_hovered)
p.drawImage(rect(), m_imageActive, rect());
else
p.drawImage(rect(), m_image, rect());
}
void Indicator::setHovered(bool hovered)
{
if (hovered != m_hovered) {
m_hovered = hovered;
update();
if (hovered) {
q->setDropLocation(m_dropLocation);
} else if (q->currentDropLocation() == m_dropLocation) {
q->setDropLocation(DropIndicatorOverlayInterface::DropLocation_None);
}
}
}
QString Indicator::iconName(bool active) const
static QString iconName(DropIndicatorOverlayInterface::DropLocation loc, bool active)
{
QString suffix = active ? QStringLiteral("_active")
: QString();
QString name;
switch (m_dropLocation) {
switch (loc) {
case DropIndicatorOverlayInterface::DropLocation_Center:
name = QStringLiteral("center");
break;
@@ -84,6 +58,41 @@ QString Indicator::iconName(bool active) const
return name + suffix;
}
}
#ifdef KDDOCKWIDGETS_QTWIDGETS
#include <QPainter>
#define INDICATOR_WIDTH 40
#define OUTTER_INDICATOR_MARGIN 10
void Indicator::paintEvent(QPaintEvent *)
{
QPainter p(this);
if (m_hovered)
p.drawImage(rect(), m_imageActive, rect());
else
p.drawImage(rect(), m_image, rect());
}
void Indicator::setHovered(bool hovered)
{
if (hovered != m_hovered) {
m_hovered = hovered;
update();
if (hovered) {
q->setDropLocation(m_dropLocation);
} else if (q->currentDropLocation() == m_dropLocation) {
q->setDropLocation(DropIndicatorOverlayInterface::DropLocation_None);
}
}
}
QString Indicator::iconName(bool active) const
{
return KDDockWidgets::iconName(m_dropLocation, active);
}
QString Indicator::iconFileName(bool active) const
{
@@ -107,21 +116,9 @@ IndicatorWindow::IndicatorWindow(ClassicIndicators *classicIndicators_)
{
setWindowFlag(Qt::FramelessWindowHint, true);
setAttribute(Qt::WA_TranslucentBackground);
updatePosition();
m_indicators << m_center << m_left << m_right << m_top << m_bottom
<< m_outterBottom << m_outterTop << m_outterLeft << m_outterRight;
setObjectName(QStringLiteral("_docks_IndicatorWindow_Overlay"));
}
bool IndicatorWindow::event(QEvent *e)
{
if (e->type() == QEvent::Show) {
updatePosition();
}
return QWidget::event(e);
}
Indicator *IndicatorWindow::indicatorForLocation(DropIndicatorOverlayInterface::DropLocation loc) const
@@ -203,14 +200,6 @@ void IndicatorWindow::hover(QPoint globalPos)
}
}
void IndicatorWindow::updatePosition()
{
QRect rect = classicIndicators->rect();
QPoint pos = classicIndicators->mapToGlobal(QPoint(0, 0));
rect.moveTo(pos);
setGeometry(rect);
}
void IndicatorWindow::updatePositions()
{
QRect r = rect();
@@ -245,12 +234,16 @@ Indicator::Indicator(ClassicIndicators *classicIndicators, IndicatorWindow *pare
#else
#include <QQmlContext>
IndicatorWindow::IndicatorWindow(KDDockWidgets::ClassicIndicators *classicIndicators)
: QQuickView()
, m_classicIndicators(classicIndicators)
{
setColor(Qt::transparent);
setFlags(flags() | Qt::FramelessWindowHint);
rootContext()->setContextProperty(QStringLiteral("_window"), QVariant::fromValue<QObject*>(this));
setSource(QUrl(QStringLiteral("qrc:/kddockwidgets/private/quick/qml/ClassicIndicatorsOverlay.qml")));
show();
}
void IndicatorWindow::hover(QPoint)
@@ -270,7 +263,19 @@ void IndicatorWindow::updateIndicatorVisibility(bool)
QPoint IndicatorWindow::posForIndicator(KDDockWidgets::DropIndicatorOverlayInterface::DropLocation) const
{
QQuickItem *root = rootObject();
const QList<QQuickItem*> items = root->childItems();
for (QQuickItem *item : items) {
qDebug() << Q_FUNC_INFO << item;
}
return {};
}
QString IndicatorWindow::iconName(int loc, bool active) const
{
return KDDockWidgets::iconName(DropIndicatorOverlayInterface::DropLocation(loc), active);
}
#endif // QtQuick

View File

@@ -35,9 +35,7 @@ public:
void updateIndicatorVisibility(bool visible);
QPoint posForIndicator(DropIndicatorOverlayInterface::DropLocation) const;
private:
void updatePosition();
void resizeEvent(QResizeEvent *ev) override;
bool event(QEvent *e) override;
// When the compositor doesn't support translucency, we use a mask instead
// Only happens on Linux
@@ -96,6 +94,7 @@ public:
void updatePositions();
void updateIndicatorVisibility(bool);
QPoint posForIndicator(DropIndicatorOverlayInterface::DropLocation) const;
Q_INVOKABLE QString iconName(int loc, bool active) const;
private:
ClassicIndicators *const m_classicIndicators;
};

View File

@@ -36,6 +36,7 @@ private:
friend class KDDockWidgets::IndicatorWindow;
void raiseIndicators();
void setDropLocation(DropLocation);
void updateWindowPosition();
QWidgetOrQuick *const m_rubberBand;
IndicatorWindow *const m_indicatorWindow;

View File

@@ -22,17 +22,36 @@
using namespace KDDockWidgets;
namespace KDDockWidgets {
class QuickView : public QQuickView
{
using QQuickView::QQuickView;
bool event(QEvent *ev) override
{
if (ev->type() == QEvent::FocusAboutToChange) {
// qquickwindow.cpp::event(FocusAboutToChange) removes the item grabber. Inibit that
return true;
}
return QQuickView::event(ev);
}
};
}
FloatingWindowQuick::FloatingWindowQuick(MainWindowBase *parent)
: FloatingWindow(parent)
, m_quickWindow(new QQuickView(Config::self().qmlEngine(), nullptr))
, m_quickWindow(new QuickView(Config::self().qmlEngine(), nullptr))
{
init();
}
FloatingWindowQuick::FloatingWindowQuick(Frame *frame, MainWindowBase *parent)
: FloatingWindow(frame, parent)
, m_quickWindow(new QQuickView(Config::self().qmlEngine(), nullptr))
, m_quickWindow(new QuickView(Config::self().qmlEngine(), nullptr))
{
init();
}

View File

@@ -224,6 +224,28 @@ QWidgetAdapter *QWidgetAdapter::parentWidget() const
return nullptr;
}
QPoint QWidgetAdapter::mapToGlobal(QPoint pt) const
{
return QQuickItem::mapToGlobal(pt).toPoint();
}
QPoint QWidgetAdapter::mapFromGlobal(QPoint pt) const
{
return QQuickItem::mapFromGlobal(pt).toPoint();
}
void QWidgetAdapter::setWindowTitle(const QString &title)
{
if (QWindow *window = windowHandle())
window->setTitle(title);
}
void QWidgetAdapter::setWindowIcon(const QIcon &icon)
{
if (QWindow *window = windowHandle())
window->setIcon(icon);
}
void QWidgetAdapter::close()
{
QCloseEvent ev;

View File

@@ -89,7 +89,6 @@ public:
QRect geometry() const;
QRect rect() const;
void show();
void setEnabled(bool) {}
void setFixedHeight(int);
void setFixedWidth(int);
void raise();
@@ -121,12 +120,12 @@ public:
QWindow *windowHandle() const;
QWidgetAdapter *window() const;
QWidgetAdapter *parentWidget() const;
QPoint mapToGlobal(QPoint) const { return {}; }
QPoint mapFromGlobal(QPoint) const { return {}; }
QPoint mapToGlobal(QPoint pt) const;
QPoint mapFromGlobal(QPoint) const;
bool testAttribute(Qt::WidgetAttribute) { return false; }
void setWindowTitle(const QString &) {}
void setWindowIcon(const QIcon &) {}
void setWindowTitle(const QString &);
void setWindowIcon(const QIcon &);
void close();
QQuickItem *childAt(QPoint) const;
void move(int x, int y);

View File

@@ -12,6 +12,7 @@
#include "QmlTypes.h"
#include "DropAreaWithCentralFrame_p.h"
#include "quick/MainWindowWrapper_p.h"
#include "DropIndicatorOverlayInterface_p.h"
#include "TitleBar_p.h"
#include <QQmlEngine>
@@ -24,5 +25,7 @@ void KDDockWidgets::registerQmlTypes()
qmlRegisterType<MainWindowWrapper>("com.kdab.dockwidgets", 1, 0, "MainWindow");
qmlRegisterUncreatableType<TitleBar>("com.kdab.dockwidgets", 1, 0, "TitleBar", QStringLiteral("Enum access only"));
qmlRegisterUncreatableType<DropIndicatorOverlayInterface>("com.kdab.dockwidgets", 1, 0, "DropIndicatorOverlayInterface", QStringLiteral("Enum access only"));
qRegisterMetaType<DropArea*>();
}

View File

@@ -0,0 +1,12 @@
import QtQuick 2.9
import com.kdab.dockwidgets 1.0
Image {
id: root
property int indicatorType: DropIndicatorOverlayInterface.DropLocation_None
source: "qrc:/img/classic_indicators/" + _window.iconName(indicatorType, true) + ".png";
width: 64
height: 64
}

View File

@@ -1,7 +1,44 @@
import QtQuick 2.9
import com.kdab.dockwidgets 1.0
Rectangle {
Item {
id: root
color: "blue"
anchors.fill: parent
readonly property int outterMargin: 10
ClassicIndicator {
indicatorType: DropIndicatorOverlayInterface.DropLocation_OutterLeft
anchors {
left: parent.left
leftMargin: outterMargin
verticalCenter: parent.verticalCenter
}
}
ClassicIndicator {
indicatorType: DropIndicatorOverlayInterface.DropLocation_OutterRight
anchors {
right: parent.right
rightMargin: outterMargin
verticalCenter: parent.verticalCenter
}
}
ClassicIndicator {
indicatorType: DropIndicatorOverlayInterface.DropLocation_OutterTop
anchors {
top: parent.top
topMargin: outterMargin
horizontalCenter: parent.horizontalCenter
}
}
ClassicIndicator {
indicatorType: DropIndicatorOverlayInterface.DropLocation_OutterBottom
anchors {
bottom: parent.bottom
bottomMargin: outterMargin
horizontalCenter: parent.horizontalCenter
}
}
}

View File

@@ -8,5 +8,6 @@
<file>private/quick/qml/TitleBarBase.qml</file>
<file>private/quick/qml/TitleBar.qml</file>
<file>private/quick/qml/ClassicIndicatorsOverlay.qml</file>
<file>private/quick/qml/ClassicIndicator.qml</file>
</qresource>
</RCC>