From d83093df7602aa2896de71292b47948540c22a44 Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Mon, 6 May 2013 01:11:40 +0200 Subject: metawatch watchface in QML still a work in progress --- libsowatch/declarativewatchlet.cpp | 4 +- libsowatch/notification.h | 1 + libsowatch/notificationsmodel.cpp | 27 +++++ libsowatch/notificationsmodel.h | 12 +- libsowatch/watchserver.cpp | 27 ++++- libsowatch/watchserver.h | 8 +- metawatch/metawatchdigitalsimulator.cpp | 3 + metawatchwatchlets/metawatch-digital-watchface.qml | 123 ++++++++++++++++++++- 8 files changed, 192 insertions(+), 13 deletions(-) diff --git a/libsowatch/declarativewatchlet.cpp b/libsowatch/declarativewatchlet.cpp index 3647575..bc979b0 100644 --- a/libsowatch/declarativewatchlet.cpp +++ b/libsowatch/declarativewatchlet.cpp @@ -22,10 +22,13 @@ DeclarativeWatchlet::DeclarativeWatchlet(Watch* watch, const QString& id) : scene()->setStickyFocus(true); if (!_registered) { + qRegisterMetaType("Notification::Type"); qmlRegisterUncreatableType("com.javispedro.sowatch", 1, 0, "Watch", "Watch is only available via the 'watch' context property"); qmlRegisterUncreatableType("com.javispedro.sowatch", 1, 0, "NotificationsModel", "NotificationsModel is only available via the 'notifications' context property"); + qmlRegisterUncreatableType("com.javispedro.sowatch", 1, 0, + "Notification", "Notification is an abstract class"); qmlRegisterType(); qmlRegisterType("com.javispedro.sowatch", 1, 0, "GConfKey"); _registered = true; @@ -121,7 +124,6 @@ void DeclarativeWatchlet::deactivate() void DeclarativeWatchlet::setNotificationsModel(NotificationsModel *model) { - qDebug() << Q_FUNC_INFO; _context->setContextProperty("notifications", model); } diff --git a/libsowatch/notification.h b/libsowatch/notification.h index 8bae4ff..7080f7f 100644 --- a/libsowatch/notification.h +++ b/libsowatch/notification.h @@ -73,5 +73,6 @@ signals: } QML_DECLARE_TYPE(sowatch::Notification) +QML_DECLARE_TYPE(sowatch::Notification::Type) #endif // SOWATCH_NOTIFICATION_H diff --git a/libsowatch/notificationsmodel.cpp b/libsowatch/notificationsmodel.cpp index 73d4ab6..259ac93 100644 --- a/libsowatch/notificationsmodel.cpp +++ b/libsowatch/notificationsmodel.cpp @@ -56,6 +56,8 @@ void NotificationsModel::add(Notification *n) _list[type].append(n); endInsertRows(); + emit modelChanged(); + connect(n, SIGNAL(changed()), SLOT(handleNotificationChanged())); } @@ -77,6 +79,8 @@ void NotificationsModel::remove(Notification::Type type, Notification *n) beginRemoveRows(QModelIndex(), index, index); _list[type].removeAt(subindex); endRemoveRows(); + + emit modelChanged(); } int NotificationsModel::fullCount() const @@ -97,6 +101,28 @@ int NotificationsModel::fullCountByType(Notification::Type type) const return count; } +int NotificationsModel::fullCountByType(int type) const +{ + Q_ASSERT(type >= 0 && type < Notification::TypeCount); + return fullCountByType(static_cast(type)); +} + +Notification* NotificationsModel::getMostRecentByType(Notification::Type type) const +{ + if (!_list[type].empty()) { + // TODO Actually get the most recent (sort by date) + return _list[type].first(); + } else { + return 0; + } +} + +Notification* NotificationsModel::getMostRecentByType(int type) const +{ + Q_ASSERT(type >= 0 && type < Notification::TypeCount); + return getMostRecentByType(static_cast(type)); +} + Notification::Type NotificationsModel::getTypeOfDeletedNotification(Notification *n) const { // Can't call any methods of 'n' @@ -154,5 +180,6 @@ void NotificationsModel::handleNotificationChanged() const int index = getIndexForNotification(n); emit dataChanged(createIndex(index, 0), createIndex(index, 0)); + emit modelChanged(); } } diff --git a/libsowatch/notificationsmodel.h b/libsowatch/notificationsmodel.h index 6aabf71..d88693f 100644 --- a/libsowatch/notificationsmodel.h +++ b/libsowatch/notificationsmodel.h @@ -11,6 +11,7 @@ namespace sowatch class NotificationsModel : public QAbstractListModel { Q_OBJECT + public: explicit NotificationsModel(QObject *parent = 0); @@ -27,11 +28,18 @@ public: void remove(Notification *n); void remove(Notification::Type type, Notification *n); - int fullCount() const; - int fullCountByType(Notification::Type type) const; + Q_INVOKABLE int fullCount() const; + Q_INVOKABLE int fullCountByType(Notification::Type type) const; + Q_INVOKABLE int fullCountByType(int type) const; // See QTBUG-26415 + + Q_INVOKABLE Notification* getMostRecentByType(Notification::Type type) const; + Q_INVOKABLE Notification* getMostRecentByType(int type) const; Notification::Type getTypeOfDeletedNotification(Notification *n) const; +signals: + void modelChanged(); + private: int getOffsetForType(Notification::Type type) const; int getAppendOffsetForType(Notification::Type type) const; diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp index 6448508..41dc78e 100644 --- a/libsowatch/watchserver.cpp +++ b/libsowatch/watchserver.cpp @@ -65,10 +65,13 @@ void WatchServer::setIdleWatchlet(Watchlet *watchlet) { if (_idleWatchlet) { removeWatchlet(_idleWatchlet); + unsetWatchletProperties(_idleWatchlet); } _idleWatchlet = watchlet; if (watchlet) { _watchletIds[watchlet->id()] = watchlet; + setWatchletProperties(_idleWatchlet); + // TODO Possibly activate this watchlet now if we are on the idle screen. } } @@ -81,11 +84,12 @@ void WatchServer::setNotificationWatchlet(Watchlet *watchlet) { if (_notificationWatchlet) { removeWatchlet(_notificationWatchlet); + unsetWatchletProperties(_notificationWatchlet); } _notificationWatchlet = watchlet; if (watchlet) { _watchletIds[watchlet->id()] = watchlet; - // TODO Possibly activate this watchlet now if we are on the idle screen. + setWatchletProperties(_notificationWatchlet); } } @@ -213,6 +217,17 @@ void WatchServer::nextNotification() } void WatchServer::runWatchlet(Watchlet *watchlet) +{ + Q_ASSERT(watchlet->watch() == _watch); + if (_activeWatchlet) { + deactivateActiveWatchlet(); + } + if (_watch->isConnected()) { + activateWatchlet(watchlet); + } +} + +void WatchServer::openWatchlet(Watchlet *watchlet) { Q_ASSERT(watchlet->watch() == _watch); if (_activeWatchlet) { @@ -224,10 +239,10 @@ void WatchServer::runWatchlet(Watchlet *watchlet) } } -void WatchServer::runWatchlet(const QString& id) +void WatchServer::openWatchlet(const QString& id) { Q_ASSERT(_watchletIds.contains(id)); - runWatchlet(_watchletIds[id]); + openWatchlet(_watchletIds[id]); } void WatchServer::closeWatchlet() @@ -291,7 +306,7 @@ void WatchServer::nextWatchlet() closeWatchlet(); } else { Watchlet* watchlet = _watchlets.at(_currentWatchletIndex); - runWatchlet(watchlet); + openWatchlet(watchlet); } } @@ -306,7 +321,9 @@ void WatchServer::syncTime() uint WatchServer::getNotificationCount(Notification::Type type) { - return _notifications->fullCountByType(type); + // TODO: deprecate + return 0; + //return _notifications->fullCountByType(type); } void WatchServer::removeNotification(Notification::Type type, Notification *n) diff --git a/libsowatch/watchserver.h b/libsowatch/watchserver.h index eafee7a..cc6c548 100644 --- a/libsowatch/watchserver.h +++ b/libsowatch/watchserver.h @@ -56,9 +56,15 @@ public slots: void postNotification(Notification *notification); void nextNotification(); + /** Run the selected watchlet (set it as active, but not as current). */ void runWatchlet(Watchlet* watchlet); - void runWatchlet(const QString& id); + /** Run the selected watchlet and set it as the current. + If the watch is disconnected, a notification arrives, etc. */ + void openWatchlet(Watchlet* watchlet); + void openWatchlet(const QString& id); + /** Close the active watchlet (and return back to the current watc) */ void closeWatchlet(); + /** Close the active watchlet, advance the current watchlet carousel and open it */ void nextWatchlet(); void syncTime(); diff --git a/metawatch/metawatchdigitalsimulator.cpp b/metawatch/metawatchdigitalsimulator.cpp index dcd0f6f..c20e8c5 100644 --- a/metawatch/metawatchdigitalsimulator.cpp +++ b/metawatch/metawatchdigitalsimulator.cpp @@ -24,6 +24,9 @@ MetaWatchDigitalSimulator::MetaWatchDigitalSimulator(ConfigKey *config, QObject // Show the form _form->showNormal(); + + // Schedule a connection even if BT is off or anything like that. + scheduleConnect(); } MetaWatchDigitalSimulator::~MetaWatchDigitalSimulator() diff --git a/metawatchwatchlets/metawatch-digital-watchface.qml b/metawatchwatchlets/metawatch-digital-watchface.qml index 712dbeb..23236a6 100644 --- a/metawatchwatchlets/metawatch-digital-watchface.qml +++ b/metawatchwatchlets/metawatch-digital-watchface.qml @@ -1,8 +1,9 @@ import QtQuick 1.0 +import com.javispedro.sowatch 1.0 import com.javispedro.sowatch.metawatch 1.0 MWPage { - // Remember that firmware draws top 30 lines + id: page Connections { target: watch @@ -11,8 +12,122 @@ MWPage { } } - MWLabel { - anchors.centerIn: parent - text: "This is a test" + Column { + Item { + id: systemArea + // Firmware draws top 30 lines; + // ensure we do not draw anything on top + width: page.width + height: 30 + } + + Image { + width: page.width + height: 2 + source: "idle_border.png" + } + + Item { + width: page.width + height: 30 + } + + Image { + width: page.width + height: 2 + source: "idle_border.png" + } + + Item { + width: page.width + height: 2 + } + + Row { + anchors.horizontalCenter: parent.horizontalCenter + height: 30 + spacing: 8 + Column { + spacing: 4 + Image { + width: 24 + height: 18 + source: "idle_call.png" + } + Text { + id: labelCalls + anchors.horizontalCenter: parent.horizontalCenter + font.family: "MetaWatch Large caps 8pt" + font.pixelSize: 8 + text: "0" + } + } + Column { + spacing: 2 + Image { + width: 24 + height: 18 + source: "idle_msg.png" + } + Text { + id: labelMsgs + anchors.horizontalCenter: parent.horizontalCenter + font.family: "MetaWatch Large caps 8pt" + font.pixelSize: 8 + text: "0" + } + } + Column { + spacing: 2 + Image { + width: 24 + height: 18 + source: "idle_mail.png" + } + Text { + id: labelMails + anchors.horizontalCenter: parent.horizontalCenter + font.family: "MetaWatch Large caps 8pt" + font.pixelSize: 8 + text: "0" + } + } + } + } + + function updateUnreadCounts() { + labelCalls.text = notifications.fullCountByType(Notification.MissedCallNotification); + labelMsgs.text = notifications.fullCountByType(Notification.SmsNotification) + + notifications.fullCountByType(Notification.MmsNotification) + + notifications.fullCountByType(Notification.ImNotification); + labelMails.text = notifications.fullCountByType(Notification.EmailNotification); + console.log("unread mails = " + labelMails.text); + } + + function updateWeather() { + var weather = notifications.getMostRecentByType(Notification.WeatherNotification); + if (typeof weather !== "undefined") { + // TODO + } + } + + function update() { + updateUnreadCounts(); + updateWeather(); + } + + Connections { + target: watch + onActiveChanged: { + if (watch.active) { + console.log("watchface active"); + //updateUnreadCounts(); + } + } + } + + Connections { + target: notifications + onModelChanged: update(); } } -- cgit v1.2.3