From a644a7cc6749f8dd5ca20589ee6e59acc2892b3e Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Tue, 27 Sep 2011 04:51:30 +0200 Subject: new qmafw watchlet --- libsowatch/declarativewatchlet.cpp | 27 ++++++++++++++++++--- libsowatch/declarativewatchlet.h | 10 +++++--- libsowatch/declarativewatchwrapper.cpp | 10 ++++++-- libsowatch/declarativewatchwrapper.h | 3 +++ libsowatch/graphicswatchlet.cpp | 44 ++++++++++++++++++++++++++-------- libsowatch/graphicswatchlet.h | 15 ++++++++++-- libsowatch/libsowatch.pro | 4 ++-- libsowatch/testwatchlet.cpp | 40 ------------------------------- libsowatch/testwatchlet.h | 29 ---------------------- libsowatch/watch.cpp | 5 ++++ libsowatch/watch.h | 20 +++++++++------- libsowatch/watchlet.cpp | 5 ++++ libsowatch/watchlet.h | 3 ++- libsowatch/watchserver.cpp | 14 ++++++----- libsowatch/watchserver.h | 23 +++++++++++++----- 15 files changed, 140 insertions(+), 112 deletions(-) delete mode 100644 libsowatch/testwatchlet.cpp delete mode 100644 libsowatch/testwatchlet.h (limited to 'libsowatch') diff --git a/libsowatch/declarativewatchlet.cpp b/libsowatch/declarativewatchlet.cpp index ca60fb0..dbd4759 100644 --- a/libsowatch/declarativewatchlet.cpp +++ b/libsowatch/declarativewatchlet.cpp @@ -29,6 +29,11 @@ DeclarativeWatchlet::DeclarativeWatchlet(WatchServer* server, const QString& id) _engine->rootContext()->setContextProperty("watch", _wrapper); } +DeclarativeWatchlet::~DeclarativeWatchlet() +{ + +} + void DeclarativeWatchlet::setSource(const QUrl &url) { if (_item) { @@ -64,6 +69,11 @@ QDeclarativeContext* DeclarativeWatchlet::rootContext() return _engine->rootContext(); } +QDeclarativeItem* DeclarativeWatchlet::rootObject() +{ + return _item; +} + void DeclarativeWatchlet::activate() { GraphicsWatchlet::activate(); @@ -76,6 +86,19 @@ void DeclarativeWatchlet::deactivate() GraphicsWatchlet::deactivate(); } +void DeclarativeWatchlet::setRootObject(QDeclarativeItem *item) +{ + Q_ASSERT(_item == 0); /* This function should not be called with a current object. */ + if (!item) { + qWarning() << "QML root object is not a declarative item?"; + return; + } + + _item = item; + // TODO Resize _item + scene()->addItem(_item); +} + void DeclarativeWatchlet::handleComponentStatus(QDeclarativeComponent::Status status) { QObject *obj; @@ -93,9 +116,7 @@ void DeclarativeWatchlet::handleComponentStatus(QDeclarativeComponent::Status st qWarning() << _component->errors(); return; } - Q_ASSERT(_item == 0); - _item = qobject_cast(obj); - scene()->addItem(_item); + setRootObject(qobject_cast(obj)); break; case QDeclarativeComponent::Error: qWarning() << "QML has errors found while loading:"; diff --git a/libsowatch/declarativewatchlet.h b/libsowatch/declarativewatchlet.h index 0dd7e23..087387a 100644 --- a/libsowatch/declarativewatchlet.h +++ b/libsowatch/declarativewatchlet.h @@ -18,25 +18,29 @@ class SOWATCH_EXPORT DeclarativeWatchlet : public GraphicsWatchlet Q_OBJECT public: explicit DeclarativeWatchlet(WatchServer* server, const QString& id); + ~DeclarativeWatchlet(); void setSource(const QUrl& url); QDeclarativeEngine* engine(); QDeclarativeContext* rootContext(); - -protected slots: - void handleComponentStatus(QDeclarativeComponent::Status status); + QDeclarativeItem* rootObject(); protected: void activate(); void deactivate(); +private: + void setRootObject(QDeclarativeItem* item); + static bool _registered; QDeclarativeEngine* _engine; QDeclarativeComponent* _component; QDeclarativeItem* _item; DeclarativeWatchWrapper* _wrapper; +private slots: + void handleComponentStatus(QDeclarativeComponent::Status status); }; } diff --git a/libsowatch/declarativewatchwrapper.cpp b/libsowatch/declarativewatchwrapper.cpp index 384a29d..f7914f8 100644 --- a/libsowatch/declarativewatchwrapper.cpp +++ b/libsowatch/declarativewatchwrapper.cpp @@ -20,6 +20,13 @@ bool DeclarativeWatchWrapper::active() const return _active; } +void DeclarativeWatchWrapper::vibrate(int msecs) +{ + if (_active) { + _watch->vibrate(msecs); + } +} + void DeclarativeWatchWrapper::activate() { if (!_active) { @@ -33,8 +40,7 @@ void DeclarativeWatchWrapper::activate() void DeclarativeWatchWrapper::deactivate() { if (_active) { - disconnect(this, SIGNAL(buttonPressed(int))); - disconnect(this, SIGNAL(buttonReleased(int))); + disconnect(_watch, 0, this, 0); _active = false; emit activeChanged(); } diff --git a/libsowatch/declarativewatchwrapper.h b/libsowatch/declarativewatchwrapper.h index 42746ec..583b2d2 100644 --- a/libsowatch/declarativewatchwrapper.h +++ b/libsowatch/declarativewatchwrapper.h @@ -21,6 +21,9 @@ public: Q_INVOKABLE QString model() const; Q_INVOKABLE bool active() const; +public slots: + void vibrate(int msecs); + signals: void buttonPressed(int button); void buttonReleased(int button); diff --git a/libsowatch/graphicswatchlet.cpp b/libsowatch/graphicswatchlet.cpp index 195d11b..e11d5cc 100644 --- a/libsowatch/graphicswatchlet.cpp +++ b/libsowatch/graphicswatchlet.cpp @@ -8,8 +8,15 @@ using namespace sowatch; GraphicsWatchlet::GraphicsWatchlet(WatchServer* server, const QString& id) : - Watchlet(server, id), _scene(0), _damaged() + Watchlet(server, id), _scene(0), _frameTimer(), _damaged() { + _frameTimer.setSingleShot(true); + connect(&_frameTimer, SIGNAL(timeout()), SLOT(frameTimeout())); +} + +GraphicsWatchlet::~GraphicsWatchlet() +{ + } QGraphicsScene* GraphicsWatchlet::scene() @@ -20,7 +27,7 @@ QGraphicsScene* GraphicsWatchlet::scene() void GraphicsWatchlet::setScene(QGraphicsScene *scene) { if (_scene) { - disconnect(this, SLOT(sceneChanged(QList))); + disconnect(_scene, 0, this, 0); } _scene = scene; if (_scene) { @@ -34,15 +41,26 @@ void GraphicsWatchlet::sceneChanged(const QList ®ion) foreach(const QRectF& r, region) { _damaged += r.toRect(); } - if (!_damaged.isEmpty() && _active && !watch()->busy()) { - const QVector rects = _damaged.rects(); - QPainter p(watch()); - - foreach(const QRect& r, rects) { - _scene->render(&p, r, r, Qt::IgnoreAspectRatio); - } - _damaged = QRegion(); + if (!_damaged.isEmpty()) { + _frameTimer.start(frameDelay); + } +} + +void GraphicsWatchlet::frameTimeout() +{ + if (!_active) return; // Watchlet was ejected, do not draw. + if (watch()->busy()) { + _frameTimer.start(busyFrameDelay); + return; + } + + const QVector rects = _damaged.rects(); + QPainter p(watch()); + + foreach(const QRect& r, rects) { + _scene->render(&p, r, r, Qt::IgnoreAspectRatio); } + _damaged = QRegion(); } void GraphicsWatchlet::activate() @@ -53,3 +71,9 @@ void GraphicsWatchlet::activate() _damaged += area; _scene->update(area); } + +void GraphicsWatchlet::deactivate() +{ + _frameTimer.stop(); + Watchlet::deactivate(); +} diff --git a/libsowatch/graphicswatchlet.h b/libsowatch/graphicswatchlet.h index 3202631..61b68bf 100644 --- a/libsowatch/graphicswatchlet.h +++ b/libsowatch/graphicswatchlet.h @@ -1,6 +1,7 @@ #ifndef SOWATCH_GRAPHICSWATCHLET_H #define SOWATCH_GRAPHICSWATCHLET_H +#include #include #include #include "watchlet.h" @@ -14,17 +15,27 @@ class SOWATCH_EXPORT GraphicsWatchlet : public Watchlet Q_OBJECT public: explicit GraphicsWatchlet(WatchServer* server, const QString& id); + ~GraphicsWatchlet(); QGraphicsScene* scene(); void setScene(QGraphicsScene* scene); -protected slots: - void sceneChanged(const QList& region); + static const int frameDelay = 20; + static const int busyFrameDelay = 40; protected: void activate(); + void deactivate(); QGraphicsScene* _scene; + QTimer _frameTimer; + +private slots: + void sceneChanged(const QList& region); + void frameTimeout(); + +private: + QRegion _damaged; }; diff --git a/libsowatch/libsowatch.pro b/libsowatch/libsowatch.pro index 5ab1f3b..4c0d7dc 100644 --- a/libsowatch/libsowatch.pro +++ b/libsowatch/libsowatch.pro @@ -19,7 +19,6 @@ SOURCES += \ watchpaintengine.cpp \ watchlet.cpp \ watch.cpp \ - testwatchlet.cpp \ graphicswatchlet.cpp \ declarativewatchwrapper.cpp \ declarativewatchlet.cpp \ @@ -35,7 +34,6 @@ HEADERS +=\ watchpaintengine.h \ watchlet.h \ watch.h \ - testwatchlet.h \ sowatch.h \ graphicswatchlet.h \ declarativewatchwrapper.h \ @@ -90,6 +88,8 @@ unix:!symbian { + + diff --git a/libsowatch/testwatchlet.cpp b/libsowatch/testwatchlet.cpp deleted file mode 100644 index ffc4097..0000000 --- a/libsowatch/testwatchlet.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include - -#include "testwatchlet.h" -#include "watch.h" - -using namespace sowatch; - -TestWatchlet::TestWatchlet(WatchServer* server) : - Watchlet(server, "com.javispedro.sowatch.testwatchlet"), _timer(new QTimer(this)), _y(0) -{ - _timer->setInterval(50); - connect(_timer, SIGNAL(timeout()), SLOT(interv())); - connect(this, SIGNAL(activated()), SLOT(handleActivated())); - connect(this, SIGNAL(deactivated()), SLOT(handleDeactivated())); -} - -void TestWatchlet::interv() -{ - QPainter p(watch()); - //p.fillRect(8, _y, 8, 1, Qt::black); - _y = (_y + 1) % watch()->height(); - p.fillRect(0, _y, _y, 2, Qt::black); - //p.fillRect(0, 0, watch()->width(), watch()->height(), Qt::black); -} - - -void TestWatchlet::handleActivated() -{ - qDebug() << "test watchlet activated"; - QPainter p(watch()); - p.fillRect(0, 0, watch()->width(), watch()->height(), Qt::white); - _timer->start(); -} - -void TestWatchlet::handleDeactivated() -{ - _timer->stop(); - qDebug() << "test watchlet deactivated"; -} diff --git a/libsowatch/testwatchlet.h b/libsowatch/testwatchlet.h deleted file mode 100644 index 6556724..0000000 --- a/libsowatch/testwatchlet.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef SOWATCH_TESTWATCHLET_H -#define SOWATCH_TESTWATCHLET_H - -#include -#include "watchlet.h" - -namespace sowatch -{ - -class TestWatchlet : public Watchlet -{ - Q_OBJECT -public: - explicit TestWatchlet(WatchServer* server); - -protected slots: - void interv(); - void handleActivated(); - void handleDeactivated(); - -private: - QTimer *_timer; - int _y; - -}; - -} - -#endif // SOWATCH_TESTWATCHLET_H diff --git a/libsowatch/watch.cpp b/libsowatch/watch.cpp index 7792693..e62c6c4 100644 --- a/libsowatch/watch.cpp +++ b/libsowatch/watch.cpp @@ -13,3 +13,8 @@ Watch::~Watch() { } + +void Watch::vibrate(int msecs) +{ + /* The default implementation does nothing. */ +} diff --git a/libsowatch/watch.h b/libsowatch/watch.h index ee9bde7..bb4376c 100644 --- a/libsowatch/watch.h +++ b/libsowatch/watch.h @@ -14,7 +14,7 @@ namespace sowatch class Watch : public QObject, public QPaintDevice { Q_OBJECT - Q_PROPERTY(QString model READ model) + Q_PROPERTY(QString model READ model CONSTANT) Q_PROPERTY(bool connected READ isConnected) Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime) @@ -38,13 +38,6 @@ public: /** Sets the current date/time on the watch. */ virtual void setDateTime(const QDateTime& dateTime) = 0; - /** Go back to the idle screen. */ - virtual void displayIdleScreen() = 0; - /** A standard notification; it's up to the watch when to stop showing it. */ - virtual void displayNotification(Notification* n) = 0; - /** Enter application mode. */ - virtual void displayApplication() = 0; - /** Grabs a button from whatever is default function is for the current mode. */ virtual void grabButton(int button) = 0; /** Restores a button to its default function. */ @@ -53,6 +46,17 @@ public: /** Tells the watch to update the unread notifications count, if visible. */ virtual void updateNotificationCount(Notification::Type type, int count) = 0; +public slots: + /** Go back to the idle screen. */ + virtual void displayIdleScreen() = 0; + /** A standard notification; it's up to the watch when to stop showing it. */ + virtual void displayNotification(Notification* notification) = 0; + /** Enter application mode. */ + virtual void displayApplication() = 0; + + /** Vibrate for a while. The default implementation does nothing. */ + virtual void vibrate(int msecs); + signals: /** The watch has been found and linked to. */ void connected(); diff --git a/libsowatch/watchlet.cpp b/libsowatch/watchlet.cpp index 6d7fe68..15e0b6c 100644 --- a/libsowatch/watchlet.cpp +++ b/libsowatch/watchlet.cpp @@ -9,6 +9,11 @@ Watchlet::Watchlet(WatchServer *server, const QString& id) : _server->registerWatchlet(this); } +Watchlet::~Watchlet() +{ + +} + WatchServer* Watchlet::server() { return _server; diff --git a/libsowatch/watchlet.h b/libsowatch/watchlet.h index 7f3413d..dad1ddc 100644 --- a/libsowatch/watchlet.h +++ b/libsowatch/watchlet.h @@ -18,12 +18,13 @@ class SOWATCH_EXPORT Watchlet : public QObject public: explicit Watchlet(WatchServer *server, const QString& id); + virtual ~Watchlet(); WatchServer* server(); Watch* watch(); Q_INVOKABLE QString id() const; - Q_INVOKABLE bool isActive() const; + bool isActive() const; signals: void activeChanged(); diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp index c81d937..9f11795 100644 --- a/libsowatch/watchserver.cpp +++ b/libsowatch/watchserver.cpp @@ -49,7 +49,7 @@ void WatchServer::setNextWatchletButton(const QString& value) void WatchServer::addProvider(NotificationProvider *provider) { provider->setParent(this); - connect(provider, SIGNAL(incomingNotification(Notification*)), SLOT(notificationReceived(Notification*))); + connect(provider, SIGNAL(incomingNotification(Notification*)), SLOT(postNotification(Notification*))); // And that's it, really. } @@ -80,7 +80,9 @@ void WatchServer::closeWatchlet() void WatchServer::registerWatchlet(Watchlet *watchlet) { Q_ASSERT(watchlet->_server == this); - _watchlets[watchlet->id()] = watchlet; + QString id = watchlet->id(); + _watchlets[id] = watchlet; + _watchletIds.append(id); } void WatchServer::reactivateCurrentWatchlet() @@ -92,13 +94,13 @@ void WatchServer::reactivateCurrentWatchlet() void WatchServer::nextWatchlet() { - QStringList watchlets = _watchlets.keys(); + qDebug() << "current watchlet index" << _currentWatchletIndex; _currentWatchletIndex++; - if (_currentWatchletIndex >= watchlets.size()) { + if (_currentWatchletIndex >= _watchletIds.size() || _currentWatchletIndex < 0) { _currentWatchletIndex = -1; closeWatchlet(); } else { - QString watchlet = watchlets.at(_currentWatchletIndex); + QString watchlet = _watchletIds.at(_currentWatchletIndex); runWatchlet(watchlet); } } @@ -176,7 +178,7 @@ void WatchServer::watchButtonPress(int button) } } -void WatchServer::notificationReceived(Notification *notification) +void WatchServer::postNotification(Notification *notification) { const Notification::Type type = notification->type(); _notifications[type].append(notification); diff --git a/libsowatch/watchserver.h b/libsowatch/watchserver.h index a3e0593..66c941a 100644 --- a/libsowatch/watchserver.h +++ b/libsowatch/watchserver.h @@ -2,6 +2,7 @@ #define SOWATCH_WATCHSERVER_H #include +#include #include #include @@ -31,39 +32,49 @@ public: void addProvider(NotificationProvider* provider); +public slots: + void postNotification(Notification *notification); void runWatchlet(const QString& id); void closeWatchlet(); + void nextWatchlet(); -protected: +private: Watch* _watch; + /** The watch button that causes next watchlet to be run. */ int _nextWatchletButton; + /** The amount of seconds that have to pass for a notification to be considered "outdated" and not shown. */ int _oldNotificationThreshold; + /** A list of watchlets in order, for use by nextWatchlet() */ + QStringList _watchletIds; + /** Actual Watchlet child objects by id. */ QMap _watchlets; - /** Stores current notifications, classified by type. */ + /** Stores current live notifications, classified by type. */ QList _notifications[Notification::TypeCount]; + /** A list of notifications that are yet to be shown to the user. */ QQueue _pendingNotifications; + /** Current watchlet. */ Watchlet* _currentWatchlet; - unsigned char _currentWatchletIndex; + /** The current watchlet index if any, for use by nextWatchlet() */ + int _currentWatchletIndex; void registerWatchlet(Watchlet *watchlet); void reactivateCurrentWatchlet(); - void nextWatchlet(); void nextNotification(); uint getNotificationCount(Notification::Type type); void goToIdle(); -protected slots: +private slots: void watchConnected(); void watchDisconnected(); void watchIdling(); void watchButtonPress(int button); - void notificationReceived(Notification* notification); + void notificationChanged(); void notificationCleared(); -- cgit v1.2.3