From 07b7041b9289048fd498eb489e8fab2fa92417d6 Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 28 Feb 2012 14:49:20 +0100 Subject: [PATCH] common class for sheet and dialog --- .../plasmacomponents/CMakeLists.txt | 1 + .../plasmacomponents/fullscreendialog.cpp | 337 +-------------- .../plasmacomponents/fullscreendialog.h | 71 +--- .../plasmacomponents/fullscreensheet.cpp | 78 +++- .../plasmacomponents/fullscreensheet.h | 28 +- .../plasmacomponents/fullscreenwindow.cpp | 383 ++++++++++++++++++ .../plasmacomponents/fullscreenwindow.h | 101 +++++ .../plasmacomponentsplugin.cpp | 2 + .../platformcomponents/touch/Sheet.qml | 48 ++- .../plasmacomponents/qml/Sheet.qml | 36 +- 10 files changed, 643 insertions(+), 442 deletions(-) create mode 100644 declarativeimports/plasmacomponents/fullscreenwindow.cpp create mode 100644 declarativeimports/plasmacomponents/fullscreenwindow.h diff --git a/declarativeimports/plasmacomponents/CMakeLists.txt b/declarativeimports/plasmacomponents/CMakeLists.txt index 8428f2be2..8563e8cc4 100644 --- a/declarativeimports/plasmacomponents/CMakeLists.txt +++ b/declarativeimports/plasmacomponents/CMakeLists.txt @@ -3,6 +3,7 @@ project(plasmacomponents) set(plasmacomponents_SRCS fullscreendialog.cpp fullscreensheet.cpp + fullscreenwindow.cpp plasmacomponentsplugin.cpp qrangemodel.cpp enums.cpp diff --git a/declarativeimports/plasmacomponents/fullscreendialog.cpp b/declarativeimports/plasmacomponents/fullscreendialog.cpp index 76542e2a3..591e02442 100644 --- a/declarativeimports/plasmacomponents/fullscreendialog.cpp +++ b/declarativeimports/plasmacomponents/fullscreendialog.cpp @@ -18,351 +18,18 @@ ***************************************************************************/ #include "fullscreendialog.h" -#include "../core/declarativeitemcontainer_p.h" -#include "plasmacomponentsplugin.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - - -uint FullScreenDialog::s_numItems = 0; - -class Background : public QWidget -{ -public: - Background(FullScreenDialog *dialog) - : QWidget( 0L ), - m_dialog(dialog) - { - setAttribute( Qt::WA_NoSystemBackground ); - setAttribute( Qt::WA_TranslucentBackground ); - - setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint); - KWindowSystem::setOnAllDesktops(winId(), true); - unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager | NET::MaxVert | NET::MaxHoriz; - KWindowSystem::setState(effectiveWinId(), state); - } - - ~Background() - {} - - void paintEvent( QPaintEvent *e ) - { - QPainter painter( this ); - painter.setCompositionMode(QPainter::CompositionMode_Source); - painter.fillRect(e->rect(), QColor(0, 0, 0, 80)); - } - - void mousePressEvent(QMouseEvent *event) - { - event->accept(); - m_dialog->view()->winId(); - KWindowSystem::forceActiveWindow(m_dialog->view()->winId()); - } - - void mouseReleaseEvent(QMouseEvent *event) - { - if (!m_dialog->view()->geometry().contains(event->globalPos())) { - m_dialog->close(); - } - } - -private: - FullScreenDialog *m_dialog; -}; FullScreenDialog::FullScreenDialog(QDeclarativeItem *parent) - : QDeclarativeItem(parent), - m_declarativeItemContainer(0) + : FullScreenWindow(parent) { - m_view = new QGraphicsView(); - m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_view->installEventFilter(this); - m_view->setAutoFillBackground(false); - m_view->viewport()->setAutoFillBackground(false); - m_view->setAttribute(Qt::WA_TranslucentBackground); - m_view->setAttribute(Qt::WA_NoSystemBackground); - m_view->viewport()->setAttribute(Qt::WA_NoSystemBackground); - m_view->setCacheMode(QGraphicsView::CacheNone); - m_view->setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint); - m_view->setFrameShape(QFrame::NoFrame); - KWindowSystem::setOnAllDesktops(m_view->winId(), true); - unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager; - KWindowSystem::setState(m_view->effectiveWinId(), state); + init("Dialog"); - //Try to figure out the path of the dialog component - QString componentsPlatform = getenv("KDE_PLASMA_COMPONENTS_PLATFORM"); - if (componentsPlatform.isEmpty()) { - KConfigGroup cg(KSharedConfig::openConfig("kdeclarativerc"), "Components-platform"); - componentsPlatform = cg.readEntry("name", "desktop"); - } - - QString filePath; - if (componentsPlatform == "desktop") { - foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "imports/")) { - filePath = importPath % "org/kde/plasma/components/" % componentName() % ".qml"; - QFile f(filePath); - if (f.exists()) { - break; - } - } - } else { - foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "platformimports/" % componentsPlatform)) { - filePath = importPath % "org/kde/plasma/components/" % componentName() % ".qml"; - QFile f(filePath); - if (f.exists()) { - break; - } - } - } - - - QDeclarativeEngine *engine = EngineBookKeeping::self()->engineFor(this); - QDeclarativeComponent *component = new QDeclarativeComponent(engine, filePath, this); - - QDeclarativeContext *creationContext = component->creationContext(); - m_rootObject = component->create(creationContext); - if (component->status() == QDeclarativeComponent::Error) { - kWarning()<errors(); - } - - if (m_rootObject) { - setMainItem(qobject_cast(m_rootObject.data())); - connect(m_rootObject.data(), SIGNAL(statusChanged()), this, SLOT(statusHasChanged())); - connect(m_rootObject.data(), SIGNAL(accepted()), this, SIGNAL(accepted())); - connect(m_rootObject.data(), SIGNAL(rejected()), this, SIGNAL(rejected())); - connect(m_rootObject.data(), SIGNAL(clickedOutside()), this, SIGNAL(clickedOutside())); - } - - m_background = new Background(this); } FullScreenDialog::~FullScreenDialog() { - delete m_view; } -QString FullScreenDialog::componentName() const -{ - return "Dialog"; -} - -QGraphicsObject *FullScreenDialog::mainItem() const -{ - return m_mainItem.data(); -} - -void FullScreenDialog::setMainItem(QGraphicsObject *mainItem) -{ - if (m_mainItem.data() != mainItem) { - if (m_mainItem) { - m_mainItem.data()->setParent(mainItem->parent()); - m_mainItem.data()->removeEventFilter(this); - m_mainItem.data()->setY(0); - m_scene = 0; - } - m_mainItem = mainItem; - if (mainItem) { - mainItem->setParentItem(0); - mainItem->setParent(this); - m_scene = mainItem->scene(); - } - - mainItem->installEventFilter(this); - - //if this is called in Compenent.onCompleted we have to wait a loop the item is added to a scene - QTimer::singleShot(0, this, SLOT(syncMainItem())); - } -} - -void FullScreenDialog::syncMainItem() -{ - if (!m_mainItem) { - return; - } - - //not have a scene? go up in the hyerarchy until we find something with a scene - QGraphicsScene *scene = m_mainItem.data()->scene(); - if (!scene) { - QObject *parent = m_mainItem.data(); - while ((parent = parent->parent())) { - QGraphicsObject *qo = qobject_cast(parent); - if (qo) { - scene = qo->scene(); - - if (scene) { - scene->addItem(m_mainItem.data()); - ++s_numItems; - Plasma::Corona *corona = qobject_cast(scene); - QDeclarativeItem *di = qobject_cast(m_mainItem.data()); - - if (corona && di) { - if (!m_declarativeItemContainer) { - m_declarativeItemContainer = new DeclarativeItemContainer(); - scene->addItem(m_declarativeItemContainer); - corona->addOffscreenWidget(m_declarativeItemContainer); - } - m_declarativeItemContainer->setDeclarativeItem(di); - } else { - m_mainItem.data()->setY(-10000*s_numItems); - m_mainItem.data()->setY(10000*s_numItems); - } - break; - } - } - } - } - - if (!scene) { - return; - } - - m_view->setScene(scene); - - - if (m_declarativeItemContainer) { - m_view->resize(m_declarativeItemContainer->size().toSize()); - m_view->setSceneRect(m_declarativeItemContainer->geometry()); - } else { - QRectF itemGeometry(QPointF(m_mainItem.data()->x(), m_mainItem.data()->y()), - QSizeF(m_mainItem.data()->boundingRect().size())); - m_view->resize(itemGeometry.size().toSize()); - m_view->setSceneRect(itemGeometry); - } - - m_view->move(QApplication::desktop()->availableGeometry().center() - QPoint(m_view->width()/2, m_view->height()/2)); -} - -bool FullScreenDialog::isVisible() const -{ - return m_view->isVisible(); -} - -void FullScreenDialog::setVisible(const bool visible) -{ - if (m_view->isVisible() != visible) { - m_background->setVisible(visible); - Plasma::WindowEffects::slideWindow(m_view->winId(), Plasma::BottomEdge, 0); - m_view->setVisible(visible); - unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager; - KWindowSystem::setState(m_view->effectiveWinId(), state); - KWindowSystem::setState(m_background->effectiveWinId(), state); - if (visible) { - m_view->raise(); - KWindowSystem::forceActiveWindow(m_view->effectiveWinId()); - } - } -} - -QGraphicsView *FullScreenDialog::view() const -{ - return m_view; -} - -QDeclarativeListProperty FullScreenDialog::title() -{ - if (m_rootObject) { - return m_rootObject.data()->property("title").value >(); - } else { - return QDeclarativeListProperty(this, m_dummyTitleElements); - } -} - -QDeclarativeListProperty FullScreenDialog::content() -{ - if (m_rootObject) { - return m_rootObject.data()->property("content").value >(); - } else { - return QDeclarativeListProperty(this, m_dummyContentElements); - } -} - -QDeclarativeListProperty FullScreenDialog::buttons() -{ - if (m_rootObject) { - return m_rootObject.data()->property("buttons").value >(); - } else { - return QDeclarativeListProperty(this, m_dummyButtonsElements); - } -} - -DialogStatus::Status FullScreenDialog::status() const -{ - if (m_rootObject) { - return (DialogStatus::Status)m_rootObject.data()->property("status").toInt(); - } else { - return DialogStatus::Closed; - } -} - - -void FullScreenDialog::statusHasChanged() -{ - if (status() == DialogStatus::Closed) { - setVisible(false); - } else { - setVisible(true); - } - emit statusChanged(); -} - -void FullScreenDialog::open() -{ - if (m_rootObject) { - QMetaObject::invokeMethod(m_rootObject.data(), "open"); - } -} - -void FullScreenDialog::accept() -{ - if (m_rootObject) { - QMetaObject::invokeMethod(m_rootObject.data(), "accept"); - } -} - -void FullScreenDialog::reject() -{ - if (m_rootObject) { - QMetaObject::invokeMethod(m_rootObject.data(), "reject"); - } -} - -void FullScreenDialog::close() -{ - if (m_rootObject) { - QMetaObject::invokeMethod(m_rootObject.data(), "close"); - } -} - - - - -bool FullScreenDialog::eventFilter(QObject *watched, QEvent *event) -{ - if (watched == m_mainItem.data() && - (event->type() == QEvent::GraphicsSceneResize)) { - syncMainItem(); - } - return false; -} - - - #include "fullscreendialog.moc" diff --git a/declarativeimports/plasmacomponents/fullscreendialog.h b/declarativeimports/plasmacomponents/fullscreendialog.h index 53132bea6..6cd8adf41 100644 --- a/declarativeimports/plasmacomponents/fullscreendialog.h +++ b/declarativeimports/plasmacomponents/fullscreendialog.h @@ -19,82 +19,15 @@ #ifndef FULLSCREENDIALOG_P #define FULLSCREENDIALOG_P -#include -#include -#include -#include -#include -#include +#include "fullscreenwindow.h" -#include "enums.h" - -class QGraphicsObject; -class QGraphicsView; -class QGraphicsScene; -class DeclarativeItemContainer; -class Background; - -class FullScreenDialog : public QDeclarativeItem +class FullScreenDialog : public FullScreenWindow { Q_OBJECT - Q_PROPERTY(QDeclarativeListProperty title READ title DESIGNABLE false) - Q_PROPERTY(QDeclarativeListProperty content READ content DESIGNABLE false) - Q_PROPERTY(QDeclarativeListProperty buttons READ buttons DESIGNABLE false) - Q_PROPERTY(DialogStatus::Status status READ status NOTIFY statusChanged) - - public: FullScreenDialog(QDeclarativeItem *parent = 0); ~FullScreenDialog(); - - QGraphicsObject *mainItem() const; - void setMainItem(QGraphicsObject *mainItem); - - bool isVisible() const; - void setVisible(const bool visible); - - QGraphicsView *view() const; - - //QML properties - QDeclarativeListProperty title(); - QDeclarativeListProperty content(); - QDeclarativeListProperty buttons(); - DialogStatus::Status status() const; - - Q_INVOKABLE void open(); - Q_INVOKABLE void accept(); - Q_INVOKABLE void reject(); - Q_INVOKABLE void close(); - -Q_SIGNALS: - void accepted(); - void rejected(); - void clickedOutside(); - void statusChanged(); - - -private Q_SLOTS: - void syncMainItem(); - void statusHasChanged(); - -protected: - bool eventFilter(QObject *watched, QEvent *event); - virtual QString componentName() const; - -private: - QGraphicsView *m_view; - QWeakPointer m_mainItem; - DeclarativeItemContainer *m_declarativeItemContainer; - QGraphicsScene *m_scene; - QWeakPointer m_rootObject; - static uint s_numItems; - Background *m_background; - - //those only used in case of error, to not make plasma crash - QList m_dummyTitleElements; - QList m_dummyContentElements; - QList m_dummyButtonsElements; }; #endif diff --git a/declarativeimports/plasmacomponents/fullscreensheet.cpp b/declarativeimports/plasmacomponents/fullscreensheet.cpp index 66e897c2c..91eb82786 100644 --- a/declarativeimports/plasmacomponents/fullscreensheet.cpp +++ b/declarativeimports/plasmacomponents/fullscreensheet.cpp @@ -19,19 +19,91 @@ #include "fullscreensheet.h" +#include FullScreenSheet::FullScreenSheet(QDeclarativeItem *parent) - : FullScreenDialog(parent) + : FullScreenWindow(parent) { + init("Sheet"); + + if (mainItem()) { + connect(mainItem(), SIGNAL(acceptButtonChanged()), + this, SIGNAL(acceptButtonChanged())); + connect(mainItem(), SIGNAL(rejectButtonChanged()), + this, SIGNAL(rejectButtonChanged())); + connect(mainItem(), SIGNAL(acceptButtonTextChanged()), + this, SIGNAL(acceptButtonTextChanged())); + connect(mainItem(), SIGNAL(rejectButtonTextChanged()), + this, SIGNAL(rejectButtonTextChanged())); + } } FullScreenSheet::~FullScreenSheet() { } -QString FullScreenSheet::componentName() const +QGraphicsObject *FullScreenSheet::acceptButton() const { - return "Sheet"; + if (mainItem()) { + return mainItem()->property("acceptButton").value(); + } else { + return 0; + } +} + +void FullScreenSheet::setAcceptButton(QGraphicsObject *button) +{ + if (mainItem()) { + mainItem()->setProperty("acceptButton", QVariant::fromValue(button)); + } +} + +QGraphicsObject *FullScreenSheet::rejectButton() const +{ + if (mainItem()) { + return mainItem()->property("rejectButton").value(); + } else { + return 0; + } +} + +void FullScreenSheet::setRejectButton(QGraphicsObject *button) +{ + if (mainItem()) { + mainItem()->setProperty("rejectButton", QVariant::fromValue(button)); + } +} + +QString FullScreenSheet::acceptButtonText() const +{ + if (mainItem()) { + return mainItem()->property("acceptButtonText").toString(); + } else { + return 0; + } +} + +void FullScreenSheet::setAcceptButtonText(const QString &text) +{ + if (mainItem()) { + mainItem()->setProperty("acceptButtonText", QVariant::fromValue(text)); + } +} + +QString FullScreenSheet::rejectButtonText() const +{ + if (mainItem()) { + return mainItem()->property("rejectButtonText").toString(); + } else { + return 0; + } +} + +void FullScreenSheet::setRejectButtonText(const QString &text) +{ + if (mainItem()) { + mainItem()->setProperty("rejectButtonText", QVariant::fromValue(text)); + } } #include "fullscreensheet.moc" diff --git a/declarativeimports/plasmacomponents/fullscreensheet.h b/declarativeimports/plasmacomponents/fullscreensheet.h index 4590c737a..17c1bbe44 100644 --- a/declarativeimports/plasmacomponents/fullscreensheet.h +++ b/declarativeimports/plasmacomponents/fullscreensheet.h @@ -19,18 +19,38 @@ #ifndef FULLSCREENSHEET_P #define FULLSCREENSHEET_P -#include "fullscreendialog.h" +#include "fullscreenwindow.h" -class FullScreenSheet : public FullScreenDialog +class FullScreenSheet : public FullScreenWindow { Q_OBJECT + Q_PROPERTY(QGraphicsObject *acceptButton READ acceptButton WRITE setAcceptButton NOTIFY acceptButtonChanged) + Q_PROPERTY(QGraphicsObject *rejectButton READ rejectButton WRITE setRejectButton NOTIFY rejectButtonChanged) + + Q_PROPERTY(QString acceptButtonText READ acceptButtonText WRITE setAcceptButtonText NOTIFY acceptButtonTextChanged) + Q_PROPERTY(QString rejectButtonText READ rejectButtonText WRITE setRejectButtonText NOTIFY rejectButtonTextChanged) public: FullScreenSheet(QDeclarativeItem *parent = 0); ~FullScreenSheet(); -protected: - virtual QString componentName() const; + QGraphicsObject *acceptButton() const; + void setAcceptButton(QGraphicsObject *button); + + QGraphicsObject *rejectButton() const; + void setRejectButton(QGraphicsObject *button); + + QString acceptButtonText() const; + void setAcceptButtonText(const QString &text); + + QString rejectButtonText() const; + void setRejectButtonText(const QString &text); + +Q_SIGNALS: + void acceptButtonChanged(); + void rejectButtonChanged(); + void acceptButtonTextChanged(); + void rejectButtonTextChanged(); }; #endif diff --git a/declarativeimports/plasmacomponents/fullscreenwindow.cpp b/declarativeimports/plasmacomponents/fullscreenwindow.cpp new file mode 100644 index 000000000..486bdbe6e --- /dev/null +++ b/declarativeimports/plasmacomponents/fullscreenwindow.cpp @@ -0,0 +1,383 @@ +/*************************************************************************** + * Copyright 2012 Marco Martin * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "fullscreenwindow.h" +#include "../core/declarativeitemcontainer_p.h" +#include "plasmacomponentsplugin.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + +uint FullScreenWindow::s_numItems = 0; + +class Background : public QWidget +{ +public: + Background(FullScreenWindow *dialog) + : QWidget( 0L ), + m_dialog(dialog) + { + setAttribute( Qt::WA_NoSystemBackground ); + setAttribute( Qt::WA_TranslucentBackground ); + + setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint); + KWindowSystem::setOnAllDesktops(winId(), true); + unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager | NET::MaxVert | NET::MaxHoriz; + KWindowSystem::setState(effectiveWinId(), state); + } + + ~Background() + {} + + void paintEvent( QPaintEvent *e ) + { + QPainter painter( this ); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(e->rect(), QColor(0, 0, 0, 80)); + } + + void mousePressEvent(QMouseEvent *event) + { + event->accept(); + m_dialog->view()->winId(); + KWindowSystem::forceActiveWindow(m_dialog->view()->winId()); + } + + void mouseReleaseEvent(QMouseEvent *event) + { + if (!m_dialog->view()->geometry().contains(event->globalPos())) { + m_dialog->close(); + } + } + +private: + FullScreenWindow *m_dialog; +}; + +FullScreenWindow::FullScreenWindow(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + m_declarativeItemContainer(0) +{ + m_view = new QGraphicsView(); + m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_view->installEventFilter(this); + m_view->setAutoFillBackground(false); + m_view->viewport()->setAutoFillBackground(false); + m_view->setAttribute(Qt::WA_TranslucentBackground); + m_view->setAttribute(Qt::WA_NoSystemBackground); + m_view->viewport()->setAttribute(Qt::WA_NoSystemBackground); + m_view->setCacheMode(QGraphicsView::CacheNone); + m_view->setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint); + m_view->setFrameShape(QFrame::NoFrame); + KWindowSystem::setOnAllDesktops(m_view->winId(), true); + unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager; + KWindowSystem::setState(m_view->effectiveWinId(), state); + + m_background = new Background(this); +} + +FullScreenWindow::~FullScreenWindow() +{ + delete m_view; +} + +void FullScreenWindow::init(const QString &componentName) +{ + if (m_rootObject) { + return; + } + + //Try to figure out the path of the dialog component + QString componentsPlatform = getenv("KDE_PLASMA_COMPONENTS_PLATFORM"); + if (componentsPlatform.isEmpty()) { + KConfigGroup cg(KSharedConfig::openConfig("kdeclarativerc"), "Components-platform"); + componentsPlatform = cg.readEntry("name", "desktop"); + } + + QString filePath; + if (componentsPlatform == "desktop") { + foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "imports/")) { + filePath = importPath % "org/kde/plasma/components/" % componentName % ".qml"; + QFile f(filePath); + if (f.exists()) { + break; + } + } + } else { + foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "platformimports/" % componentsPlatform)) { + filePath = importPath % "org/kde/plasma/components/" % componentName % ".qml"; + QFile f(filePath); + if (f.exists()) { + break; + } + } + } + + + QDeclarativeEngine *engine = EngineBookKeeping::self()->engineFor(this); + QDeclarativeComponent *component = new QDeclarativeComponent(engine, filePath, this); + + QDeclarativeContext *creationContext = component->creationContext(); + m_rootObject = component->create(creationContext); + if (component->status() == QDeclarativeComponent::Error) { + kWarning()<errors(); + } + + if (m_rootObject) { + setMainItem(qobject_cast(m_rootObject.data())); + connect(m_rootObject.data(), SIGNAL(statusChanged()), this, SLOT(statusHasChanged())); + connect(m_rootObject.data(), SIGNAL(accepted()), this, SIGNAL(accepted())); + connect(m_rootObject.data(), SIGNAL(rejected()), this, SIGNAL(rejected())); + connect(m_rootObject.data(), SIGNAL(clickedOutside()), this, SIGNAL(clickedOutside())); + } +} + +QGraphicsObject *FullScreenWindow::mainItem() const +{ + return m_mainItem.data(); +} + +void FullScreenWindow::setMainItem(QGraphicsObject *mainItem) +{ + if (m_mainItem.data() != mainItem) { + if (m_mainItem) { + m_mainItem.data()->setParent(mainItem->parent()); + m_mainItem.data()->removeEventFilter(this); + m_mainItem.data()->setY(0); + m_scene = 0; + } + m_mainItem = mainItem; + if (mainItem) { + mainItem->setParentItem(0); + mainItem->setParent(this); + m_scene = mainItem->scene(); + } + + mainItem->installEventFilter(this); + + //if this is called in Compenent.onCompleted we have to wait a loop the item is added to a scene + QTimer::singleShot(0, this, SLOT(syncViewToMainItem())); + } +} + +void FullScreenWindow::syncViewToMainItem() +{ + if (!m_mainItem) { + return; + } + + //not have a scene? go up in the hyerarchy until we find something with a scene + QGraphicsScene *scene = m_mainItem.data()->scene(); + if (!scene) { + QObject *parent = m_mainItem.data(); + while ((parent = parent->parent())) { + QGraphicsObject *qo = qobject_cast(parent); + if (qo) { + scene = qo->scene(); + + if (scene) { + scene->addItem(m_mainItem.data()); + ++s_numItems; + Plasma::Corona *corona = qobject_cast(scene); + QDeclarativeItem *di = qobject_cast(m_mainItem.data()); + + if (corona && di) { + if (!m_declarativeItemContainer) { + m_declarativeItemContainer = new DeclarativeItemContainer(); + scene->addItem(m_declarativeItemContainer); + corona->addOffscreenWidget(m_declarativeItemContainer); + } + m_declarativeItemContainer->setDeclarativeItem(di); + } else { + m_mainItem.data()->setY(-10000*s_numItems); + m_mainItem.data()->setY(10000*s_numItems); + } + break; + } + } + } + } + + if (!scene) { + return; + } + + m_view->setScene(scene); + + + if (m_declarativeItemContainer) { + m_view->resize(m_declarativeItemContainer->size().toSize()); + m_view->setSceneRect(m_declarativeItemContainer->geometry()); + } else { + QRectF itemGeometry(QPointF(m_mainItem.data()->x(), m_mainItem.data()->y()), + QSizeF(m_mainItem.data()->boundingRect().size())); + m_view->resize(itemGeometry.size().toSize()); + m_view->setSceneRect(itemGeometry); + } + + m_view->move(QApplication::desktop()->availableGeometry().center() - QPoint(m_view->width()/2, m_view->height()/2)); +} + +void FullScreenWindow::syncMainItemToView() +{ + if (!m_mainItem) { + return; + } + + m_mainItem.data()->setProperty("width", m_view->width()); + m_mainItem.data()->setProperty("height", m_view->height()); +} + +bool FullScreenWindow::isVisible() const +{ + return m_view->isVisible(); +} + +void FullScreenWindow::setVisible(const bool visible) +{ + if (m_view->isVisible() != visible) { + m_background->setVisible(visible); + Plasma::WindowEffects::slideWindow(m_view->winId(), Plasma::BottomEdge, 0); + m_view->setVisible(visible); + unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager; + KWindowSystem::setState(m_view->effectiveWinId(), state); + KWindowSystem::setState(m_background->effectiveWinId(), state); + if (visible) { + m_view->raise(); + KWindowSystem::forceActiveWindow(m_view->effectiveWinId()); + } + } +} + +QGraphicsView *FullScreenWindow::view() const +{ + return m_view; +} + +QDeclarativeListProperty FullScreenWindow::title() +{ + if (m_rootObject) { + return m_rootObject.data()->property("title").value >(); + } else { + return QDeclarativeListProperty(this, m_dummyTitleElements); + } +} + +QDeclarativeListProperty FullScreenWindow::content() +{ + if (m_rootObject) { + return m_rootObject.data()->property("content").value >(); + } else { + return QDeclarativeListProperty(this, m_dummyContentElements); + } +} + +QDeclarativeListProperty FullScreenWindow::buttons() +{ + if (m_rootObject) { + return m_rootObject.data()->property("buttons").value >(); + } else { + return QDeclarativeListProperty(this, m_dummyButtonsElements); + } +} + +DialogStatus::Status FullScreenWindow::status() const +{ + if (m_rootObject) { + return (DialogStatus::Status)m_rootObject.data()->property("status").toInt(); + } else { + return DialogStatus::Closed; + } +} + + +void FullScreenWindow::statusHasChanged() +{ + if (status() == DialogStatus::Closed) { + setVisible(false); + } else { + setVisible(true); + } + emit statusChanged(); +} + +void FullScreenWindow::open() +{ + if (m_rootObject) { + QMetaObject::invokeMethod(m_rootObject.data(), "open"); + } +} + +void FullScreenWindow::accept() +{ + if (m_rootObject) { + QMetaObject::invokeMethod(m_rootObject.data(), "accept"); + } +} + +void FullScreenWindow::reject() +{ + if (m_rootObject) { + QMetaObject::invokeMethod(m_rootObject.data(), "reject"); + } +} + +void FullScreenWindow::close() +{ + if (m_rootObject) { + QMetaObject::invokeMethod(m_rootObject.data(), "close"); + } +} + + + + +bool FullScreenWindow::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == m_mainItem.data() && + (event->type() == QEvent::GraphicsSceneResize)) { + syncViewToMainItem(); + } else if (watched == m_view && + (event->type() == QEvent::Resize)) { + syncMainItemToView(); + } + return false; +} + + + +#include "fullscreenwindow.moc" + diff --git a/declarativeimports/plasmacomponents/fullscreenwindow.h b/declarativeimports/plasmacomponents/fullscreenwindow.h new file mode 100644 index 000000000..c1a378604 --- /dev/null +++ b/declarativeimports/plasmacomponents/fullscreenwindow.h @@ -0,0 +1,101 @@ +/*************************************************************************** + * Copyright 2012 Marco Martin * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ +#ifndef FULLSCREENWINDOW_P +#define FULLSCREENWINDOW_P + +#include +#include +#include +#include +#include +#include + +#include "enums.h" + +class QGraphicsObject; +class QGraphicsView; +class QGraphicsScene; +class DeclarativeItemContainer; +class Background; + +class FullScreenWindow : public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QDeclarativeListProperty title READ title DESIGNABLE false) + Q_PROPERTY(QDeclarativeListProperty content READ content DESIGNABLE false) + Q_PROPERTY(QDeclarativeListProperty buttons READ buttons DESIGNABLE false) + Q_PROPERTY(DialogStatus::Status status READ status NOTIFY statusChanged) + + +public: + FullScreenWindow(QDeclarativeItem *parent = 0); + ~FullScreenWindow(); + + QGraphicsObject *mainItem() const; + void setMainItem(QGraphicsObject *mainItem); + + bool isVisible() const; + void setVisible(const bool visible); + + QGraphicsView *view() const; + + //QML properties + QDeclarativeListProperty title(); + QDeclarativeListProperty content(); + QDeclarativeListProperty buttons(); + DialogStatus::Status status() const; + + Q_INVOKABLE void open(); + Q_INVOKABLE void accept(); + Q_INVOKABLE void reject(); + Q_INVOKABLE void close(); + +Q_SIGNALS: + void accepted(); + void rejected(); + void clickedOutside(); + void statusChanged(); + + +private Q_SLOTS: + void syncViewToMainItem(); + void syncMainItemToView(); + void statusHasChanged(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + void init(const QString &componentName); + +private: + QGraphicsView *m_view; + QWeakPointer m_mainItem; + DeclarativeItemContainer *m_declarativeItemContainer; + QGraphicsScene *m_scene; + QWeakPointer m_rootObject; + static uint s_numItems; + Background *m_background; + + //those only used in case of error, to not make plasma crash + QList m_dummyTitleElements; + QList m_dummyContentElements; + QList m_dummyButtonsElements; +}; + +#endif diff --git a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp index 615cfe845..ca75c2443 100644 --- a/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp @@ -34,6 +34,7 @@ #include "qmenuitem.h" #include "kdialogproxy.h" #include "fullscreendialog.h" +#include "fullscreensheet.h" Q_EXPORT_PLUGIN2(plasmacomponentsplugin, PlasmaComponentsPlugin) @@ -100,6 +101,7 @@ void PlasmaComponentsPlugin::registerTypes(const char *uri) //on touch systems the dialog is fullscreen, c++ needed to do that } else { qmlRegisterType(uri, 0, 1, "Dialog"); + qmlRegisterType(uri, 0, 1, "Sheet"); } qmlRegisterType(uri, 0, 1, "RangeModel"); diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/Sheet.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/Sheet.qml index cbc7a50db..c988996e0 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/Sheet.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/Sheet.qml @@ -47,18 +47,22 @@ import "." 0.1 Item { id: root - width: dialog.width - height: dialog.height + width: 600 + height: 200 + onHeightChanged:print(height) property alias title: titleBar.children property alias content: contentItem.children - property alias buttons: buttonItem.children // property alias visualParent: dialog.visualParent property int status: DialogStatus.Closed + property alias acceptButtonText: acceptButton.text + property alias rejectButtonText: rejectButton.text + property alias acceptButton: acceptButton + property alias rejectButton: rejectButton property alias privateTitleHeight: titleBar.height - property alias privateButtonsHeight: buttonItem.height + property alias privateButtonsHeight: buttonsRow.height signal accepted signal rejected @@ -110,9 +114,7 @@ Item { PlasmaCore.FrameSvgItem { id: dialog - width: mainItem.width + margins.left + margins.right - height: mainItem.height + margins.top + margins.bottom - anchors.centerIn: parent + anchors.fill: parent imagePath: "dialogs/background" state: "closed" @@ -123,9 +125,8 @@ Item { id: mainItem x: dialog.margins.left y: dialog.margins.top - width: theme.defaultFont.mSize.width * 40 - height: titleBar.childrenRect.height + contentItem.childrenRect.height + buttonItem.childrenRect.height + 8 - + width: parent.width - dialog.margins.left - dialog.margins.right + height: parent.height - dialog.margins.top - dialog.margins.bottom // Consume all key events that are not processed by children Keys.onPressed: event.accepted = true @@ -146,24 +147,33 @@ Item { id: contentItem clip: true - onChildrenRectChanged: mainItem.width = Math.max(childrenRect.width, buttonItem.childrenRect.width) + onChildrenRectChanged: mainItem.width = Math.max(childrenRect.width, buttonsRow.childrenRect.width) anchors { top: titleBar.bottom left: parent.left right: parent.right - bottom: buttonItem.top + bottom: buttonsRow.top } } - Item { - id: buttonItem - - height: childrenRect.height + Row { + id: buttonsRow + spacing: 8 anchors { - left: parent.left - right: parent.right bottom: parent.bottom - bottomMargin: 8 + horizontalCenter: parent.horizontalCenter + //the bottom margin is disabled but we want it anyways + bottomMargin: theme.defaultFont.mSize.height*0.6 + } + + Button { + id: acceptButton + onClicked: accept() + } + + Button { + id: rejectButton + onClicked: reject() } } } diff --git a/declarativeimports/plasmacomponents/qml/Sheet.qml b/declarativeimports/plasmacomponents/qml/Sheet.qml index 76bf53d43..8ce6e94c8 100644 --- a/declarativeimports/plasmacomponents/qml/Sheet.qml +++ b/declarativeimports/plasmacomponents/qml/Sheet.qml @@ -111,13 +111,16 @@ Item { property alias title: titleBar.children property alias content: contentItem.children - property alias buttons: buttonItem.children // property alias visualParent: dialog.visualParent property int status: DialogStatus.Closed + property alias acceptButtonText: acceptButton.text + property alias rejectButtonText: rejectButton.text + property alias acceptButton: acceptButton + property alias rejectButton: rejectButton property alias privateTitleHeight: titleBar.height - property alias privateButtonsHeight: buttonItem.height + property alias privateButtonsHeight: buttonsRow.height signal accepted signal rejected @@ -175,7 +178,7 @@ Item { mainItem: Item { id: mainItem width: theme.defaultFont.mSize.width * 40 - height: titleBar.childrenRect.height + contentItem.childrenRect.height + buttonItem.childrenRect.height + 8 + height: titleBar.childrenRect.height + contentItem.childrenRect.height + buttonsRow.childrenRect.height + 8 // Consume all key events that are not processed by children Keys.onPressed: event.accepted = true @@ -195,27 +198,36 @@ Item { Item { id: contentItem - onChildrenRectChanged: mainItem.width = Math.max(childrenRect.width, buttonItem.childrenRect.width) + onChildrenRectChanged: mainItem.width = Math.max(childrenRect.width, buttonsRow.childrenRect.width) clip: true anchors { top: titleBar.bottom left: parent.left right: parent.right - bottom: buttonItem.top + bottom: buttonsRow.top bottomMargin: 8 } } - Item { - id: buttonItem - - height: childrenRect.height + Row { + id: buttonsRow + spacing: 8 anchors { - left: parent.left - right: parent.right bottom: parent.bottom - bottomMargin: 4 + horizontalCenter: parent.horizontalCenter + //the bottom margin is disabled but we want it anyways + bottomMargin: theme.defaultFont.mSize.height*0.6 + } + + Button { + id: acceptButton + onClicked: accept() + } + + Button { + id: rejectButton + onClicked: reject() } } }