From 76fe517541453c7eecd2c9bb4e39e66bad3111a3 Mon Sep 17 00:00:00 2001 From: laserpants Date: Tue, 21 Jun 2016 12:18:51 +0300 Subject: [PATCH] implement Dialog window --- components/dialog.cpp | 114 +++++++++++++++-------------- components/dialog.h | 5 +- components/dialog_internal.cpp | 18 ++++- components/dialog_internal.h | 14 +++- components/dialog_p.h | 8 +- lib/transparencyproxy.cpp | 15 ++++ lib/transparencyproxy.h | 6 ++ lib/transparencyproxy_internal.cpp | 18 +++-- mainwindow.cpp | 18 +++++ 9 files changed, 146 insertions(+), 70 deletions(-) diff --git a/components/dialog.cpp b/components/dialog.cpp index e707391..f770713 100644 --- a/components/dialog.cpp +++ b/components/dialog.cpp @@ -1,6 +1,10 @@ #include "dialog.h" #include "dialog_p.h" #include +#include +#include +#include +#include #include #include #include @@ -8,7 +12,10 @@ #include "dialog_internal.h" DialogPrivate::DialogPrivate(Dialog *q) - : q_ptr(q) + : q_ptr(q), + machine(new QStateMachine(q)), + window(new DialogWindow(q)), + proxy(new TransparencyProxy) { } @@ -21,15 +28,12 @@ void DialogPrivate::init() QWidget *widget = new QWidget; - proxy = new TransparencyProxy; widget->setLayout(proxy); layout->addWidget(widget); layout->setAlignment(widget, Qt::AlignCenter); widget->setMinimumWidth(400); - widget->setMinimumHeight(400); - window = new DialogWindow(q); proxy->setWidget(window); QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect; @@ -38,54 +42,55 @@ void DialogPrivate::init() effect->setOffset(0, 13); widget->setGraphicsEffect(effect); -/* - { - QVBoxLayout *layout = new QVBoxLayout; - window->setLayout(layout); - - QPushButton *button = new QPushButton; - button->setText("Hello test!"); - layout->addWidget(button); - - button = new QPushButton; - button->setText("Hello test!"); - layout->addWidget(button); - - button = new QPushButton; - button->setText("Hello test!"); - layout->addWidget(button); - - button = new QPushButton; - button->setText("Hello test!"); - layout->addWidget(button); - - button = new QPushButton; - button->setText("Hello test!"); - layout->addWidget(button); - } - */ - // - proxy->setCurrentIndex(1); + QState *hiddenState = new QState; + QState *visibleState = new QState; - // + machine->addState(hiddenState); + machine->addState(visibleState); + machine->setInitialState(hiddenState); + QSignalTransition *transition; - QPushButton *btn; + transition = new QSignalTransition(window, SIGNAL(dialogActivated())); + transition->setTargetState(visibleState); + hiddenState->addTransition(transition); - btn = new QPushButton; - btn->setText("One"); - layout->addWidget(btn); + transition = new QSignalTransition(window, SIGNAL(dialogDeactivated())); + transition->setTargetState(hiddenState); + visibleState->addTransition(transition); - QObject::connect(btn, SIGNAL(pressed()), q, SLOT(pressOne())); + visibleState->assignProperty(proxy, "opacity", 1); + visibleState->assignProperty(effect, "color", QColor(0, 0, 0, 200)); + visibleState->assignProperty(window, "offset", 0); + hiddenState->assignProperty(proxy, "opacity", 0); + hiddenState->assignProperty(effect, "color", QColor(0, 0, 0, 0)); + hiddenState->assignProperty(window, "offset", 200); - btn = new QPushButton; - btn->setText("Two"); - layout->addWidget(btn); + QObject::connect(proxy, SIGNAL(opacityChanged()), q, SLOT(update())); - QObject::connect(btn, SIGNAL(pressed()), q, SLOT(pressTwo())); + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(proxy, "opacity"); + animation->setDuration(280); + machine->addDefaultAnimation(animation); + + animation = new QPropertyAnimation(effect, "color"); + animation->setDuration(280); + machine->addDefaultAnimation(animation); + + animation = new QPropertyAnimation(window, "offset"); + animation->setDuration(280); + animation->setEasingCurve(QEasingCurve::OutCirc); + machine->addDefaultAnimation(animation); + + QObject::connect(visibleState, SIGNAL(propertiesAssigned()), q, SLOT(acceptMouseEvents())); + + machine->start(); + + QCoreApplication::processEvents(); } Dialog::Dialog(QWidget *parent) @@ -113,18 +118,24 @@ void Dialog::setWindowLayout(QLayout *layout) d->window->setLayout(layout); } -void Dialog::pressOne() +void Dialog::showDialog() { Q_D(Dialog); - d->proxy->setOpaque(); + emit d->window->dialogActivated(); } -void Dialog::pressTwo() +void Dialog::hideDialog() { Q_D(Dialog); - d->proxy->setOpacity(0.5); + emit d->window->dialogDeactivated(); + setAttribute(Qt::WA_TransparentForMouseEvents); +} + +void Dialog::acceptMouseEvents() +{ + setAttribute(Qt::WA_TransparentForMouseEvents, false); } bool Dialog::event(QEvent *event) @@ -176,21 +187,16 @@ void Dialog::paintEvent(QPaintEvent *event) { Q_UNUSED(event) + Q_D(Dialog); + QPainter painter(this); - //QPen pen; - //pen.setColor(Qt::blue); - //pen.setWidth(3); - //painter.setPen(pen); - - //painter.drawRect(rect()); - QBrush brush; brush.setStyle(Qt::SolidPattern); brush.setColor(Qt::black); painter.setBrush(brush); painter.setPen(Qt::NoPen); - painter.setOpacity(0.5); + painter.setOpacity(d->proxy->opacity()/2); painter.drawRect(rect()); } diff --git a/components/dialog.h b/components/dialog.h index 2deecf6..e7d6180 100644 --- a/components/dialog.h +++ b/components/dialog.h @@ -17,8 +17,9 @@ public: void setWindowLayout(QLayout *layout); protected slots: - void pressOne(); - void pressTwo(); + void showDialog(); + void hideDialog(); + void acceptMouseEvents(); protected: bool event(QEvent *event) Q_DECL_OVERRIDE; diff --git a/components/dialog_internal.cpp b/components/dialog_internal.cpp index 0dc812a..ff77208 100644 --- a/components/dialog_internal.cpp +++ b/components/dialog_internal.cpp @@ -1,9 +1,11 @@ #include "dialog_internal.h" #include +#include #include "dialog.h" -DialogWindow::DialogWindow(QWidget *parent) - : QWidget(parent) +DialogWindow::DialogWindow(Dialog *dialog, QWidget *parent) + : QWidget(parent), + dialog(dialog) { } @@ -11,6 +13,18 @@ DialogWindow::~DialogWindow() { } +void DialogWindow::setOffset(int offset) +{ + QMargins margins = dialog->layout()->contentsMargins(); + margins.setBottom(offset); + dialog->layout()->setContentsMargins(margins); +} + +int DialogWindow::offset() const +{ + return dialog->layout()->contentsMargins().bottom(); +} + void DialogWindow::paintEvent(QPaintEvent *event) { Q_UNUSED(event) diff --git a/components/dialog_internal.h b/components/dialog_internal.h index 513d7cd..dab279d 100644 --- a/components/dialog_internal.h +++ b/components/dialog_internal.h @@ -3,21 +3,33 @@ #include +class QStateMachine; class Dialog; class DialogWindow : public QWidget { Q_OBJECT + Q_PROPERTY(int offset WRITE setOffset READ offset) + public: - DialogWindow(QWidget *parent = 0); + explicit DialogWindow(Dialog *dialog, QWidget *parent = 0); ~DialogWindow(); + void setOffset(int offset); + int offset() const; + +signals: + void dialogActivated(); + void dialogDeactivated(); + protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; private: Q_DISABLE_COPY(DialogWindow) + + Dialog *const dialog; }; //#include diff --git a/components/dialog_p.h b/components/dialog_p.h index 0efd03a..1d7c102 100644 --- a/components/dialog_p.h +++ b/components/dialog_p.h @@ -3,6 +3,7 @@ #include +class QStateMachine; class Dialog; class DialogWindow; class TransparencyProxy; @@ -17,9 +18,10 @@ public: void init(); - Dialog *const q_ptr; - DialogWindow *window; - TransparencyProxy *proxy; + Dialog *const q_ptr; + QStateMachine *const machine; + DialogWindow *const window; + TransparencyProxy *const proxy; }; #endif // DIALOG_P_H diff --git a/lib/transparencyproxy.cpp b/lib/transparencyproxy.cpp index 562830f..9510093 100644 --- a/lib/transparencyproxy.cpp +++ b/lib/transparencyproxy.cpp @@ -61,6 +61,8 @@ void TransparencyProxy::setOpaque() d->proxy->setOpacity(1); setCurrentIndex(0); + + emit opacityChanged(); } void TransparencyProxy::setOpacity(qreal opacity) @@ -71,6 +73,19 @@ void TransparencyProxy::setOpacity(qreal opacity) return; } + if (1 == opacity) { + return setOpaque(); + } + d->proxy->setOpacity(opacity); setCurrentIndex(1); + + emit opacityChanged(); +} + +qreal TransparencyProxy::opacity() const +{ + Q_D(const TransparencyProxy); + + return d->proxy->opacity(); } diff --git a/lib/transparencyproxy.h b/lib/transparencyproxy.h index e7e6a49..475b240 100644 --- a/lib/transparencyproxy.h +++ b/lib/transparencyproxy.h @@ -10,6 +10,8 @@ class TransparencyProxy : public QStackedLayout { Q_OBJECT + Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity NOTIFY opacityChanged) + public: TransparencyProxy(); ~TransparencyProxy(); @@ -18,6 +20,10 @@ public: void setOpaque(); void setOpacity(qreal opacity); + qreal opacity() const; + +signals: + void opacityChanged(); protected: const QScopedPointer d_ptr; diff --git a/lib/transparencyproxy_internal.cpp b/lib/transparencyproxy_internal.cpp index 26568a7..95c8289 100644 --- a/lib/transparencyproxy_internal.cpp +++ b/lib/transparencyproxy_internal.cpp @@ -4,7 +4,7 @@ ProxyWidget::ProxyWidget(QWidget *widget, QWidget *parent) : QWidget(parent), _widget(widget), - _opacity(1.0) + _opacity(0) { } @@ -18,15 +18,17 @@ void ProxyWidget::paintEvent(QPaintEvent *event) QPainter painter(this); - //QPen pen; - //pen.setColor(Qt::red); - //pen.setWidth(5); - //painter.setPen(pen); - - //painter.drawRect(rect()); - painter.setOpacity(_opacity); QPixmap pixmap = _widget->grab(rect()); painter.drawPixmap(rect(), pixmap); + +#ifdef DEBUG_LAYOUT + QPen pen; + pen.setColor(Qt::red); + pen.setWidth(5); + painter.setPen(pen); + + painter.drawRect(rect()); +#endif } diff --git a/mainwindow.cpp b/mainwindow.cpp index a1eb59e..2f28a75 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -98,6 +98,24 @@ MainWindow::MainWindow(QWidget *parent) layout->addWidget(btn); layout->addWidget(btn2); + + { + QPushButton *btn; + + btn = new QPushButton; + btn->setParent(this); + btn->setText("Show"); + btn->setGeometry(190, 80, 140, 40); + + QObject::connect(btn, SIGNAL(pressed()), dialog, SLOT(showDialog())); + + btn = new QPushButton; + btn->setParent(this); + btn->setText("Hide"); + btn->setGeometry(370, 80, 140, 40); + + QObject::connect(btn, SIGNAL(pressed()), dialog, SLOT(hideDialog())); + } } }