From 790c6e39b60983ad3084f1edb92cd8a95bdd3545 Mon Sep 17 00:00:00 2001 From: Patrick von Reth Date: Wed, 2 Jul 2014 18:54:05 +0200 Subject: [PATCH] rewrote snore backend with qml --- CMakeLists.txt | 1 + src/plugins/backends/snore/CMakeLists.txt | 12 +- src/plugins/backends/snore/DpiScaler.cpp | 200 ----------------- src/plugins/backends/snore/DpiScaler.h | 75 ------- src/plugins/backends/snore/notification.qml | 109 +++++++++ src/plugins/backends/snore/notifywidget.cpp | 75 +++---- src/plugins/backends/snore/notifywidget.h | 21 +- src/plugins/backends/snore/notifywidget.ui | 206 ------------------ .../backends/snore/resources/close.png | Bin 0 -> 725 bytes src/plugins/backends/snore/snore.qrc | 6 + 10 files changed, 163 insertions(+), 542 deletions(-) delete mode 100644 src/plugins/backends/snore/DpiScaler.cpp delete mode 100644 src/plugins/backends/snore/DpiScaler.h create mode 100644 src/plugins/backends/snore/notification.qml delete mode 100644 src/plugins/backends/snore/notifywidget.ui create mode 100644 src/plugins/backends/snore/resources/close.png create mode 100644 src/plugins/backends/snore/snore.qrc diff --git a/CMakeLists.txt b/CMakeLists.txt index 91485c1..0cfade3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ else() find_package(Qt5Widgets REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5DBus QUIET) + find_package(Qt5Declarative QUIET) include(ECMQt4To5Porting) set(SNORE_SUFFIX "-qt5") set(SNORE_CamelCase_SUFFIX "Qt5") diff --git a/src/plugins/backends/snore/CMakeLists.txt b/src/plugins/backends/snore/CMakeLists.txt index be73423..60341e0 100644 --- a/src/plugins/backends/snore/CMakeLists.txt +++ b/src/plugins/backends/snore/CMakeLists.txt @@ -1,16 +1,14 @@ +QT4_ADD_RESOURCES(SNORE_RCS ${CMAKE_CURRENT_SOURCE_DIR}/snore.qrc) + set( SNORE_SRC snorenotifier.cpp notifywidget.cpp - DpiScaler.cpp + ${SNORE_RCS} ) -set( SNORE_FORMS - notifywidget.ui) -qt4_wrap_ui(SNORE_UI ${SNORE_FORMS}) - -add_library(libsnore_backend_snore MODULE ${SNORE_SRC} ${SNORE_UI} ) -target_link_libraries(libsnore_backend_snore snorecore ${QT_QTCORE_LIBRARY} ) +add_library(libsnore_backend_snore MODULE ${SNORE_SRC} ) +target_link_libraries(libsnore_backend_snore snorecore ${QT_QTCORE_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) install(TARGETS libsnore_backend_snore ${SNORE_PLUGIN_INSTALL_PATH}) diff --git a/src/plugins/backends/snore/DpiScaler.cpp b/src/plugins/backends/snore/DpiScaler.cpp deleted file mode 100644 index 8b52865..0000000 --- a/src/plugins/backends/snore/DpiScaler.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2013, Teo Mrnjavac - * - * Tomahawk 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 3 of the License, or - * (at your option) any later version. - * - * Tomahawk 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 Tomahawk. If not, see . - */ - -#include "DpiScaler.h" -#include -#include - - -namespace TomahawkUtils -{ -int DpiScaler::s_fontSize = 0; -#ifdef Q_OS_MAC - const qreal DpiScaler::s_baseDpi = 72.; -#else - const qreal DpiScaler::s_baseDpi = 96.; -#endif - -DpiScaler::DpiScaler( const QPaintDevice* that ) - : that( that ) -{ - m_ratioX = ratioX( that ); - m_ratioY = ratioY( that ); -} - - -QSize -DpiScaler::scaled( int w, int h ) const -{ - return QSize( scaledX( w ), scaledY( h ) ); -} - - -QSize -DpiScaler::scaled( const QSize& size ) const -{ - return scaled( size.width(), size.height() ); -} - - -QMargins -DpiScaler::scaled( int left, int top, int right, int bottom ) const -{ - return QMargins( scaledX( left ), - scaledY( top ), - scaledX( right ), - scaledY( bottom ) ); -} - - -QMargins -DpiScaler::scaled( const QMargins& margins ) const -{ - return scaled( margins.left(), - margins.top(), - margins.right(), - margins.bottom() ); -} - - -int -DpiScaler::scaledX( int x ) const -{ - return qRound( x * m_ratioX ); -} - - -int -DpiScaler::scaledY( int y ) const -{ - return qRound( y * m_ratioY ); -} - -// static methods start here - -QSize -DpiScaler::scaled( const QPaintDevice* pd, int w, int h ) -{ - return QSize( scaledX( pd, w ), scaledY( pd, h ) ); -} - - -QSize -DpiScaler::scaled( const QPaintDevice* pd, const QSize& size ) -{ - return scaled( pd, size.width(), size.height() ); -} - - -QMargins -DpiScaler::scaled( const QPaintDevice* pd, int left, int top, int right, int bottom ) -{ - return QMargins( scaledX( pd, left ), - scaledY( pd, top ), - scaledX( pd, right ), - scaledY( pd, bottom ) ); -} - - -QMargins -DpiScaler::scaled( const QPaintDevice* pd, const QMargins& margins ) -{ - return scaled( pd, - margins.left(), - margins.top(), - margins.right(), - margins.bottom() ); -} - - -int -DpiScaler::scaledX( const QPaintDevice* pd, int x ) -{ - return qRound( x * ratioX( pd ) ); -} - - -int -DpiScaler::scaledY( const QPaintDevice* pd, int y ) -{ - return qRound( y * ratioY( pd ) ); -} -int DpiScaler::getFontSize() -{ - return s_fontSize; -} - -void DpiScaler::setFontSize(int value) -{ - s_fontSize = value; -} - - - -qreal -DpiScaler::ratioX( const QPaintDevice* pd ) -{ - qreal ratioFromFH = ratioFromFontHeight(); - qreal ratioYFromDpi = pd->logicalDpiY() / s_baseDpi; //using Y because we compare with height - - //if the error is less than 1%, we trust that the logical DPI setting has the best value - if ( qAbs( ratioFromFH / ratioYFromDpi - 1 ) < 0.01 ) - return pd->logicalDpiX() / s_baseDpi; - else - return ratioFromFH; -} - - -qreal -DpiScaler::ratioY( const QPaintDevice* pd ) -{ - qreal ratioFromFH = ratioFromFontHeight(); - qreal ratioYFromDpi = pd->logicalDpiY() / s_baseDpi; //using Y because we compare with height - - //if the error is less than 1%, we trust that the logical DPI setting has the best value - if ( qAbs( ratioFromFH / ratioYFromDpi - 1 ) < 0.01 ) - return ratioYFromDpi; - else - return ratioFromFH; -} - - -qreal -DpiScaler::ratioFromFontHeight() -{ - int fS = s_fontSize; - QFont f; - f.setPointSize( fS ); - int fH = QFontMetrics( f ).ascent() + 1; //a font's em-height should be ascent + 1px (baseline) - - qreal basePpp = s_baseDpi / 72.; //72*(1.333)=96 dpi - -#ifdef Q_OS_MAC - const int baseFontSize = 13; -#else - const int baseFontSize = 8; -#endif - - qreal baseFontHeight = baseFontSize * basePpp; //we assume a minimum font size of 7pt - - qreal ratioFromFontHeights = qMax( fH / baseFontHeight, 1. ); - return ratioFromFontHeights; -} - - -} diff --git a/src/plugins/backends/snore/DpiScaler.h b/src/plugins/backends/snore/DpiScaler.h deleted file mode 100644 index bb50706..0000000 --- a/src/plugins/backends/snore/DpiScaler.h +++ /dev/null @@ -1,75 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2013, Teo Mrnjavac - * - * Tomahawk 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 3 of the License, or - * (at your option) any later version. - * - * Tomahawk 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 Tomahawk. If not, see . - */ - -#ifndef DPISCALER_H -#define DPISCALER_H - - -#include -#include -#include - -namespace TomahawkUtils -{ - -/** - * @brief The DpiScaler class provides some convenience methods to recompute fixed pixel sizes - * into values suitable for different environment DPI settings. - * Usage: - * class Foo : public QWidget, private TomahawkUtils::DpiScaler {...}; - */ -class DpiScaler -{ -public: - DpiScaler( const QPaintDevice* that ); - - QSize scaled( int w, int h ) const; - QSize scaled( const QSize& size ) const; - QMargins scaled( int left, int top, int right, int bottom ) const; - QMargins scaled( const QMargins& margins ) const; - int scaledX( int x ) const; - int scaledY( int y ) const; - - // convenience one-shot methods, usable without composing or private-inheriting DpiScaler - static QSize scaled( const QPaintDevice* pd, int w, int h ); - static QSize scaled( const QPaintDevice* pd, const QSize& size ); - static QMargins scaled( const QPaintDevice* pd, int left, int top, int right, int bottom ); - static QMargins scaled( const QPaintDevice* pd, const QMargins& margins ); - static int scaledX( const QPaintDevice* pd, int x ); - static int scaledY( const QPaintDevice* pd, int y ); - - static int getFontSize(); - static void setFontSize(int value); - -private: - static int s_fontSize; - inline static qreal ratioX( const QPaintDevice* pd ); - inline static qreal ratioY( const QPaintDevice* pd ); - inline static qreal ratioFromFontHeight(); - - qreal m_ratioX; - qreal m_ratioY; - - const QPaintDevice* that; - - static const qreal s_baseDpi; -}; - -} - -#endif // DPISCALER_H diff --git a/src/plugins/backends/snore/notification.qml b/src/plugins/backends/snore/notification.qml new file mode 100644 index 0000000..f190966 --- /dev/null +++ b/src/plugins/backends/snore/notification.qml @@ -0,0 +1,109 @@ +import QtQuick 1.1 + + + + +Rectangle { + objectName: "qmlNotification" + id: root + width: 365 + height: 100 + clip: true + + signal dismissed() + + signal linkClicked(string link) + + signal invoked() + + + + function update(nTitle, bBody, nImage, nAppIcon, color) + { + title.text = nTitle + body.text = bBody + appIcon.source = nAppIcon + image.source = nImage + root.color = color + } + + + + + + MouseArea { + id: mouseArea2 + anchors.fill: parent + z: -1 + onClicked: root.invoked() + } + + Text { + id: title + x: 106 + y: 3 + width: 217 + height: 14 + color: "#ffffff" + + text: qsTr("Title") + wrapMode: Text.WordWrap + font.pixelSize: 12 + } + + Text { + id: body + x: 106 + y: 23 + width: 217 + height: 69 + color: "#ffffff" + text: qsTr("Body") + wrapMode: Text.WordWrap + font.pixelSize: 12 + onLinkActivated: root.linkClicked(link) + + } + + + Image { + id: image + width: 100 + height: 100 + z: 4 + fillMode: Image.PreserveAspectFit + source: "qrc:/root/images/freedesktop-dbus.png" + } + + Image { + id: appIcon + x: 329 + y: 62 + width: 30 + height: 30 + fillMode: Image.PreserveAspectFit + source: "qrc:/root/snore.png" + } + + Image { + id: closeButton + x: 345 + y: 0 + width: 20 + height: 20 + fillMode: Image.PreserveAspectFit + z: 3 + source: "qrc:/resources/close.png" + + MouseArea { + id: mouseArea1 + anchors.fill: parent + onClicked: root.dismissed() + } + } + + + + + +} diff --git a/src/plugins/backends/snore/notifywidget.cpp b/src/plugins/backends/snore/notifywidget.cpp index bff06f7..125aafc 100644 --- a/src/plugins/backends/snore/notifywidget.cpp +++ b/src/plugins/backends/snore/notifywidget.cpp @@ -18,28 +18,31 @@ */ #include "notifywidget.h" -#include "ui_notifywidget.h" #include "core/log.h" #include +#include #include +#include +#include +#include using namespace Snore; NotifyWidget::NotifyWidget(int pos,QWidget *parent) : - QWidget(parent, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint - #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - | Qt::WindowDoesNotAcceptFocus - #endif - ), - ui(new Ui::NotifyWidget), + QDeclarativeView(QUrl("qrc:/notification.qml"), parent), m_moveTimer(new QTimer(this)), m_desktop(QDesktopWidget().availableGeometry()), m_id(pos), m_mem(QString("SnoreNotifyWidget%1").arg(QString::number(m_id))), m_ready(true) { - ui->setupUi(this); + qmlNotification = rootObject(); + this->setWindowFlags(Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint + #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + | Qt::WindowDoesNotAcceptFocus + #endif + ); if(m_mem.create(sizeof(SHARED_MEM_TYPE))) { m_mem.lock(); @@ -59,24 +62,26 @@ NotifyWidget::NotifyWidget(int pos,QWidget *parent) : snoreDebug( SNORE_DEBUG ) << "Status" << *data; } - TomahawkUtils::DpiScaler::setFontSize(10); - m_scaler = new TomahawkUtils::DpiScaler(this); - ui->closeButton->setMaximumWidth(ui->closeButton->height()); - setFixedSize( m_scaler->scaled(300, 80)); - m_dest = QPoint(m_desktop.topRight().x() - width(), m_desktop.topRight().y() + m_scaler->scaledY(10) + (m_scaler->scaledY(10) + height()) * pos); + + m_dest = QPoint(m_desktop.topRight().x() - width(), m_desktop.topRight().y() + 10 + 10 + height() * pos); m_start = QPoint(m_desktop.topRight().x(), m_dest.y()); snoreDebug( SNORE_DEBUG ) << m_dest << m_start << size(); + + + m_moveTimer->setInterval(1); connect( m_moveTimer, SIGNAL(timeout()), this, SLOT(slotMove())); + + connect(qmlNotification, SIGNAL(invoked()),this, SLOT(slotInvoked())); + connect(qmlNotification, SIGNAL(dismissed()),this, SLOT(slotDismissed())); + connect(qmlNotification, SIGNAL(linkClicked(QString)),this, SLOT(slotLinkClicked(QString))); } NotifyWidget::~NotifyWidget() { - delete m_scaler; - delete ui; } void NotifyWidget::display(const Notification ¬ification) @@ -92,17 +97,14 @@ void NotifyWidget::display(const Notification ¬ification) void NotifyWidget::update(const Notification ¬ification) { m_notification = notification; - ui->titel->setText(notification.title()); - ui->body->setText(notification.text()); - ui->body->setFixedHeight((m_scaler->scaledY(40) / ui->body->fontInfo().pointSize()) * ui->body->fontInfo().pointSize());//round it by line height + QMetaObject::invokeMethod(qmlNotification, "update", Qt::QueuedConnection, + Q_ARG( QVariant, notification.title()), + Q_ARG( QVariant, notification.text()), + Q_ARG( QVariant, QUrl::fromLocalFile(notification.icon().localUrl())), + Q_ARG( QVariant, QUrl::fromLocalFile(notification.application().icon().localUrl())), + Q_ARG( QVariant, computeBackgrondColor(notification.application().icon().image()))); - QSize iconSize = m_scaler->scaled(65,65); - ui->icon->setPixmap(QPixmap::fromImage(notification.icon().image().scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation))); - iconSize = m_scaler->scaled(20,20); - QImage img = notification.application().icon().image().scaled(iconSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); - ui->appIcon->setPixmap(QPixmap::fromImage(img)); - setPalette(img); } bool NotifyWidget::acquire() @@ -164,17 +166,17 @@ void NotifyWidget::slotMove() } } -void NotifyWidget::on_closeButton_clicked() +void NotifyWidget::slotDismissed() { emit dismissed(); } -void NotifyWidget::mousePressEvent(QMouseEvent *) +void NotifyWidget::slotInvoked() { emit invoked(); } -void NotifyWidget::setPalette(const QImage &img) +QColor NotifyWidget::computeBackgrondColor(const QImage &img) { qulonglong r = 0; qulonglong g = 0; @@ -191,22 +193,11 @@ void NotifyWidget::setPalette(const QImage &img) } int s = img.width()*img.height(); - QPalette p = palette(); - QColor bg = QColor(r/s, g/s, b/s); - p.setColor(QPalette::All, QPalette::Window, bg); - p.setColor(QPalette::All, QPalette::Background, bg); - p.setColor(QPalette::All, QPalette::Base, bg); - p.setColor(QPalette::All, QPalette::Text, Qt::white); - p.setColor(QPalette::All, QPalette::BrightText, Qt::white); - p.setColor(QPalette::All, QPalette::ButtonText, Qt::white); - p.setColor(QPalette::All, QPalette::WindowText, Qt::white); - QWidget::setPalette(p); - ui->closeButton->setPalette(p); - ui->body->setPalette(p); - ui->titel->setPalette(p); + return QColor(r/s, g/s, b/s); + } -void NotifyWidget::on_body_linkActivated(const QString &link) +void NotifyWidget::slotLinkClicked(QString link) { - snoreDebug( SNORE_DEBUG ) << link; + QDesktopServices::openUrl( QUrl(link)); } diff --git a/src/plugins/backends/snore/notifywidget.h b/src/plugins/backends/snore/notifywidget.h index 8284462..4a96dfe 100644 --- a/src/plugins/backends/snore/notifywidget.h +++ b/src/plugins/backends/snore/notifywidget.h @@ -24,14 +24,12 @@ #include #include #include "core/notification/notification.h" -#include "DpiScaler.h" -namespace Ui { -class NotifyWidget; -} +#include + typedef bool SHARED_MEM_TYPE; -class NotifyWidget : public QWidget +class NotifyWidget : public QDeclarativeView { Q_OBJECT @@ -58,27 +56,26 @@ signals: private slots: void slotMove(); - void on_closeButton_clicked(); + void slotDismissed(); - void on_body_linkActivated(const QString &link); + void slotInvoked(); -protected: - void mousePressEvent(QMouseEvent *e); + void slotLinkClicked(QString link); private: - void setPalette(const QImage &img); - Ui::NotifyWidget *ui; + QColor computeBackgrondColor(const QImage &img); QTimer *m_moveTimer; QPoint m_dest; QPoint m_start; int m_dist; QRect m_desktop; - TomahawkUtils::DpiScaler *m_scaler; Snore::Notification m_notification; + QObject *qmlNotification; + int m_id; QSharedMemory m_mem; bool m_ready; diff --git a/src/plugins/backends/snore/notifywidget.ui b/src/plugins/backends/snore/notifywidget.ui deleted file mode 100644 index 80cc47a..0000000 --- a/src/plugins/backends/snore/notifywidget.ui +++ /dev/null @@ -1,206 +0,0 @@ - - - NotifyWidget - - - - 0 - 0 - 359 - 175 - - - - - 0 - 0 - - - - true - - - Form - - - - :/root/snore.png:/root/snore.png - - - - 6 - - - QLayout::SetDefaultConstraint - - - - - - - - - - 0 - 0 - - - - appIcon - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Icon - - - - - - - 0 - - - QLayout::SetFixedSize - - - - - 0 - - - QLayout::SetMinimumSize - - - - - - 0 - 0 - - - - - 10 - 75 - true - true - - - - TextLabel - - - false - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - 0 - - - - - - - - 0 - 0 - - - - - 75 - true - - - - Qt::NoFocus - - - X - - - - - - true - - - - - - - - - - 0 - 0 - - - - - 10 - - - - <i>This is Snore</i><br><a href="https://github.com/TheOneRing/Snorenotify">Project Website</a><br>1<br>2<br>3<br>4<br>5<br> - - - Qt::RichText - - - false - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - 0 - - - 0 - - - true - - - - - - - - - - - - - - diff --git a/src/plugins/backends/snore/resources/close.png b/src/plugins/backends/snore/resources/close.png new file mode 100644 index 0000000000000000000000000000000000000000..621f024a9cf64717e3a05a8ab60c8ddd1d23537d GIT binary patch literal 725 zcmV;`0xJE9P)G32E4H&ZpU=%RAB$PQ zEMOKu{^QMNv-CgO zO+w74<>p7~0)yb!NBF9B)?HvKKmUH0C14_WDH0y$Hzi?G00G`w0y)2X67C9Mz*|XR z=Qk!{R6qi}wuI#Th7#Ne{4Ozg6F;{v6#g>dq+;VS-QB#4xd1K&ihp3((E#rNgU zRYqgd-9Z9=?YqE<`cJSV2@rV7Fj#^F7(BHQl92EjC7eov=aj+{68@55NPxq$Zikg6 zsKBSr2cRXW!6(fKfhDNICkX&bP=`+z0Fdx*0iPv6P(nz0X#t-tKv04S{Joo@lq9;1!zhTgO?VdAwd)#Apj{s93CYAApru96mXHS6^gY*z@r6(`rsfG z>yTM2sSA)Uj#e?=vIYUD$`B&KRRRx_;3|TLNN|=A-VxDin31}T_?u~N7#5dLz{kUP=3Y6gq2HSQG6`6k@#6s>iy zaEb)_Uf~1@n(!$S_`Ag!5-i|364IX+AV{!;r$~7C#0Y6ZBnIiZ!8MLJq>YUZr2HJC zp=$|6z)wi{rsn6E4TYdxN$?{Q-WtZ5 + + notification.qml + resources/close.png + +