Merge "fix availableScreenGeometryForPosition()"
This commit is contained in:
commit
d28871cb65
@ -48,6 +48,8 @@ PLASMA_UNIT_TESTS(
|
|||||||
add_executable(storagetest storagetest.cpp ../src/plasma/private/storage.cpp ../src/plasma/private/storagethread.cpp)
|
add_executable(storagetest storagetest.cpp ../src/plasma/private/storage.cpp ../src/plasma/private/storagethread.cpp)
|
||||||
target_link_libraries(storagetest Qt5::Gui Qt5::Test Qt5::Sql KF5::KIOCore KF5::Plasma KF5::CoreAddons)
|
target_link_libraries(storagetest Qt5::Gui Qt5::Test Qt5::Sql KF5::KIOCore KF5::Plasma KF5::CoreAddons)
|
||||||
|
|
||||||
|
set(dialogtest_srcs dialogtest.cpp)
|
||||||
|
ecm_add_test(${dialogtest_srcs} TEST_NAME dialogtest LINK_LIBRARIES Qt5::Gui Qt5::Test Qt5::Qml Qt5::Quick KF5::WindowSystem KF5::Plasma KF5::PlasmaQuick)
|
||||||
|
|
||||||
set(coronatest_srcs coronatest.cpp)
|
set(coronatest_srcs coronatest.cpp)
|
||||||
qt5_add_resources(coronatest_srcs coronatestresources.qrc)
|
qt5_add_resources(coronatest_srcs coronatestresources.qrc)
|
||||||
|
57
autotests/dialogtest.cpp
Normal file
57
autotests/dialogtest.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/********************************************************************************
|
||||||
|
* Copyright 2014 Marco Martin <mart@kde.org> *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Library General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2 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 *
|
||||||
|
* Library General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public License *
|
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to *
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||||
|
* Boston, MA 02110-1301, USA. *
|
||||||
|
*********************************************************************************/
|
||||||
|
|
||||||
|
#include "dialogtest.h"
|
||||||
|
#include <KWindowSystem>
|
||||||
|
|
||||||
|
|
||||||
|
void DialogTest::initTestCase()
|
||||||
|
{
|
||||||
|
m_dialog = new PlasmaQuick::Dialog;
|
||||||
|
|
||||||
|
m_panel = new QQuickView;
|
||||||
|
m_panel->setGeometry(0, 0, 50, 50);
|
||||||
|
m_panel->setFlags(Qt::FramelessWindowHint|Qt::WindowDoesNotAcceptFocus);
|
||||||
|
|
||||||
|
m_content = new QQuickItem;
|
||||||
|
m_content->setWidth(100);
|
||||||
|
m_content->setHeight(100);
|
||||||
|
m_dialog->setMainItem(m_content);
|
||||||
|
|
||||||
|
m_panel->show();
|
||||||
|
KWindowSystem::setType(m_panel->winId(), NET::Dock);
|
||||||
|
m_dialog->setVisualParent(m_panel->contentItem());
|
||||||
|
m_dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogTest::cleanupTestCase()
|
||||||
|
{
|
||||||
|
delete m_dialog;
|
||||||
|
delete m_panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogTest::position()
|
||||||
|
{
|
||||||
|
QTest::qWaitForWindowExposed(m_dialog);
|
||||||
|
|
||||||
|
QCOMPARE(m_dialog->x(), 0);
|
||||||
|
QCOMPARE(m_dialog->y(), 49);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(DialogTest)
|
48
autotests/dialogtest.h
Normal file
48
autotests/dialogtest.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Copyright 2014 Marco Martin <mart@kde.org> *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Library General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2 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 *
|
||||||
|
* Library General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public License *
|
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to *
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||||
|
* Boston, MA 02110-1301, USA. *
|
||||||
|
*******************************************************************************/
|
||||||
|
#ifndef DIALOGTEST_H
|
||||||
|
#define DIALOGTEST_H
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include <QQuickView>
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
#include "plasmaquick/dialog.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DialogTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void initTestCase();
|
||||||
|
void cleanupTestCase();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void position();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QQuickView *m_panel;
|
||||||
|
QQuickItem *m_content;
|
||||||
|
PlasmaQuick::Dialog *m_dialog;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -2,6 +2,7 @@
|
|||||||
* Copyright 2011 Marco Martin <mart@kde.org> *
|
* Copyright 2011 Marco Martin <mart@kde.org> *
|
||||||
* Copyright 2013 Sebastian Kügler <sebas@kde.org> *
|
* Copyright 2013 Sebastian Kügler <sebas@kde.org> *
|
||||||
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> *
|
* Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> *
|
||||||
|
* Copyright 2014 Vishesh Handa <vhanda@kde.org> *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
@ -29,6 +30,7 @@
|
|||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
#include <kwindowsystem.h>
|
#include <kwindowsystem.h>
|
||||||
#include <KWindowSystem/KWindowInfo>
|
#include <KWindowSystem/KWindowInfo>
|
||||||
@ -61,21 +63,27 @@ public:
|
|||||||
hideOnWindowDeactivate(false),
|
hideOnWindowDeactivate(false),
|
||||||
outputOnly(false),
|
outputOnly(false),
|
||||||
componentComplete(dialog->parent() == 0),
|
componentComplete(dialog->parent() == 0),
|
||||||
resizeOrigin(Undefined),
|
|
||||||
backgroundHints(Dialog::StandardBackground)
|
backgroundHints(Dialog::StandardBackground)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ResizeOrigin {
|
|
||||||
Undefined,
|
|
||||||
MainItem,
|
|
||||||
Window
|
|
||||||
};
|
|
||||||
|
|
||||||
void updateInputShape();
|
void updateInputShape();
|
||||||
|
|
||||||
//SLOTS
|
//SLOTS
|
||||||
void syncBorders();
|
/**
|
||||||
|
* Sync Borders updates the enabled borders of the frameSvgItem depending
|
||||||
|
* on the geometry of the window.
|
||||||
|
*
|
||||||
|
* \param windowGeometry The window geometry which should be taken into
|
||||||
|
* consideration when activating/deactivating certain borders
|
||||||
|
*/
|
||||||
|
void syncBorders(const QRect& windowGeometry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function sets the blurBehind, background contrast and shadows. It
|
||||||
|
* does so wrt the frameSvgItem. So make sure the frameSvgItem is the
|
||||||
|
* correct size before calling this function.
|
||||||
|
*/
|
||||||
void updateTheme();
|
void updateTheme();
|
||||||
void updateVisibility(bool visible);
|
void updateVisibility(bool visible);
|
||||||
|
|
||||||
@ -84,16 +92,32 @@ public:
|
|||||||
void updateMaximumWidth();
|
void updateMaximumWidth();
|
||||||
void updateMaximumHeight();
|
void updateMaximumHeight();
|
||||||
|
|
||||||
void syncMainItemToSize();
|
/**
|
||||||
|
* This function is an optimized version of updateMaximumHeight,
|
||||||
|
* updateMaximumWidth,updateMinimumWidth and updateMinimumHeight.
|
||||||
|
* It should be called when you need to call all 4 of these functions
|
||||||
|
* AND you have called syncToMainItemSize before.
|
||||||
|
*/
|
||||||
|
void updateLayoutParameters();
|
||||||
|
|
||||||
|
QRect availableScreenGeometryForPosition(const QPoint& pos) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function checks the current position of the dialog and repositions
|
||||||
|
* it so that no part of it is not on the screen
|
||||||
|
*/
|
||||||
|
void repositionIfOffScreen();
|
||||||
|
|
||||||
|
void slotMainItemSizeChanged();
|
||||||
|
void slotWindowPositionChanged();
|
||||||
|
|
||||||
void syncToMainItemSize();
|
void syncToMainItemSize();
|
||||||
void requestSizeSync(bool delayed = false);
|
|
||||||
|
|
||||||
Dialog *q;
|
Dialog *q;
|
||||||
QTimer *syncTimer;
|
|
||||||
Plasma::Types::Location location;
|
Plasma::Types::Location location;
|
||||||
Plasma::FrameSvgItem *frameSvgItem;
|
Plasma::FrameSvgItem *frameSvgItem;
|
||||||
QWeakPointer<QQuickItem> mainItem;
|
QPointer<QQuickItem> mainItem;
|
||||||
QWeakPointer<QQuickItem> visualParent;
|
QPointer<QQuickItem> visualParent;
|
||||||
|
|
||||||
QRect cachedGeometry;
|
QRect cachedGeometry;
|
||||||
Dialog::WindowType type;
|
Dialog::WindowType type;
|
||||||
@ -101,14 +125,13 @@ public:
|
|||||||
bool outputOnly;
|
bool outputOnly;
|
||||||
Plasma::Theme theme;
|
Plasma::Theme theme;
|
||||||
bool componentComplete;
|
bool componentComplete;
|
||||||
ResizeOrigin resizeOrigin;
|
|
||||||
Dialog::BackgroundHints backgroundHints;
|
Dialog::BackgroundHints backgroundHints;
|
||||||
|
|
||||||
//Attached Layout property of mainItem, if any
|
//Attached Layout property of mainItem, if any
|
||||||
QWeakPointer <QObject> mainItemLayout;
|
QPointer <QObject> mainItemLayout;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DialogPrivate::syncBorders()
|
QRect DialogPrivate::availableScreenGeometryForPosition(const QPoint& pos) const
|
||||||
{
|
{
|
||||||
// FIXME: QWindow::screen() never ever changes if the window is moved across
|
// FIXME: QWindow::screen() never ever changes if the window is moved across
|
||||||
// virtual screens (normal two screens with X), this seems to be intentional
|
// virtual screens (normal two screens with X), this seems to be intentional
|
||||||
@ -117,42 +140,43 @@ void DialogPrivate::syncBorders()
|
|||||||
// we simply iterate over the virtual screens and pick the one our QWindow
|
// we simply iterate over the virtual screens and pick the one our QWindow
|
||||||
// says it's at.
|
// says it's at.
|
||||||
QRect avail;
|
QRect avail;
|
||||||
QPoint pos = q->position();
|
|
||||||
Q_FOREACH (QScreen *screen, q->screen()->virtualSiblings()) {
|
Q_FOREACH (QScreen *screen, q->screen()->virtualSiblings()) {
|
||||||
if (screen->availableGeometry().contains(pos)) {
|
//we check geometry() but then take availableGeometry()
|
||||||
|
//to reliably check in which screen a position is, we need the full
|
||||||
|
//geometry, including areas for panels
|
||||||
|
if (screen->geometry().contains(pos)) {
|
||||||
avail = screen->availableGeometry();
|
avail = screen->availableGeometry();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return avail;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogPrivate::syncBorders(const QRect& geom)
|
||||||
|
{
|
||||||
|
QRect avail = availableScreenGeometryForPosition(geom.topLeft());
|
||||||
int borders = Plasma::FrameSvg::AllBorders;
|
int borders = Plasma::FrameSvg::AllBorders;
|
||||||
|
|
||||||
//Tooltips always have all the borders
|
//Tooltips always have all the borders
|
||||||
// floating windows have all borders
|
// floating windows have all borders
|
||||||
if ((q->flags() & Qt::ToolTip) != Qt::ToolTip && location != Plasma::Types::Floating) {
|
if ((q->flags() & Qt::ToolTip) != Qt::ToolTip && location != Plasma::Types::Floating) {
|
||||||
if (q->x() <= avail.x() || location == Plasma::Types::LeftEdge) {
|
if (geom.x() <= avail.x() || location == Plasma::Types::LeftEdge) {
|
||||||
borders = borders & ~Plasma::FrameSvg::LeftBorder;
|
borders = borders & ~Plasma::FrameSvg::LeftBorder;
|
||||||
}
|
}
|
||||||
if (q->y() <= avail.y() || location == Plasma::Types::TopEdge) {
|
if (geom.y() <= avail.y() || location == Plasma::Types::TopEdge) {
|
||||||
borders = borders & ~Plasma::FrameSvg::TopBorder;
|
borders = borders & ~Plasma::FrameSvg::TopBorder;
|
||||||
}
|
}
|
||||||
if (avail.right() <= q->x() + q->width() || location == Plasma::Types::RightEdge) {
|
if (avail.right() <= geom.x() + geom.width() || location == Plasma::Types::RightEdge) {
|
||||||
borders = borders & ~Plasma::FrameSvg::RightBorder;
|
borders = borders & ~Plasma::FrameSvg::RightBorder;
|
||||||
}
|
}
|
||||||
if (avail.bottom() <= q->y() + q->height() || location == Plasma::Types::BottomEdge) {
|
if (avail.bottom() <= geom.y() + geom.height() || location == Plasma::Types::BottomEdge) {
|
||||||
borders = borders & ~Plasma::FrameSvg::BottomBorder;
|
borders = borders & ~Plasma::FrameSvg::BottomBorder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameSvgItem->enabledBorders() != (Plasma::FrameSvg::EnabledBorder)borders) {
|
if (frameSvgItem->enabledBorders() != (Plasma::FrameSvg::EnabledBorder)borders) {
|
||||||
frameSvgItem->setEnabledBorders((Plasma::FrameSvg::EnabledBorder)borders);
|
frameSvgItem->setEnabledBorders((Plasma::FrameSvg::EnabledBorder)borders);
|
||||||
|
|
||||||
if (mainItemLayout) {
|
|
||||||
updateMinimumWidth();
|
|
||||||
updateMinimumHeight();
|
|
||||||
updateMaximumWidth();
|
|
||||||
updateMaximumHeight();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,8 +218,8 @@ void DialogPrivate::updateTheme()
|
|||||||
void DialogPrivate::updateVisibility(bool visible)
|
void DialogPrivate::updateVisibility(bool visible)
|
||||||
{
|
{
|
||||||
if (visible) {
|
if (visible) {
|
||||||
if (visualParent && visualParent.data()->window()) {
|
if (visualParent && visualParent->window()) {
|
||||||
q->setTransientParent(visualParent.data()->window());
|
q->setTransientParent(visualParent->window());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->location() == Plasma::Types::FullScreen) {
|
if (q->location() == Plasma::Types::FullScreen) {
|
||||||
@ -210,11 +234,19 @@ void DialogPrivate::updateVisibility(bool visible)
|
|||||||
} else {
|
} else {
|
||||||
if (!cachedGeometry.isNull()) {
|
if (!cachedGeometry.isNull()) {
|
||||||
q->resize(cachedGeometry.size());
|
q->resize(cachedGeometry.size());
|
||||||
syncMainItemToSize();
|
slotWindowPositionChanged();
|
||||||
|
if (visualParent) {
|
||||||
|
q->setPosition(q->popupPosition(visualParent, q->size()));
|
||||||
|
}
|
||||||
cachedGeometry = QRect();
|
cachedGeometry = QRect();
|
||||||
}
|
}
|
||||||
|
if (mainItem) {
|
||||||
syncToMainItemSize();
|
syncToMainItemSize();
|
||||||
}
|
}
|
||||||
|
if (mainItemLayout) {
|
||||||
|
updateLayoutParameters();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(q->flags() & Qt::ToolTip)) {
|
if (!(q->flags() & Qt::ToolTip)) {
|
||||||
@ -259,68 +291,211 @@ void DialogPrivate::updateVisibility(bool visible)
|
|||||||
|
|
||||||
void DialogPrivate::updateMinimumWidth()
|
void DialogPrivate::updateMinimumWidth()
|
||||||
{
|
{
|
||||||
if (mainItemLayout) {
|
Q_ASSERT(mainItem);
|
||||||
|
Q_ASSERT(mainItemLayout);
|
||||||
|
|
||||||
|
mainItem->disconnect(q);
|
||||||
|
|
||||||
|
syncBorders(q->geometry());
|
||||||
|
|
||||||
|
int minimumWidth = mainItemLayout->property("minimumWidth").toInt();
|
||||||
|
auto margin = frameSvgItem->margins();
|
||||||
|
|
||||||
int oldWidth = q->width();
|
int oldWidth = q->width();
|
||||||
q->setMinimumWidth(mainItemLayout.data()->property("minimumWidth").toInt() + frameSvgItem->margins()->left() + frameSvgItem->margins()->right());
|
|
||||||
//Sometimes setMinimumWidth doesn't actually resize: Qt bug?
|
q->setMinimumWidth(minimumWidth + margin->left() + margin->right());
|
||||||
resizeOrigin = DialogPrivate::Window;
|
|
||||||
q->setWidth(qMax(q->width(), q->minimumWidth()));
|
q->setWidth(qMax(q->width(), q->minimumWidth()));
|
||||||
|
|
||||||
|
mainItem->setWidth(q->width() - margin->left() - margin->right());
|
||||||
|
frameSvgItem->setWidth(q->width());
|
||||||
|
|
||||||
if (location == Plasma::Types::RightEdge) {
|
if (location == Plasma::Types::RightEdge) {
|
||||||
q->setX(q->x() + (oldWidth - q->size().width()));
|
q->setX(q->x() + (oldWidth - q->size().width()));
|
||||||
}
|
}
|
||||||
} else {
|
repositionIfOffScreen();
|
||||||
q->setMinimumWidth(-1);
|
if (visualParent) {
|
||||||
|
const QRect geom(q->popupPosition(visualParent, q->size()), q->size());
|
||||||
|
q->setGeometry(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateTheme();
|
||||||
|
|
||||||
|
QObject::connect(mainItem, SIGNAL(widthChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
|
QObject::connect(mainItem, SIGNAL(heightChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogPrivate::updateMinimumHeight()
|
void DialogPrivate::updateMinimumHeight()
|
||||||
{
|
{
|
||||||
if (mainItemLayout) {
|
if (!componentComplete) {
|
||||||
int oldHeight = q->height();
|
return;
|
||||||
q->setMinimumHeight(mainItemLayout.data()->property("minimumHeight").toInt() + frameSvgItem->margins()->top() + frameSvgItem->margins()->bottom());
|
}
|
||||||
//Sometimes setMinimumHeight doesn't actually resize: Qt bug?
|
Q_ASSERT(mainItem);
|
||||||
resizeOrigin = DialogPrivate::Window;
|
Q_ASSERT(mainItemLayout);
|
||||||
|
|
||||||
|
mainItem->disconnect(q);
|
||||||
|
|
||||||
|
syncBorders(q->geometry());
|
||||||
|
|
||||||
|
int minimumHeight = mainItemLayout->property("minimumHeight").toInt();
|
||||||
|
auto margin = frameSvgItem->margins();
|
||||||
|
|
||||||
|
int oldHeight = mainItem->height();
|
||||||
|
|
||||||
|
q->setMinimumHeight(minimumHeight + margin->top() + margin->bottom());
|
||||||
q->setHeight(qMax(q->height(), q->minimumHeight()));
|
q->setHeight(qMax(q->height(), q->minimumHeight()));
|
||||||
|
|
||||||
|
mainItem->setHeight(q->height() - margin->top() - margin->bottom());
|
||||||
|
frameSvgItem->setHeight(q->height());
|
||||||
|
|
||||||
if (location == Plasma::Types::BottomEdge) {
|
if (location == Plasma::Types::BottomEdge) {
|
||||||
q->setY(q->y() + (oldHeight - q->size().height()));
|
q->setY(q->y() + (oldHeight - q->size().height()));
|
||||||
}
|
}
|
||||||
} else {
|
repositionIfOffScreen();
|
||||||
q->setMinimumHeight(-1);
|
if (visualParent) {
|
||||||
|
const QRect geom(q->popupPosition(visualParent, q->size()), q->size());
|
||||||
|
q->setGeometry(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateTheme();
|
||||||
|
|
||||||
|
QObject::connect(mainItem, SIGNAL(widthChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
|
QObject::connect(mainItem, SIGNAL(heightChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogPrivate::updateMaximumWidth()
|
void DialogPrivate::updateMaximumWidth()
|
||||||
{
|
{
|
||||||
if (mainItemLayout) {
|
if (!componentComplete) {
|
||||||
const int hint = mainItemLayout.data()->property("maximumWidth").toInt();
|
return;
|
||||||
resizeOrigin = DialogPrivate::Window;
|
|
||||||
if (hint > 0) {
|
|
||||||
q->setMaximumWidth(hint + frameSvgItem->margins()->left() + frameSvgItem->margins()->right());
|
|
||||||
q->setWidth(qMin(q->width(), q->maximumWidth()));
|
|
||||||
} else {
|
|
||||||
q->setMaximumWidth(DIALOGSIZE_MAX);
|
|
||||||
}
|
}
|
||||||
} else {
|
Q_ASSERT(mainItem);
|
||||||
q->setMaximumWidth(DIALOGSIZE_MAX);
|
Q_ASSERT(mainItemLayout);
|
||||||
|
|
||||||
|
mainItem->disconnect(q);
|
||||||
|
|
||||||
|
syncBorders(q->geometry());
|
||||||
|
|
||||||
|
int maximumWidth = mainItemLayout->property("maximumWidth").toInt();
|
||||||
|
maximumWidth = maximumWidth ? maximumWidth : DIALOGSIZE_MAX;
|
||||||
|
auto margin = frameSvgItem->margins();
|
||||||
|
|
||||||
|
q->setMaximumWidth(maximumWidth + margin->left() + margin->right());
|
||||||
|
q->setWidth(qBound(q->minimumWidth(), q->width(), q->maximumWidth()));
|
||||||
|
mainItem->setWidth(q->width() - margin->left() - margin->right());
|
||||||
|
frameSvgItem->setWidth(q->width());
|
||||||
|
|
||||||
|
repositionIfOffScreen();
|
||||||
|
if (visualParent) {
|
||||||
|
const QRect geom(q->popupPosition(visualParent, q->size()), q->size());
|
||||||
|
q->setGeometry(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateTheme();
|
||||||
|
|
||||||
|
QObject::connect(mainItem, SIGNAL(widthChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
|
QObject::connect(mainItem, SIGNAL(heightChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogPrivate::updateMaximumHeight()
|
void DialogPrivate::updateMaximumHeight()
|
||||||
{
|
{
|
||||||
if (mainItemLayout) {
|
if (!componentComplete) {
|
||||||
const int hint = mainItemLayout.data()->property("maximumHeight").toInt();
|
return;
|
||||||
resizeOrigin = DialogPrivate::Window;
|
|
||||||
if (hint > 0) {
|
|
||||||
q->setMaximumHeight(hint + frameSvgItem->margins()->top() + frameSvgItem->margins()->bottom());
|
|
||||||
q->setHeight(qMin(q->height(), q->maximumHeight()));
|
|
||||||
} else {
|
|
||||||
q->setMaximumHeight(DIALOGSIZE_MAX);
|
|
||||||
}
|
}
|
||||||
} else {
|
Q_ASSERT(mainItem);
|
||||||
q->setMaximumHeight(DIALOGSIZE_MAX);
|
Q_ASSERT(mainItemLayout);
|
||||||
|
|
||||||
|
mainItem->disconnect(q);
|
||||||
|
|
||||||
|
syncBorders(q->geometry());
|
||||||
|
|
||||||
|
int maximumHeight = mainItemLayout->property("maximumHeight").toInt();
|
||||||
|
maximumHeight = maximumHeight ? maximumHeight : DIALOGSIZE_MAX;
|
||||||
|
auto margin = frameSvgItem->margins();
|
||||||
|
|
||||||
|
q->setMaximumHeight(maximumHeight + margin->top() + margin->bottom());
|
||||||
|
q->setHeight(qBound(q->minimumHeight(), q->height(), q->maximumHeight()));
|
||||||
|
|
||||||
|
mainItem->setHeight(q->height() - margin->top() - margin->bottom());
|
||||||
|
frameSvgItem->setHeight(q->height());
|
||||||
|
|
||||||
|
repositionIfOffScreen();
|
||||||
|
if (visualParent) {
|
||||||
|
const QRect geom(q->popupPosition(visualParent, q->size()), q->size());
|
||||||
|
q->setGeometry(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateTheme();
|
||||||
|
|
||||||
|
QObject::connect(mainItem, SIGNAL(widthChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
|
QObject::connect(mainItem, SIGNAL(heightChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogPrivate::updateLayoutParameters()
|
||||||
|
{
|
||||||
|
if (!componentComplete || !mainItem || !q->isVisible()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_ASSERT(mainItem);
|
||||||
|
Q_ASSERT(mainItemLayout);
|
||||||
|
|
||||||
|
mainItem->disconnect(q);
|
||||||
|
|
||||||
|
int minimumHeight = mainItemLayout->property("minimumHeight").toInt();
|
||||||
|
int maximumHeight = mainItemLayout->property("maximumHeight").toInt();
|
||||||
|
maximumHeight = maximumHeight ? maximumHeight : DIALOGSIZE_MAX;
|
||||||
|
|
||||||
|
int minimumWidth = mainItemLayout->property("minimumWidth").toInt();
|
||||||
|
int maximumWidth = mainItemLayout->property("maximumWidth").toInt();
|
||||||
|
maximumWidth = maximumWidth ? maximumWidth : DIALOGSIZE_MAX;
|
||||||
|
|
||||||
|
auto margin = frameSvgItem->margins();
|
||||||
|
|
||||||
|
q->setMinimumHeight(minimumHeight + margin->top() + margin->bottom());
|
||||||
|
q->setMaximumHeight(maximumHeight + margin->top() + margin->bottom());
|
||||||
|
q->setHeight(qBound(q->minimumHeight(), q->height(), q->maximumHeight()));
|
||||||
|
|
||||||
|
q->setMinimumWidth(minimumWidth + margin->left() + margin->right());
|
||||||
|
q->setMaximumWidth(maximumWidth + margin->left() + margin->right());
|
||||||
|
q->setWidth(qBound(q->minimumWidth(), q->width(), q->maximumWidth()));
|
||||||
|
|
||||||
|
mainItem->setX(margin->left());
|
||||||
|
mainItem->setY(margin->top());
|
||||||
|
mainItem->setWidth(q->width() - margin->left() - margin->right());
|
||||||
|
mainItem->setHeight(q->height() - margin->top() - margin->bottom());
|
||||||
|
|
||||||
|
frameSvgItem->setWidth(q->width());
|
||||||
|
frameSvgItem->setHeight(q->height());
|
||||||
|
|
||||||
|
repositionIfOffScreen();
|
||||||
|
updateTheme();
|
||||||
|
|
||||||
|
QObject::connect(mainItem, SIGNAL(widthChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
|
QObject::connect(mainItem, SIGNAL(heightChanged()), q, SLOT(slotMainItemSizeChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogPrivate::repositionIfOffScreen()
|
||||||
|
{
|
||||||
|
if (!componentComplete) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QRect avail = availableScreenGeometryForPosition(q->position());
|
||||||
|
|
||||||
|
int x = q->x();
|
||||||
|
int y = q->y();
|
||||||
|
|
||||||
|
if (x < avail.left()) {
|
||||||
|
x = avail.left();
|
||||||
|
} else if (x + q->width() > avail.right()) {
|
||||||
|
x = avail.right() - q->width() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < avail.top()) {
|
||||||
|
y = avail.top();
|
||||||
|
} else if (y + q->height() > avail.bottom()) {
|
||||||
|
y = avail.bottom() - q->height() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
q->setX(x);
|
||||||
|
q->setY(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogPrivate::updateInputShape()
|
void DialogPrivate::updateInputShape()
|
||||||
@ -367,34 +542,38 @@ void DialogPrivate::updateInputShape()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogPrivate::syncMainItemToSize()
|
|
||||||
{
|
|
||||||
syncBorders();
|
|
||||||
|
|
||||||
updateTheme();
|
|
||||||
|
|
||||||
if (mainItem) {
|
|
||||||
mainItem.data()->setX(frameSvgItem->margins()->left());
|
|
||||||
mainItem.data()->setY(frameSvgItem->margins()->top());
|
|
||||||
mainItem.data()->setWidth(q->width() - frameSvgItem->margins()->left() - frameSvgItem->margins()->right());
|
|
||||||
mainItem.data()->setHeight(q->height() - frameSvgItem->margins()->top() - frameSvgItem->margins()->bottom());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (q->visualParent()) {
|
|
||||||
q->setPosition(q->popupPosition(q->visualParent(), q->size()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogPrivate::syncToMainItemSize()
|
void DialogPrivate::syncToMainItemSize()
|
||||||
{
|
{
|
||||||
//if manually sync a sync timer was running cancel it so we don't get called twice
|
Q_ASSERT(mainItem);
|
||||||
syncTimer->stop();
|
|
||||||
|
|
||||||
if (!mainItem) {
|
if (!componentComplete || !q->isVisible()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QSize s = QSize(mainItem.data()->width(), mainItem.data()->height()) +
|
if (visualParent) {
|
||||||
|
// Get the full size with ALL the borders
|
||||||
|
frameSvgItem->setEnabledBorders(Plasma::FrameSvg::AllBorders);
|
||||||
|
auto margins = frameSvgItem->margins();
|
||||||
|
|
||||||
|
const QSize fullSize = QSize(mainItem->width(), mainItem->height()) +
|
||||||
|
QSize(margins->left() + margins->right(),
|
||||||
|
margins->top() + margins->bottom());
|
||||||
|
|
||||||
|
// We get the popup position with the fullsize as we need the popup
|
||||||
|
// position in order to determine our actual size, as the position
|
||||||
|
// determines which borders will be shown.
|
||||||
|
const QRect geom(q->popupPosition(visualParent, fullSize), fullSize);
|
||||||
|
|
||||||
|
// We're then moving the window to where we think we would be with all
|
||||||
|
// the borders. This way when syncBorders is called, it has a geometry
|
||||||
|
// to work with.
|
||||||
|
syncBorders(geom);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
syncBorders(q->geometry());
|
||||||
|
}
|
||||||
|
|
||||||
|
const QSize s = QSize(mainItem->width(), mainItem->height()) +
|
||||||
QSize(frameSvgItem->margins()->left() + frameSvgItem->margins()->right(),
|
QSize(frameSvgItem->margins()->left() + frameSvgItem->margins()->right(),
|
||||||
frameSvgItem->margins()->top() + frameSvgItem->margins()->bottom());
|
frameSvgItem->margins()->top() + frameSvgItem->margins()->bottom());
|
||||||
|
|
||||||
@ -403,34 +582,43 @@ void DialogPrivate::syncToMainItemSize()
|
|||||||
frameSvgItem->setWidth(s.width());
|
frameSvgItem->setWidth(s.width());
|
||||||
frameSvgItem->setHeight(s.height());
|
frameSvgItem->setHeight(s.height());
|
||||||
|
|
||||||
if (q->visualParent()) {
|
if (visualParent) {
|
||||||
const QRect geom(q->popupPosition(q->visualParent(), s), s);
|
const QRect geom(q->popupPosition(visualParent, s), s);
|
||||||
|
|
||||||
if (geom == q->geometry()) {
|
if (geom == q->geometry()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
q->adjustGeometry(geom);
|
q->adjustGeometry(geom);
|
||||||
|
// The borders will instantly be updated but the geometry might take a
|
||||||
|
// while as sub-classes can reimplement adjustGeometry and animate it.
|
||||||
|
syncBorders(geom);
|
||||||
} else {
|
} else {
|
||||||
q->resize(s);
|
q->resize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
syncBorders();
|
mainItem->setX(frameSvgItem->margins()->left());
|
||||||
mainItem.data()->setX(frameSvgItem->margins()->left());
|
mainItem->setY(frameSvgItem->margins()->top());
|
||||||
mainItem.data()->setY(frameSvgItem->margins()->top());
|
|
||||||
|
|
||||||
updateTheme();
|
updateTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogPrivate::requestSizeSync(bool delayed)
|
void DialogPrivate::slotWindowPositionChanged()
|
||||||
{
|
{
|
||||||
if (!componentComplete) {
|
// Tooltips always have all the borders
|
||||||
|
// floating windows have all borders
|
||||||
|
if ((q->flags() & Qt::ToolTip) || location == Plasma::Types::Floating) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delayed && !syncTimer->isActive()) {
|
syncBorders(q->geometry());
|
||||||
syncTimer->start(150);
|
updateTheme();
|
||||||
} else {
|
|
||||||
syncTimer->start(0);
|
if (mainItem) {
|
||||||
|
auto margin = frameSvgItem->margins();
|
||||||
|
mainItem->setX(margin->left());
|
||||||
|
mainItem->setY(margin->top());
|
||||||
|
mainItem->setWidth(q->width() - margin->left() - margin->right());
|
||||||
|
mainItem->setHeight(q->height() - margin->top() - margin->bottom());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,35 +632,9 @@ Dialog::Dialog(QQuickItem *parent)
|
|||||||
|
|
||||||
setIcon(QIcon::fromTheme("plasma"));
|
setIcon(QIcon::fromTheme("plasma"));
|
||||||
|
|
||||||
d->syncTimer = new QTimer(this);
|
connect(this, &QWindow::xChanged, [=]() { d->slotWindowPositionChanged(); });
|
||||||
d->syncTimer->setSingleShot(true);
|
connect(this, &QWindow::yChanged, [=]() { d->slotWindowPositionChanged(); });
|
||||||
d->syncTimer->setInterval(0);
|
|
||||||
connect(d->syncTimer, &QTimer::timeout,
|
|
||||||
[ = ]() {
|
|
||||||
if (d->resizeOrigin == DialogPrivate::MainItem) {
|
|
||||||
d->syncToMainItemSize();
|
|
||||||
} else {
|
|
||||||
d->syncMainItemToSize();
|
|
||||||
}
|
|
||||||
d->resizeOrigin = DialogPrivate::Undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(this, &QWindow::xChanged, [ = ]() {
|
|
||||||
//Tooltips always have all the borders
|
|
||||||
// floating windows have all borders
|
|
||||||
if (!(flags() & Qt::ToolTip) && d->location != Plasma::Types::Floating) {
|
|
||||||
d->resizeOrigin = DialogPrivate::Window;
|
|
||||||
d->requestSizeSync(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(this, &QWindow::yChanged, [ = ]() {
|
|
||||||
//Tooltips always have all the borders
|
|
||||||
// floating windows have all borders
|
|
||||||
if (!(flags() & Qt::ToolTip) && d->location != Plasma::Types::Floating) {
|
|
||||||
d->resizeOrigin = DialogPrivate::Window;
|
|
||||||
d->requestSizeSync(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(this, SIGNAL(visibleChanged(bool)),
|
connect(this, SIGNAL(visibleChanged(bool)),
|
||||||
this, SLOT(updateInputShape()));
|
this, SLOT(updateInputShape()));
|
||||||
connect(this, SIGNAL(outputOnlyChanged()),
|
connect(this, SIGNAL(outputOnlyChanged()),
|
||||||
@ -497,14 +659,14 @@ Dialog::~Dialog()
|
|||||||
|
|
||||||
QQuickItem *Dialog::mainItem() const
|
QQuickItem *Dialog::mainItem() const
|
||||||
{
|
{
|
||||||
return d->mainItem.data();
|
return d->mainItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dialog::setMainItem(QQuickItem *mainItem)
|
void Dialog::setMainItem(QQuickItem *mainItem)
|
||||||
{
|
{
|
||||||
if (d->mainItem.data() != mainItem) {
|
if (d->mainItem != mainItem) {
|
||||||
if (d->mainItem) {
|
if (d->mainItem) {
|
||||||
d->mainItem.data()->setParent(parent());
|
d->mainItem->setParent(parent());
|
||||||
}
|
}
|
||||||
|
|
||||||
d->mainItem = mainItem;
|
d->mainItem = mainItem;
|
||||||
@ -513,20 +675,9 @@ void Dialog::setMainItem(QQuickItem *mainItem)
|
|||||||
mainItem->setParent(contentItem());
|
mainItem->setParent(contentItem());
|
||||||
mainItem->setProperty("parent", QVariant::fromValue(contentItem()));
|
mainItem->setProperty("parent", QVariant::fromValue(contentItem()));
|
||||||
|
|
||||||
if (mainItem->metaObject()->indexOfSignal("widthChanged")) {
|
connect(mainItem, SIGNAL(widthChanged()), this, SLOT(slotMainItemSizeChanged()));
|
||||||
connect(mainItem, &QQuickItem::widthChanged, [ = ]() {
|
connect(mainItem, SIGNAL(heightChanged()), this, SLOT(slotMainItemSizeChanged()));
|
||||||
d->resizeOrigin = DialogPrivate::MainItem;
|
d->slotMainItemSizeChanged();
|
||||||
d->syncTimer->start(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (mainItem->metaObject()->indexOfSignal("heightChanged")) {
|
|
||||||
connect(mainItem, &QQuickItem::heightChanged, [ = ]() {
|
|
||||||
d->resizeOrigin = DialogPrivate::MainItem;
|
|
||||||
d->syncTimer->start(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
d->resizeOrigin = DialogPrivate::MainItem;
|
|
||||||
d->requestSizeSync();
|
|
||||||
|
|
||||||
//Extract the representation's Layout, if any
|
//Extract the representation's Layout, if any
|
||||||
QObject *layout = 0;
|
QObject *layout = 0;
|
||||||
@ -546,7 +697,7 @@ void Dialog::setMainItem(QQuickItem *mainItem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d->mainItemLayout) {
|
if (d->mainItemLayout) {
|
||||||
disconnect(d->mainItemLayout.data(), 0, this, 0);
|
disconnect(d->mainItemLayout, 0, this, 0);
|
||||||
}
|
}
|
||||||
d->mainItemLayout = layout;
|
d->mainItemLayout = layout;
|
||||||
|
|
||||||
@ -556,10 +707,7 @@ void Dialog::setMainItem(QQuickItem *mainItem)
|
|||||||
connect(layout, SIGNAL(maximumWidthChanged()), this, SLOT(updateMaximumWidth()));
|
connect(layout, SIGNAL(maximumWidthChanged()), this, SLOT(updateMaximumWidth()));
|
||||||
connect(layout, SIGNAL(maximumHeightChanged()), this, SLOT(updateMaximumHeight()));
|
connect(layout, SIGNAL(maximumHeightChanged()), this, SLOT(updateMaximumHeight()));
|
||||||
|
|
||||||
d->updateMinimumWidth();
|
d->updateLayoutParameters();
|
||||||
d->updateMinimumHeight();
|
|
||||||
d->updateMaximumWidth();
|
|
||||||
d->updateMaximumHeight();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -569,14 +717,19 @@ void Dialog::setMainItem(QQuickItem *mainItem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogPrivate::slotMainItemSizeChanged()
|
||||||
|
{
|
||||||
|
syncToMainItemSize();
|
||||||
|
}
|
||||||
|
|
||||||
QQuickItem *Dialog::visualParent() const
|
QQuickItem *Dialog::visualParent() const
|
||||||
{
|
{
|
||||||
return d->visualParent.data();
|
return d->visualParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dialog::setVisualParent(QQuickItem *visualParent)
|
void Dialog::setVisualParent(QQuickItem *visualParent)
|
||||||
{
|
{
|
||||||
if (d->visualParent.data() == visualParent) {
|
if (d->visualParent == visualParent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,8 +739,9 @@ void Dialog::setVisualParent(QQuickItem *visualParent)
|
|||||||
if (visualParent->window()) {
|
if (visualParent->window()) {
|
||||||
setTransientParent(visualParent->window());
|
setTransientParent(visualParent->window());
|
||||||
}
|
}
|
||||||
d->resizeOrigin = DialogPrivate::MainItem;
|
if (d->mainItem) {
|
||||||
d->requestSizeSync(true);
|
d->syncToMainItemSize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,8 +888,10 @@ void Dialog::setLocation(Plasma::Types::Location location)
|
|||||||
}
|
}
|
||||||
d->location = location;
|
d->location = location;
|
||||||
emit locationChanged();
|
emit locationChanged();
|
||||||
d->resizeOrigin = DialogPrivate::MainItem;
|
|
||||||
d->requestSizeSync();
|
if (d->mainItem) {
|
||||||
|
d->syncToMainItemSize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject *Dialog::margins() const
|
QObject *Dialog::margins() const
|
||||||
@ -756,17 +912,20 @@ void Dialog::adjustGeometry(const QRect &geom)
|
|||||||
|
|
||||||
void Dialog::resizeEvent(QResizeEvent* re)
|
void Dialog::resizeEvent(QResizeEvent* re)
|
||||||
{
|
{
|
||||||
d->frameSvgItem->setX(0);
|
|
||||||
d->frameSvgItem->setY(0);
|
|
||||||
d->frameSvgItem->setWidth(re->size().width());
|
|
||||||
d->frameSvgItem->setHeight(re->size().height());
|
|
||||||
|
|
||||||
QQuickWindow::resizeEvent(re);
|
QQuickWindow::resizeEvent(re);
|
||||||
|
|
||||||
if (d->resizeOrigin == DialogPrivate::Undefined) {
|
d->mainItem->disconnect(this);
|
||||||
d->resizeOrigin = DialogPrivate::Window;
|
|
||||||
}
|
d->frameSvgItem->setWidth(re->size().width());
|
||||||
d->requestSizeSync(true);
|
d->frameSvgItem->setHeight(re->size().height());
|
||||||
|
auto margin = d->frameSvgItem->margins();
|
||||||
|
d->mainItem->setX(margin->left());
|
||||||
|
d->mainItem->setY(margin->top());
|
||||||
|
d->mainItem->setWidth(re->size().width() - margin->left() - margin->right());
|
||||||
|
d->mainItem->setHeight(re->size().height() - margin->top() - margin->bottom());
|
||||||
|
|
||||||
|
QObject::connect(d->mainItem, SIGNAL(widthChanged()), this, SLOT(slotMainItemSizeChanged()));
|
||||||
|
QObject::connect(d->mainItem, SIGNAL(heightChanged()), this, SLOT(slotMainItemSizeChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dialog::setType(WindowType type)
|
void Dialog::setType(WindowType type)
|
||||||
@ -833,7 +992,6 @@ void Dialog::focusOutEvent(QFocusEvent *ev)
|
|||||||
bool childHasFocus = focusWindow && ((focusWindow->isActive() && isAncestorOf(focusWindow)) || focusWindow->type() & Qt::Popup);
|
bool childHasFocus = focusWindow && ((focusWindow->isActive() && isAncestorOf(focusWindow)) || focusWindow->type() & Qt::Popup);
|
||||||
|
|
||||||
if (qobject_cast<const View *>(focusWindow) || (!parentHasFocus && !childHasFocus)) {
|
if (qobject_cast<const View *>(focusWindow) || (!parentHasFocus && !childHasFocus)) {
|
||||||
qDebug() << "DIALOG: hiding dialog.";
|
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
emit windowDeactivated();
|
emit windowDeactivated();
|
||||||
}
|
}
|
||||||
@ -872,15 +1030,24 @@ void Dialog::hideEvent(QHideEvent *event)
|
|||||||
|
|
||||||
void Dialog::classBegin()
|
void Dialog::classBegin()
|
||||||
{
|
{
|
||||||
|
d->componentComplete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dialog::componentComplete()
|
void Dialog::componentComplete()
|
||||||
{
|
{
|
||||||
d->componentComplete = true;
|
d->componentComplete = true;
|
||||||
|
|
||||||
|
d->updateTheme();
|
||||||
|
|
||||||
|
if (d->mainItem) {
|
||||||
d->syncToMainItemSize();
|
d->syncToMainItemSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (d->mainItemLayout) {
|
||||||
|
d->updateLayoutParameters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Dialog::hideOnWindowDeactivate() const
|
bool Dialog::hideOnWindowDeactivate() const
|
||||||
{
|
{
|
||||||
return d->hideOnWindowDeactivate;
|
return d->hideOnWindowDeactivate;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
#include <QWeakPointer>
|
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
#include <QQmlParserStatus>
|
#include <QQmlParserStatus>
|
||||||
|
|
||||||
@ -236,15 +235,16 @@ private:
|
|||||||
friend class DialogPrivate;
|
friend class DialogPrivate;
|
||||||
DialogPrivate *const d;
|
DialogPrivate *const d;
|
||||||
|
|
||||||
Q_PRIVATE_SLOT(d, void syncBorders())
|
Q_PRIVATE_SLOT(d, void updateInputShape())
|
||||||
Q_PRIVATE_SLOT(d, void updateTheme())
|
Q_PRIVATE_SLOT(d, void updateTheme())
|
||||||
Q_PRIVATE_SLOT(d, void updateVisibility(bool visible))
|
Q_PRIVATE_SLOT(d, void updateVisibility(bool visible))
|
||||||
Q_PRIVATE_SLOT(d, void updateInputShape())
|
|
||||||
|
|
||||||
Q_PRIVATE_SLOT(d, void updateMinimumWidth())
|
Q_PRIVATE_SLOT(d, void updateMinimumWidth())
|
||||||
Q_PRIVATE_SLOT(d, void updateMinimumHeight())
|
Q_PRIVATE_SLOT(d, void updateMinimumHeight())
|
||||||
Q_PRIVATE_SLOT(d, void updateMaximumWidth())
|
Q_PRIVATE_SLOT(d, void updateMaximumWidth())
|
||||||
Q_PRIVATE_SLOT(d, void updateMaximumHeight())
|
Q_PRIVATE_SLOT(d, void updateMaximumHeight())
|
||||||
|
|
||||||
|
Q_PRIVATE_SLOT(d, void slotMainItemSizeChanged())
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
59
tests/dialog_fullscreen.qml
Normal file
59
tests/dialog_fullscreen.qml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Vishesh Handa <vhanda@kde.org>
|
||||||
|
*
|
||||||
|
* 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,
|
||||||
|
* 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 Library General Public
|
||||||
|
* License along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
import QtQuick.Controls 1.1 as Controls
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
|
||||||
|
PlasmaCore.Dialog {
|
||||||
|
id: dialog
|
||||||
|
location: PlasmaCore.Types.Floating
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Controls.Label {
|
||||||
|
Layout.maximumWidth: rect.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
text: "Clicking on the rectangle should toggle the full screen mode. Make sure it retains its original geometry when jumping in between full screen and normal"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rect
|
||||||
|
color: "green"
|
||||||
|
|
||||||
|
width: 500
|
||||||
|
height: 500
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (dialog.location != PlasmaCore.Types.FullScreen) {
|
||||||
|
dialog.location = PlasmaCore.Types.FullScreen;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dialog.location = PlasmaCore.Types.Floating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,7 @@ import QtQuick.Layouts 1.1
|
|||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
PlasmaCore.Dialog {
|
PlasmaCore.Dialog {
|
||||||
|
id: root
|
||||||
location: PlasmaCore.Types.Floating
|
location: PlasmaCore.Types.Floating
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@ -34,6 +35,10 @@ PlasmaCore.Dialog {
|
|||||||
|
|
||||||
color: "red"
|
color: "red"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: rect.Layout.minimumWidth
|
||||||
|
height: rect.Layout.minimumHeight
|
||||||
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
@ -53,6 +58,18 @@ PlasmaCore.Dialog {
|
|||||||
rect.Layout.minimumHeight = rect.Layout.minimumHeight + 10
|
rect.Layout.minimumHeight = rect.Layout.minimumHeight + 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Controls.Button {
|
||||||
|
text: "Increase dialog width"
|
||||||
|
onClicked: {
|
||||||
|
root.width = root.width + 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Controls.Button {
|
||||||
|
text: "Increase dialog height"
|
||||||
|
onClicked: {
|
||||||
|
root.height = root.height + 10
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,11 @@ PlasmaCore.Dialog {
|
|||||||
id: innerRect
|
id: innerRect
|
||||||
color: "#ddffdd"
|
color: "#ddffdd"
|
||||||
width: 200
|
width: 200
|
||||||
height: 200
|
height: layout.height
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
id: layout
|
||||||
anchors.margins: 5
|
anchors.margins: 5
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left:parent.left
|
anchors.left:parent.left
|
||||||
|
89
tests/dialog_positioning2.qml
Normal file
89
tests/dialog_positioning2.qml
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Vishesh Handa <vhanda@kde.org>
|
||||||
|
*
|
||||||
|
* 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,
|
||||||
|
* 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 Library General Public
|
||||||
|
* License along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
import QtQuick.Controls 1.1 as Controls
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.components 2.0 as PlasmaComponents
|
||||||
|
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
Controls.Label {
|
||||||
|
text: "Press the buttom and make sure the popup is on the correct place"
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
PlasmaComponents.Button {
|
||||||
|
id: settingsButton
|
||||||
|
iconSource: "configure"
|
||||||
|
text: "Press Me"
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
contextMenu.visible = !contextMenu.visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaCore.Dialog {
|
||||||
|
id: contextMenu
|
||||||
|
visualParent: settingsButton
|
||||||
|
|
||||||
|
location: PlasmaCore.Types.BottomEdge
|
||||||
|
type: PlasmaCore.Dialog.PopupMenu
|
||||||
|
flags: Qt.Popup | Qt.FramelessWindowHint | Qt.WindowDoesNotAcceptFocus
|
||||||
|
|
||||||
|
mainItem: ColumnLayout {
|
||||||
|
id: menuColumn
|
||||||
|
Layout.minimumWidth: menuColumn.implicitWidth
|
||||||
|
Layout.minimumHeight: menuColumn.implicitHeight
|
||||||
|
spacing: units.smallSpacing
|
||||||
|
|
||||||
|
PlasmaExtras.Heading {
|
||||||
|
level: 3
|
||||||
|
text: "Panel Alignment"
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaComponents.ButtonColumn {
|
||||||
|
spacing: 0
|
||||||
|
Layout.fillWidth: true
|
||||||
|
PlasmaComponents.ToolButton {
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
text: "Left"
|
||||||
|
checkable: true
|
||||||
|
flat: false
|
||||||
|
}
|
||||||
|
PlasmaComponents.ToolButton {
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
text: "Center"
|
||||||
|
checkable: true
|
||||||
|
flat: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
tests/dialog_tooltip.qml
Normal file
80
tests/dialog_tooltip.qml
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Vishesh Handa <vhanda@kde.org>
|
||||||
|
*
|
||||||
|
* 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,
|
||||||
|
* 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 Library General Public
|
||||||
|
* License along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.2
|
||||||
|
|
||||||
|
import QtQuick.Controls 1.1 as Controls
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Controls.Label {
|
||||||
|
Layout.maximumWidth: mainLayout.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
text: "Hover over every rectangle so that the tooltip pops up. It should popup in the correct position"
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: mainLayout
|
||||||
|
Rectangle {
|
||||||
|
width: 300
|
||||||
|
height: 100
|
||||||
|
color: "red"
|
||||||
|
|
||||||
|
PlasmaCore.ToolTipArea {
|
||||||
|
width: 300
|
||||||
|
height: 50
|
||||||
|
|
||||||
|
mainText: "Title Number 1"
|
||||||
|
subText: "subtext"
|
||||||
|
icon: "plasma"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 300
|
||||||
|
height: 100
|
||||||
|
color: "blue"
|
||||||
|
|
||||||
|
PlasmaCore.ToolTipArea {
|
||||||
|
width: 500
|
||||||
|
height: 110
|
||||||
|
|
||||||
|
mainText: "Title Number 2"
|
||||||
|
subText: "This is some really really really long subtext. So lets write stores about the woods and the trees and how we're going hiking. Yaye!"
|
||||||
|
icon: "configure"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 300
|
||||||
|
height: 100
|
||||||
|
color: "green"
|
||||||
|
|
||||||
|
PlasmaCore.ToolTipArea {
|
||||||
|
width: 350
|
||||||
|
height: 70
|
||||||
|
|
||||||
|
mainText: "Wakka Wakka"
|
||||||
|
subText: "It's time for Africa"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
tests/dialog_visualParentChange.qml
Normal file
120
tests/dialog_visualParentChange.qml
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Vishesh Handa <vhanda@kde.org>
|
||||||
|
*
|
||||||
|
* 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,
|
||||||
|
* 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 Library General Public
|
||||||
|
* License along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
import QtQuick.Controls 1.1 as Controls
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Controls.Label {
|
||||||
|
Layout.maximumWidth: mainLayout.width
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
text: "Click on each coloured box to make a dialog popup. It should popup in the correct position. The popup should also move from one rectanlge to the other on hovering"
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: mainLayout
|
||||||
|
Rectangle {
|
||||||
|
width: 300
|
||||||
|
height: 100
|
||||||
|
color: "red"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: {
|
||||||
|
dialog.visualParent = parent;
|
||||||
|
dialog.visible = !dialog.visible;
|
||||||
|
}
|
||||||
|
onEntered: {
|
||||||
|
dialog.visualParent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 300
|
||||||
|
height: 100
|
||||||
|
color: "blue"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: {
|
||||||
|
dialog.visualParent = parent;
|
||||||
|
dialog.visible = !dialog.visible;
|
||||||
|
}
|
||||||
|
onEntered: {
|
||||||
|
dialog.visualParent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 300
|
||||||
|
height: 100
|
||||||
|
color: "green"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: {
|
||||||
|
dialog.visualParent = parent;
|
||||||
|
dialog.visible = !dialog.visible;
|
||||||
|
}
|
||||||
|
onEntered: {
|
||||||
|
dialog.visualParent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 300
|
||||||
|
height: 100
|
||||||
|
color: "yellow"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: {
|
||||||
|
dialog.visualParent = parent;
|
||||||
|
dialog.visible = !dialog.visible;
|
||||||
|
}
|
||||||
|
onEntered: {
|
||||||
|
dialog.visualParent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlasmaCore.Dialog {
|
||||||
|
id: dialog
|
||||||
|
location: PlasmaCore.Types.BottomEdge
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: "black"
|
||||||
|
width: 150
|
||||||
|
height: 150
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user