Commit 492c2d8f authored by Luca Carlon's avatar Luca Carlon
Browse files

Support resize for plasmaquick dialog.

parent e3cd0a29
Pipeline #152850 passed with stage
in 1 minute and 25 seconds
......@@ -71,6 +71,7 @@ public:
, hideOnWindowDeactivate(false)
, outputOnly(false)
, visible(false)
, resizable(false)
, componentComplete(dialog->parent() == nullptr)
, backgroundHints(Dialog::StandardBackground)
{
......@@ -134,6 +135,13 @@ public:
void applyType();
void updateMouseCursor(QMouseEvent *event);
Qt::Edges hitTest(const QPointF &pos);
bool hitTestLeft(const QPointF &pos);
bool hitTestRight(const QPointF &pos);
bool hitTestTop(const QPointF &pos);
bool hitTestBottom(const QPointF &pos);
Dialog *q;
Plasma::Types::Location location;
Plasma::FrameSvgItem *frameSvgItem;
......@@ -149,12 +157,17 @@ public:
bool hideOnWindowDeactivate;
bool outputOnly;
bool visible;
bool resizable;
Plasma::Theme theme;
bool componentComplete;
Dialog::BackgroundHints backgroundHints;
// Attached Layout property of mainItem, if any
QPointer<QObject> mainItemLayout;
// The size of the border (used to determine where the user
// is allowed to resize).
const int BORDER_SIZE = 10;
};
QRect DialogPrivate::availableScreenGeometryForPosition(const QPoint &pos) const
......@@ -825,6 +838,75 @@ void DialogPrivate::applyType()
#endif
}
void DialogPrivate::updateMouseCursor(QMouseEvent *event)
{
if (!event)
return;
QPointF globalMousePos = event->globalPos();
Qt::Edges sides = hitTest(globalMousePos);
if (sides == Qt::Edges(Qt::LeftEdge | Qt::TopEdge))
q->setCursor(Qt::SizeFDiagCursor);
else if (sides == Qt::Edges(Qt::RightEdge | Qt::TopEdge))
q->setCursor(Qt::SizeBDiagCursor);
else if (sides == Qt::Edges(Qt::LeftEdge | Qt::BottomEdge))
q->setCursor(Qt::SizeBDiagCursor);
else if (sides == Qt::Edges(Qt::RightEdge | Qt::BottomEdge))
q->setCursor(Qt::SizeFDiagCursor);
else if (sides.testFlag(Qt::TopEdge))
q->setCursor(Qt::SizeVerCursor);
else if (sides.testFlag(Qt::LeftEdge))
q->setCursor(Qt::SizeHorCursor);
else if (sides.testFlag(Qt::RightEdge))
q->setCursor(Qt::SizeHorCursor);
else if (sides.testFlag(Qt::BottomEdge))
q->setCursor(Qt::SizeVerCursor);
else
q->setCursor(Qt::ArrowCursor);
}
Qt::Edges DialogPrivate::hitTest(const QPointF &pos)
{
bool left = hitTestLeft(pos);
bool right = hitTestRight(pos);
bool top = hitTestTop(pos);
bool bottom = hitTestBottom(pos);
Qt::Edges edges;
if (left)
edges.setFlag(Qt::LeftEdge);
if (right)
edges.setFlag(Qt::RightEdge);
if (bottom)
edges.setFlag(Qt::BottomEdge);
if (top)
edges.setFlag(Qt::TopEdge);
return edges;
}
bool DialogPrivate::hitTestLeft(const QPointF &pos) {
const QRect geometry = q->geometry();
const QRectF rect(geometry.x(), geometry.y(), BORDER_SIZE, geometry.height());
return rect.contains(pos);
}
bool DialogPrivate::hitTestRight(const QPointF &pos) {
const QRect geometry = q->geometry();
const QRectF rect(geometry.x() + geometry.width() - BORDER_SIZE, geometry.y(), BORDER_SIZE, geometry.height());
return rect.contains(pos);
}
bool DialogPrivate::hitTestTop(const QPointF &pos) {
const QRect geometry = q->geometry();
const QRectF rect(geometry.x(), geometry.y(), geometry.width(), BORDER_SIZE);
return rect.contains(pos);
}
bool DialogPrivate::hitTestBottom(const QPointF &pos) {
const QRect geometry = q->geometry();
const QRectF rect(geometry.x(), geometry.y() + geometry.height() - BORDER_SIZE, geometry.width(), BORDER_SIZE);
return rect.contains(pos);
}
Dialog::Dialog(QQuickItem *parent)
: QQuickWindow(parent ? parent->window() : nullptr)
, d(new DialogPrivate(this))
......@@ -1233,6 +1315,20 @@ void Dialog::showEvent(QShowEvent *event)
QQuickWindow::showEvent(event);
}
void Dialog::mousePressEvent(QMouseEvent *event)
{
if (!d->resizable)
return QQuickWindow::mousePressEvent(event);
QPointF globalMousePos = event->globalPos();
Qt::Edges sides = d->hitTest(globalMousePos);
if (sides) {
startSystemResize(sides);
return;
}
return QQuickWindow::mousePressEvent(event);
}
bool Dialog::event(QEvent *event)
{
if (event->type() == QEvent::Expose) {
......@@ -1294,6 +1390,8 @@ bool Dialog::event(QEvent *event)
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease: {
QMouseEvent *me = static_cast<QMouseEvent *>(event);
if (d->resizable && event->type() == QEvent::MouseMove)
d->updateMouseCursor(me);
// don't mess with position if the cursor is actually outside the view:
// somebody is doing a click and drag that must not break when the cursor i outside
......@@ -1470,6 +1568,19 @@ bool Dialog::isVisible() const
return d->visible;
}
void Dialog::setResizable(bool resizable)
{
if (d->resizable == resizable)
return;
d->resizable = resizable;
Q_EMIT resizableChanged();
}
bool Dialog::isResizable() const
{
return d->resizable;
}
Dialog::BackgroundHints Dialog::backgroundHints() const
{
return d->backgroundHints;
......
......@@ -141,6 +141,12 @@ class PLASMAQUICK_EXPORT Dialog : public QQuickWindow, public QQmlParserStatus
Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChangedProxy)
/**
* This property allows to make the dialog resizable by the user.
* Default: false.
*/
Q_PROPERTY(bool resizable READ isResizable WRITE setResizable NOTIFY resizableChanged)
Q_CLASSINFO("DefaultProperty", "mainItem")
public:
......@@ -196,6 +202,9 @@ public:
bool isVisible() const;
void setVisible(bool visible);
bool isResizable() const;
void setResizable(bool resizable);
/**
* @returns The suggested screen position for the popup
* @param item the item the popup has to be positioned relatively to. if null, the popup will be positioned in the center of the window
......@@ -213,6 +222,7 @@ Q_SIGNALS:
void flagsChanged();
void backgroundHintsChanged();
void visibleChangedProxy(); // redeclaration of QQuickWindow::visibleChanged
void resizableChanged();
/**
* Emitted when the @see hideOnWindowDeactivate property is @c true and this dialog lost focus to a
* window that is neither a parent dialog to nor a child dialog of this dialog.
......@@ -224,6 +234,7 @@ protected:
* set the dialog position. subclasses may change it. ToolTipDialog adjusts the position in an animated way
*/
virtual void adjustGeometry(const QRect &geom);
virtual void mousePressEvent(QMouseEvent *event) override;
// Reimplementations
void classBegin() override;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment