From 3ca9235ddb93b52730099164a0dc387f7a301280 Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Sun, 12 May 2013 03:49:38 +0200 Subject: weather rendering in metawatchwatchlets --- libsowatch/declarativewatchlet.cpp | 13 +++ libsowatch/declarativewatchlet.h | 1 + libsowatch/notificationsmodel.cpp | 5 +- libsowatch/notificationsmodel.h | 2 +- libsowatch/watchserver.cpp | 7 +- metawatch/metawatch.cpp | 9 +- metawatch/metawatchdigital.cpp | 106 ++++++--------------- metawatch/metawatchdigital.h | 16 ---- metawatch/metawatchdigitalsimulator.cpp | 8 ++ metawatch/metawatchdigitalsimulator.h | 1 + .../javispedro/sowatch/metawatch/MWScrollable.qml | 63 ++++++++++++ .../qml/com/javispedro/sowatch/metawatch/qmldir | 1 + metawatch/res/graphics/email.bmp | Bin 126 -> 0 bytes metawatch/res/graphics/message.bmp | Bin 126 -> 0 bytes metawatch/res/graphics/phone.bmp | Bin 126 -> 0 bytes metawatch/res/graphics/play.bmp | Bin 126 -> 0 bytes metawatch/res/graphics/timer.bmp | Bin 126 -> 0 bytes metawatch/res/graphics/weather_cloudy.bmp | Bin 158 -> 0 bytes metawatch/res/graphics/weather_rain.bmp | Bin 158 -> 0 bytes metawatch/res/graphics/weather_snow.bmp | Bin 158 -> 0 bytes metawatch/res/graphics/weather_sunny.bmp | Bin 158 -> 0 bytes metawatch/res/graphics/weather_thunderstorm.bmp | Bin 158 -> 0 bytes metawatch/res/graphics/weather_wind.bmp | Bin 158 -> 0 bytes metawatchwatchlets/ChatBubble.qml | 37 +++++++ metawatchwatchlets/idle-border.png | Bin 0 -> 198 bytes metawatchwatchlets/idle-call.png | Bin 0 -> 197 bytes metawatchwatchlets/idle-mail.png | Bin 0 -> 196 bytes metawatchwatchlets/idle-msg.png | Bin 0 -> 191 bytes metawatchwatchlets/idle_border.png | Bin 198 -> 0 bytes metawatchwatchlets/idle_call.png | Bin 197 -> 0 bytes metawatchwatchlets/idle_mail.png | Bin 196 -> 0 bytes metawatchwatchlets/idle_msg.png | Bin 191 -> 0 bytes .../metawatch-digital-notification.qml | 106 ++++++++++++++------- metawatchwatchlets/metawatch-digital-watchface.qml | 66 +++++++++++-- metawatchwatchlets/metawatchwatchlets.pro | 3 + metawatchwatchlets/notification-email.png | Bin 0 -> 224 bytes metawatchwatchlets/notification-message.png | Bin 0 -> 217 bytes metawatchwatchlets/notification-phone.png | Bin 0 -> 233 bytes metawatchwatchlets/notification-timer.png | Bin 0 -> 231 bytes metawatchwatchlets/weather-cloudy.png | Bin 0 -> 337 bytes metawatchwatchlets/weather-rain.png | Bin 0 -> 372 bytes metawatchwatchlets/weather-snow.png | Bin 0 -> 363 bytes metawatchwatchlets/weather-sunny.png | Bin 0 -> 333 bytes metawatchwatchlets/weather-thunderstorm.png | Bin 0 -> 370 bytes metawatchwatchlets/weather-wind.png | Bin 0 -> 289 bytes prepare_debug_dir.sh | 11 ++- testnotification/testnotification.cpp | 2 +- testnotification/testnotification.h | 2 + testnotification/testnotification.pro | 6 +- testnotification/testnotificationprovider.cpp | 10 +- testnotification/testnotificationprovider.h | 1 + testnotification/testweathernotification.cpp | 59 ++++++++++++ testnotification/testweathernotification.h | 34 +++++++ 53 files changed, 417 insertions(+), 152 deletions(-) create mode 100644 metawatch/qml/com/javispedro/sowatch/metawatch/MWScrollable.qml delete mode 100644 metawatch/res/graphics/email.bmp delete mode 100644 metawatch/res/graphics/message.bmp delete mode 100644 metawatch/res/graphics/phone.bmp delete mode 100644 metawatch/res/graphics/play.bmp delete mode 100644 metawatch/res/graphics/timer.bmp delete mode 100644 metawatch/res/graphics/weather_cloudy.bmp delete mode 100644 metawatch/res/graphics/weather_rain.bmp delete mode 100644 metawatch/res/graphics/weather_snow.bmp delete mode 100644 metawatch/res/graphics/weather_sunny.bmp delete mode 100644 metawatch/res/graphics/weather_thunderstorm.bmp delete mode 100644 metawatch/res/graphics/weather_wind.bmp create mode 100644 metawatchwatchlets/ChatBubble.qml create mode 100644 metawatchwatchlets/idle-border.png create mode 100644 metawatchwatchlets/idle-call.png create mode 100644 metawatchwatchlets/idle-mail.png create mode 100644 metawatchwatchlets/idle-msg.png delete mode 100644 metawatchwatchlets/idle_border.png delete mode 100644 metawatchwatchlets/idle_call.png delete mode 100644 metawatchwatchlets/idle_mail.png delete mode 100644 metawatchwatchlets/idle_msg.png create mode 100644 metawatchwatchlets/notification-email.png create mode 100644 metawatchwatchlets/notification-message.png create mode 100644 metawatchwatchlets/notification-phone.png create mode 100644 metawatchwatchlets/notification-timer.png create mode 100644 metawatchwatchlets/weather-cloudy.png create mode 100644 metawatchwatchlets/weather-rain.png create mode 100644 metawatchwatchlets/weather-snow.png create mode 100644 metawatchwatchlets/weather-sunny.png create mode 100644 metawatchwatchlets/weather-thunderstorm.png create mode 100644 metawatchwatchlets/weather-wind.png create mode 100644 testnotification/testweathernotification.cpp create mode 100644 testnotification/testweathernotification.h diff --git a/libsowatch/declarativewatchlet.cpp b/libsowatch/declarativewatchlet.cpp index c223b8d..4683dcb 100644 --- a/libsowatch/declarativewatchlet.cpp +++ b/libsowatch/declarativewatchlet.cpp @@ -2,6 +2,7 @@ #include #include "watchserver.h" #include "watch.h" +#include "watchletsmodel.h" #include "notificationsmodel.h" #include "gconfkey.h" #include "declarativewatchwrapper.h" @@ -24,9 +25,15 @@ DeclarativeWatchlet::DeclarativeWatchlet(Watch* watch, const QString& id) : if (!_registered) { qRegisterMetaType("Notification::Type"); + qRegisterMetaType("Notification::Priority"); qRegisterMetaType("WeatherNotification::WeatherType"); + qRegisterMetaType("WeatherNotification::Unit"); qmlRegisterUncreatableType("com.javispedro.sowatch", 1, 0, "Watch", "Watch is only available via the 'watch' context property"); + qmlRegisterUncreatableType("com.javispedro.sowatch", 1, 0, + "Notification", "WatchletsModel is only available via the 'notifications' context property"); + qmlRegisterUncreatableType("com.javispedro.sowatch", 1, 0, + "Notification", "Watchlet is an abstract class"); qmlRegisterUncreatableType("com.javispedro.sowatch", 1, 0, "NotificationsModel", "NotificationsModel is only available via the 'notifications' context property"); qmlRegisterUncreatableType("com.javispedro.sowatch", 1, 0, @@ -48,6 +55,7 @@ DeclarativeWatchlet::DeclarativeWatchlet(Watch* watch, const QString& id) : _engine->addImportPath(SOWATCH_QML_DIR); // Set context properties that are shared by all watchlets here + _engine->rootContext()->setContextProperty("watchlets", 0); _engine->rootContext()->setContextProperty("notifications", 0); watch->setProperty("declarativeEngine", QVariant::fromValue(_engine)); @@ -126,6 +134,11 @@ void DeclarativeWatchlet::deactivate() GraphicsWatchlet::deactivate(); } +void DeclarativeWatchlet::setWatchletsModel(WatchletsModel *model) +{ + _context->setContextProperty("watchlets", model); +} + void DeclarativeWatchlet::setNotificationsModel(NotificationsModel *model) { _context->setContextProperty("notifications", model); diff --git a/libsowatch/declarativewatchlet.h b/libsowatch/declarativewatchlet.h index dc0fb4a..93e9a8e 100644 --- a/libsowatch/declarativewatchlet.h +++ b/libsowatch/declarativewatchlet.h @@ -28,6 +28,7 @@ public: void activate(); void deactivate(); + void setWatchletsModel(WatchletsModel *model); void setNotificationsModel(NotificationsModel *model); bool handlesNotification(Notification *notification) const; diff --git a/libsowatch/notificationsmodel.cpp b/libsowatch/notificationsmodel.cpp index ce0a2fb..86adabc 100644 --- a/libsowatch/notificationsmodel.cpp +++ b/libsowatch/notificationsmodel.cpp @@ -112,6 +112,7 @@ int NotificationsModel::fullCountByType(int type) const Notification* NotificationsModel::getMostRecentByType(Notification::Type type) const { if (!_list[type].empty()) { + qDebug() << "Returning most recent" << _list[type].first(); // TODO Actually get the most recent (sort by date) return _list[type].first(); } else { @@ -119,10 +120,10 @@ Notification* NotificationsModel::getMostRecentByType(Notification::Type type) c } } -Notification* NotificationsModel::getMostRecentByType(int type) const +QObject* NotificationsModel::getMostRecentByType(int type) const { Q_ASSERT(type >= 0 && type < Notification::TypeCount); - return getMostRecentByType(static_cast(type)); + return static_cast(getMostRecentByType(static_cast(type))); } Notification::Type NotificationsModel::getTypeOfDeletedNotification(Notification *n) const diff --git a/libsowatch/notificationsmodel.h b/libsowatch/notificationsmodel.h index d88693f..ffd8ab7 100644 --- a/libsowatch/notificationsmodel.h +++ b/libsowatch/notificationsmodel.h @@ -33,7 +33,7 @@ public: 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; + Q_INVOKABLE QObject* getMostRecentByType(int type) const; // QML version Notification::Type getTypeOfDeletedNotification(Notification *n) const; diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp index 06a8189..eaea040 100644 --- a/libsowatch/watchserver.cpp +++ b/libsowatch/watchserver.cpp @@ -187,11 +187,12 @@ void WatchServer::postNotification(Notification *notification) void WatchServer::nextNotification() { if (!_watch->isConnected()) return; + if (_activeWatchlet) { + // Deactive active watchlet, if any. + deactivateActiveWatchlet(); + } if (!_pendingNotifications.empty()) { Notification *n = _pendingNotifications.head(); - if (_activeWatchlet) { - deactivateActiveWatchlet(); - } _watch->displayNotification(n); if (_notificationWatchlet) { activateWatchlet(_notificationWatchlet); diff --git a/metawatch/metawatch.cpp b/metawatch/metawatch.cpp index b5aec49..3845817 100644 --- a/metawatch/metawatch.cpp +++ b/metawatch/metawatch.cpp @@ -269,8 +269,12 @@ void MetaWatch::setupBluetoothWatch() _currentMode = IdleMode; _paintMode = IdleMode; - connect(_socket, SIGNAL(readyRead()), + if (_socket) { + // If we are running under the simulator, there might not be + // a socket. + connect(_socket, SIGNAL(readyRead()), SLOT(dataReceived())); + } // Configure the watch according to user preferences updateWatchProperties(); @@ -468,9 +472,6 @@ void MetaWatch::enableButton(Mode mode, Button button, ButtonPress press) // the pressed button and the event code were. msg.data[4] = 0x80 | ((press << 4) & 0x30) | (button & 0xF); - qDebug() << "enable button" << button << "(" << press << ")" << - "in mode" << mode << "to" << static_cast(msg.data[4]); - send(msg); } diff --git a/metawatch/metawatchdigital.cpp b/metawatch/metawatchdigital.cpp index e3f8431..0d2a3cf 100644 --- a/metawatch/metawatchdigital.cpp +++ b/metawatch/metawatchdigital.cpp @@ -3,9 +3,7 @@ using namespace sowatch; MetaWatchDigital::MetaWatchDigital(ConfigKey* settings, QObject *parent) : - MetaWatch(settings, parent), - _nMails(0), _nCalls(0), _nIms(0), _nSms(0), _nMms(0), - _wForecast(WeatherNotification::UnknownWeather) + MetaWatch(settings, parent) { QImage baseImage(screenWidth, screenHeight, QImage::Format_MonoLSB); baseImage.setColor(0, QColor(Qt::white).rgb()); @@ -67,6 +65,12 @@ void MetaWatchDigital::displayApplication() MetaWatch::displayApplication(); } +void MetaWatchDigital::clear(Mode mode, bool black) +{ + if (!_connected) return; + loadLcdTemplate(mode, black ? 1 : 0); +} + void MetaWatchDigital::update(Mode mode, const QList &rects) { if (!_connected) return; @@ -86,20 +90,32 @@ void MetaWatchDigital::update(Mode mode, const QList &rects) } } -void MetaWatchDigital::clear(Mode mode, bool black) -{ - if (!_connected) return; - loadLcdTemplate(mode, black ? 1 : 0); -} - -void MetaWatchDigital::renderIdleScreen() +#if 0 +QUrl MetaWatchDigital::iconForNotification(const Notification *n) { - + switch (n->type()) { + case Notification::CallNotification: + case Notification::MissedCallNotification: + return QUrl::fromLocalFile(SOWATCH_RESOURCES_DIR "/metawatch/graphics/phone.png"); + break; + case Notification::SmsNotification: + case Notification::MmsNotification: + case Notification::ImNotification: + return QUrl::fromLocalFile(SOWATCH_RESOURCES_DIR "/metawatch/graphics/message.png"); + break; + case Notification::EmailNotification: + return QUrl::fromLocalFile(SOWATCH_RESOURCES_DIR "/metawatch/graphics/email.bmp"); + break; + case Notification::CalendarNotification: + return QUrl::fromLocalFile(SOWATCH_RESOURCES_DIR "/metawatch/graphics/timer.bmp"); + break; + default: + return QUrl(); + } } void MetaWatchDigital::renderIdleWeather() { -#if 0 _paintMode = IdleMode; QFont sf("MetaWatch Small caps 8pt"); QFont lf("MetaWatch Large 16pt"); @@ -128,7 +144,6 @@ void MetaWatchDigital::renderIdleWeather() } _paintMode = _currentMode; -#endif } QImage MetaWatchDigital::iconForWeather(WeatherNotification::WeatherType w) @@ -151,67 +166,6 @@ QImage MetaWatchDigital::iconForWeather(WeatherNotification::WeatherType w) } } -void MetaWatchDigital::renderNotification(Notification *n) -{ - _paintMode = NotificationMode; - QPainter p; - QFont sf("MetaWatch Small caps 8pt"); - QFont lf("MetaWatch Large 16pt"); - QFont mf("MetaWatch Large 16pt"); - QImage icon = iconForNotification(n); - - sf.setPixelSize(8); - mf.setPixelSize(14); - lf.setPixelSize(16); - - const int iconW = icon.width(), iconH = icon.height(); - const int margin = 4; - const int x = margin; - const int iconY = margin; - const int titleY = margin*2 + iconH; - const int dateX = x + iconW + margin; - QTextOption option; - QRect rect, titleRect; - QString text; - - p.begin(this); - - p.fillRect(0, 0, screenWidth, screenHeight, Qt::white); - p.drawImage(x, iconY, icon); - - p.setPen(Qt::black); - option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); - option.setAlignment(Qt::AlignRight | Qt::AlignVCenter); - - // Render "N minutes ago" - p.setFont(sf); - rect.setRect(dateX, iconY, (screenWidth - dateX) - margin, iconH); - text = n->displayTime(); - p.drawText(rect, text, option); - - option.setAlignment(Qt::AlignLeft | Qt::AlignTop); - - // Render title - p.setFont(lf); - rect.setRect(x, titleY, screenWidth - x*2, screenHeight - titleY); - text = n->title(); - titleRect = p.boundingRect(rect, text, option).toRect(); - p.drawText(rect, text, option); - - // Do not try to draw body if title was large - int bodyY = titleRect.y() + titleRect.height(); - if (bodyY >= screenHeight) return; - - // Render body - p.setFont(mf); - rect.setRect(x, bodyY, screenWidth - x*2, screenHeight - bodyY); - text = n->body(); - p.drawText(rect, text, option); - - p.end(); - _paintMode = _currentMode; -} - QImage MetaWatchDigital::iconForNotification(const Notification *n) { switch (n->type()) { @@ -234,6 +188,7 @@ QImage MetaWatchDigital::iconForNotification(const Notification *n) return QImage(); } } +#endif void MetaWatchDigital::setupBluetoothWatch() { @@ -256,7 +211,4 @@ void MetaWatchDigital::setupBluetoothWatch() // Configure to show watch-rendered clock in idle screen configureLcdIdleSystemArea(false); - - // Render the idle screen assuming previous contents were lost - renderIdleScreen(); } diff --git a/metawatch/metawatchdigital.h b/metawatch/metawatchdigital.h index 1e1a62b..8baed46 100644 --- a/metawatch/metawatchdigital.h +++ b/metawatch/metawatchdigital.h @@ -29,22 +29,6 @@ public: protected: void setupBluetoothWatch(); - -private: - // Idle screen: notifications unread count - ushort _nMails, _nCalls, _nIms, _nSms, _nMms; - // Idle screen: weather information - WeatherNotification::WeatherType _wForecast; - QString _wBody; - short _wTemperature; - bool _wMetric; - - void renderIdleScreen(); - void renderIdleWeather(); - QImage iconForWeather(WeatherNotification::WeatherType w); - - void renderNotification(Notification *n); - QImage iconForNotification(const Notification *n); }; } diff --git a/metawatch/metawatchdigitalsimulator.cpp b/metawatch/metawatchdigitalsimulator.cpp index f808515..41b924a 100644 --- a/metawatch/metawatchdigitalsimulator.cpp +++ b/metawatch/metawatchdigitalsimulator.cpp @@ -20,6 +20,7 @@ MetaWatchDigitalSimulator::MetaWatchDigitalSimulator(ConfigKey *config, QObject // Connect form signals connect(_form, SIGNAL(buttonPressed(int)), SIGNAL(buttonPressed(int))); connect(_form, SIGNAL(buttonReleased(int)), SIGNAL(buttonReleased(int))); + connect(_form, SIGNAL(buttonPressed(int)), SLOT(handleButtonPressed(int))); connect(_form, SIGNAL(destroyed()), SLOT(handleFormDestroyed())); // Show the form @@ -146,3 +147,10 @@ void MetaWatchDigitalSimulator::handleFormDestroyed() _form = 0; } } + +void MetaWatchDigitalSimulator::handleButtonPressed(int button) +{ + if (button == BtnA) { + emit nextWatchletRequested(); + } +} diff --git a/metawatch/metawatchdigitalsimulator.h b/metawatch/metawatchdigitalsimulator.h index 8b424ec..d9d1295 100644 --- a/metawatch/metawatchdigitalsimulator.h +++ b/metawatch/metawatchdigitalsimulator.h @@ -31,6 +31,7 @@ public: private slots: void handleFormDestroyed(); + void handleButtonPressed(int button); private: MetaWatchDigitalSimulatorForm* _form; diff --git a/metawatch/qml/com/javispedro/sowatch/metawatch/MWScrollable.qml b/metawatch/qml/com/javispedro/sowatch/metawatch/MWScrollable.qml new file mode 100644 index 0000000..65952c1 --- /dev/null +++ b/metawatch/qml/com/javispedro/sowatch/metawatch/MWScrollable.qml @@ -0,0 +1,63 @@ +import Qt 4.7 + +Flickable { + id: flickable + + property bool selectable: true + property bool indicator: true + + interactive: false + boundsBehavior: Flickable.StopAtBounds + flickableDirection: Flickable.VerticalFlick + + function scrollDown() { + var maxY = contentHeight - height; + var newContentY = contentY + 96/3; + + if (newContentY > maxY) { + contentY = maxY; // Never overscroll. + } else { + contentY = newContentY; + } + } + + function scrollUp() { + var newContentY = contentY - 96/3; + + if (newContentY < 0) { + contentY = 0; // Never overscroll. + } else { + contentY = newContentY; + } + } + + function scrollTop() { + contentY = 0; + } + + Rectangle { + id: indicatorCont + visible: flickable.indicator && (flickable.contentHeight > flickable.height) + anchors.top: parent.top + anchors.right: parent.right + anchors.bottom: parent.bottom + width: 4 + + color: "white" + + Rectangle { + id: indicatorRect + + property int minHeight: 10 + + anchors.right: parent.right + anchors.left: parent.left + anchors.leftMargin: 1 + + y: flickable.visibleArea.yPosition * indicatorCont.height + height: Math.max(minHeight, flickable.visibleArea.heightRatio * indicatorCont.height) + + color: "black" + } + } +} diff --git a/metawatch/qml/com/javispedro/sowatch/metawatch/qmldir b/metawatch/qml/com/javispedro/sowatch/metawatch/qmldir index 10ca498..aff7045 100644 --- a/metawatch/qml/com/javispedro/sowatch/metawatch/qmldir +++ b/metawatch/qml/com/javispedro/sowatch/metawatch/qmldir @@ -2,3 +2,4 @@ MWPage 1.0 MWPage.qml MWLabel 1.0 MWLabel.qml MWTitle 1.0 MWTitle.qml MWListView 1.0 MWListView.qml +MWScrollable 1.0 MWScrollable.qml diff --git a/metawatch/res/graphics/email.bmp b/metawatch/res/graphics/email.bmp deleted file mode 100644 index 7c895af..0000000 Binary files a/metawatch/res/graphics/email.bmp and /dev/null differ diff --git a/metawatch/res/graphics/message.bmp b/metawatch/res/graphics/message.bmp deleted file mode 100644 index 53605b8..0000000 Binary files a/metawatch/res/graphics/message.bmp and /dev/null differ diff --git a/metawatch/res/graphics/phone.bmp b/metawatch/res/graphics/phone.bmp deleted file mode 100644 index a9da9d8..0000000 Binary files a/metawatch/res/graphics/phone.bmp and /dev/null differ diff --git a/metawatch/res/graphics/play.bmp b/metawatch/res/graphics/play.bmp deleted file mode 100644 index f6f507c..0000000 Binary files a/metawatch/res/graphics/play.bmp and /dev/null differ diff --git a/metawatch/res/graphics/timer.bmp b/metawatch/res/graphics/timer.bmp deleted file mode 100644 index 20ae04d..0000000 Binary files a/metawatch/res/graphics/timer.bmp and /dev/null differ diff --git a/metawatch/res/graphics/weather_cloudy.bmp b/metawatch/res/graphics/weather_cloudy.bmp deleted file mode 100644 index 506c24a..0000000 Binary files a/metawatch/res/graphics/weather_cloudy.bmp and /dev/null differ diff --git a/metawatch/res/graphics/weather_rain.bmp b/metawatch/res/graphics/weather_rain.bmp deleted file mode 100644 index fc12c6e..0000000 Binary files a/metawatch/res/graphics/weather_rain.bmp and /dev/null differ diff --git a/metawatch/res/graphics/weather_snow.bmp b/metawatch/res/graphics/weather_snow.bmp deleted file mode 100644 index d328105..0000000 Binary files a/metawatch/res/graphics/weather_snow.bmp and /dev/null differ diff --git a/metawatch/res/graphics/weather_sunny.bmp b/metawatch/res/graphics/weather_sunny.bmp deleted file mode 100644 index df9f774..0000000 Binary files a/metawatch/res/graphics/weather_sunny.bmp and /dev/null differ diff --git a/metawatch/res/graphics/weather_thunderstorm.bmp b/metawatch/res/graphics/weather_thunderstorm.bmp deleted file mode 100644 index f101610..0000000 Binary files a/metawatch/res/graphics/weather_thunderstorm.bmp and /dev/null differ diff --git a/metawatch/res/graphics/weather_wind.bmp b/metawatch/res/graphics/weather_wind.bmp deleted file mode 100644 index 59bd81b..0000000 Binary files a/metawatch/res/graphics/weather_wind.bmp and /dev/null differ diff --git a/metawatchwatchlets/ChatBubble.qml b/metawatchwatchlets/ChatBubble.qml new file mode 100644 index 0000000..ba69e64 --- /dev/null +++ b/metawatchwatchlets/ChatBubble.qml @@ -0,0 +1,37 @@ +import QtQuick 1.0 + +Item { + id: container + height: bubble.height + 4 + + default property alias children: childContainer.children + + Image { + anchors { + top: parent.top; left: parent.left; + leftMargin: 18; + } + source: "bubble_tip.png" + z: 1 + } + + BorderImage { + id: bubble + anchors { + top: parent.top; left: parent.left; right: parent.right; + topMargin: 8; + } + border { left: 16; top: 16; right: 16; bottom: 16; } + height: childContainer.height + 16 + source: "bubble.png" + Item { + id: childContainer + height: childrenRect.height + anchors { + top: parent.top; left: parent.left; right: parent.right; + margins: 16 / 2 + } + } + } +} + diff --git a/metawatchwatchlets/idle-border.png b/metawatchwatchlets/idle-border.png new file mode 100644 index 0000000..7879647 Binary files /dev/null and b/metawatchwatchlets/idle-border.png differ diff --git a/metawatchwatchlets/idle-call.png b/metawatchwatchlets/idle-call.png new file mode 100644 index 0000000..872f681 Binary files /dev/null and b/metawatchwatchlets/idle-call.png differ diff --git a/metawatchwatchlets/idle-mail.png b/metawatchwatchlets/idle-mail.png new file mode 100644 index 0000000..6afaaaa Binary files /dev/null and b/metawatchwatchlets/idle-mail.png differ diff --git a/metawatchwatchlets/idle-msg.png b/metawatchwatchlets/idle-msg.png new file mode 100644 index 0000000..b3bbd6b Binary files /dev/null and b/metawatchwatchlets/idle-msg.png differ diff --git a/metawatchwatchlets/idle_border.png b/metawatchwatchlets/idle_border.png deleted file mode 100644 index 7879647..0000000 Binary files a/metawatchwatchlets/idle_border.png and /dev/null differ diff --git a/metawatchwatchlets/idle_call.png b/metawatchwatchlets/idle_call.png deleted file mode 100644 index 872f681..0000000 Binary files a/metawatchwatchlets/idle_call.png and /dev/null differ diff --git a/metawatchwatchlets/idle_mail.png b/metawatchwatchlets/idle_mail.png deleted file mode 100644 index 6afaaaa..0000000 Binary files a/metawatchwatchlets/idle_mail.png and /dev/null differ diff --git a/metawatchwatchlets/idle_msg.png b/metawatchwatchlets/idle_msg.png deleted file mode 100644 index b3bbd6b..0000000 Binary files a/metawatchwatchlets/idle_msg.png and /dev/null differ diff --git a/metawatchwatchlets/metawatch-digital-notification.qml b/metawatchwatchlets/metawatch-digital-notification.qml index 72f7bc9..dad8cca 100644 --- a/metawatchwatchlets/metawatch-digital-notification.qml +++ b/metawatchwatchlets/metawatch-digital-notification.qml @@ -11,64 +11,87 @@ MWPage { id: title } - Item { - id: container + MWScrollable { + id: scrollable anchors.top: title.bottom anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right - Item { + Column { + id: defaultContainer + visible: false + width: page.width + + MWLabel { + text: curNotification ? curNotification.title : "" + font.pixelSize: 16 + wrapMode: Text.WordWrap + } + MWLabel { + text: curNotification ? curNotification.body : "" + wrapMode: Text.WordWrap + } + } + + Column { id: emailContainer - visible: curNotification.type === Notification.EmailNotification - anchors.fill: parent + visible: false + width: page.width + Image { + source: "notification-email.png" + } + MWLabel { + text: curNotification ? curNotification.title : "" + font.pixelSize: 16 + wrapMode: Text.WordWrap + } MWLabel { - anchors.centerIn: parent - text: "Email" + text: curNotification ? curNotification.body : "" + wrapMode: Text.WordWrap } } - Item { + Column { id: chatContainer - visible: curNotification.type === Notification.ImNotification - anchors.fill: parent + visible: false + width: page.width MWLabel { id: chatTitle - text: curNotification.title + font.pixelSize: 16 + text: curNotification ? curNotification.title : "" } - Image { - x: 20 - y: chatBubble.y - 8 - source: "bubble_tip.png" - z: 1 - } - - BorderImage { - id: chatBubble - anchors { - top: chatTitle.bottom; left: parent.left; right: parent.right; - leftMargin: 2; topMargin: 8; rightMargin: 2; bottomMargin: 2; - } - border { left: 16; top: 16; right: 16; bottom: 16; } - height: childrenRect.height + 16 - source: "bubble.png" - + ChatBubble { + width: parent.width MWLabel { - anchors { - top: parent.top; left: parent.left; right: parent.right; - margins: 16 / 2 - } - text: curNotification.body width: parent.width + text: curNotification ? curNotification.body : "" wrapMode: Text.Wrap } } } } + states: [ + State { + when: curNotification && curNotification.type === Notification.EmailNotification + PropertyChanges { target: emailContainer; visible: true; } + }, + State { + when: curNotification && ( + curNotification.type === Notification.ImNotification || + curNotification.type === Notification.SmsNotification || + curNotification.type === Notification.MmsNotification) + PropertyChanges { target: chatContainer; visible: true; } + }, + State { + when: curNotification // Any other notification type + PropertyChanges { target: defaultContainer; visible: true; } + } + ] function handlesNotification(notification) { @@ -78,4 +101,21 @@ MWPage { function openNotification(notification) { curNotification = notification; } + + Connections { + target: watch + onButtonPressed: { + switch (button) { + case 1: + scrollable.scrollUp(); + break; + case 2: + scrollable.scrollDown(); + break; + } + } + onActiveChanged: { + scrollable.scrollTop(); + } + } } diff --git a/metawatchwatchlets/metawatch-digital-watchface.qml b/metawatchwatchlets/metawatch-digital-watchface.qml index a030bdb..535cbab 100644 --- a/metawatchwatchlets/metawatch-digital-watchface.qml +++ b/metawatchwatchlets/metawatch-digital-watchface.qml @@ -17,19 +17,42 @@ MWPage { Image { width: page.width height: 2 - source: "idle_border.png" + source: "idle-border.png" } - Item { + Row { width: page.width height: 30 - // TODO Weather stuff. + + Text { + id: labelForecast + width: 36 + anchors.verticalCenter: parent.verticalCenter + font.family: "MetaWatch Small caps 8pt" + font.pixelSize: 8 + wrapMode: Text.Wrap + } + + Image { + id: iconForecast + anchors.verticalCenter: parent.verticalCenter + width: 24 + } + + Text { + id: labelTemperature + width: 36 + anchors.verticalCenter: parent.verticalCenter + font.family: "MetaWatch Large 16pt" + font.pixelSize: 16 + wrapMode: Text.Wrap + } } Image { width: page.width height: 2 - source: "idle_border.png" + source: "idle-border.png" } Item { @@ -46,7 +69,7 @@ MWPage { Image { width: 24 height: 18 - source: "idle_call.png" + source: "idle-call.png" } Text { id: labelCalls @@ -61,7 +84,7 @@ MWPage { Image { width: 24 height: 18 - source: "idle_msg.png" + source: "idle-msg.png" } Text { id: labelMsgs @@ -76,7 +99,7 @@ MWPage { Image { width: 24 height: 18 - source: "idle_mail.png" + source: "idle-mail.png" } Text { id: labelMails @@ -89,19 +112,42 @@ MWPage { } } + function _getImageForWeather(type) { + switch (type) { + case WeatherNotification.Sunny: + return "weather-sunny.png"; + case WeatherNotification.PartlyCloudy: + case WeatherNotification.Cloudy: + case WeatherNotification.Fog: + return "weather-cloudy.png"; + case WeatherNotification.Rain: + return "weather-rain.png"; + case WeatherNotification.Thunderstorm: + return "weather-thunderstorm.png"; + case WeatherNotification.Snow: + return "weather-snow.png"; + } + } + 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 Weather stuff + if (weather) { + var unit = weather.temperatureUnits == WeatherNotification.Celsius ? "°C" : "°F"; + labelForecast.text = weather.body + labelTemperature.text = weather.temperature + unit + iconForecast.source = _getImageForWeather(weather.forecast) + } else { + labelForecast.text = "" + labelTemperature.text = "" + iconForecast.source = "" } } diff --git a/metawatchwatchlets/metawatchwatchlets.pro b/metawatchwatchlets/metawatchwatchlets.pro index af6dcdb..d7ec44e 100644 --- a/metawatchwatchlets/metawatchwatchlets.pro +++ b/metawatchwatchlets/metawatchwatchlets.pro @@ -26,3 +26,6 @@ unix:!symbian { } INSTALLS += target qml_files } + +OTHER_FILES += \ + ChatBubble.qml diff --git a/metawatchwatchlets/notification-email.png b/metawatchwatchlets/notification-email.png new file mode 100644 index 0000000..da7baaf Binary files /dev/null and b/metawatchwatchlets/notification-email.png differ diff --git a/metawatchwatchlets/notification-message.png b/metawatchwatchlets/notification-message.png new file mode 100644 index 0000000..babb117 Binary files /dev/null and b/metawatchwatchlets/notification-message.png differ diff --git a/metawatchwatchlets/notification-phone.png b/metawatchwatchlets/notification-phone.png new file mode 100644 index 0000000..ba2aa40 Binary files /dev/null and b/metawatchwatchlets/notification-phone.png differ diff --git a/metawatchwatchlets/notification-timer.png b/metawatchwatchlets/notification-timer.png new file mode 100644 index 0000000..56fd1de Binary files /dev/null and b/metawatchwatchlets/notification-timer.png differ diff --git a/metawatchwatchlets/weather-cloudy.png b/metawatchwatchlets/weather-cloudy.png new file mode 100644 index 0000000..027d79d Binary files /dev/null and b/metawatchwatchlets/weather-cloudy.png differ diff --git a/metawatchwatchlets/weather-rain.png b/metawatchwatchlets/weather-rain.png new file mode 100644 index 0000000..a0e6671 Binary files /dev/null and b/metawatchwatchlets/weather-rain.png differ diff --git a/metawatchwatchlets/weather-snow.png b/metawatchwatchlets/weather-snow.png new file mode 100644 index 0000000..9c26f88 Binary files /dev/null and b/metawatchwatchlets/weather-snow.png differ diff --git a/metawatchwatchlets/weather-sunny.png b/metawatchwatchlets/weather-sunny.png new file mode 100644 index 0000000..ede115c Binary files /dev/null and b/metawatchwatchlets/weather-sunny.png differ diff --git a/metawatchwatchlets/weather-thunderstorm.png b/metawatchwatchlets/weather-thunderstorm.png new file mode 100644 index 0000000..7f24ce6 Binary files /dev/null and b/metawatchwatchlets/weather-thunderstorm.png differ diff --git a/metawatchwatchlets/weather-wind.png b/metawatchwatchlets/weather-wind.png new file mode 100644 index 0000000..f303123 Binary files /dev/null and b/metawatchwatchlets/weather-wind.png differ diff --git a/prepare_debug_dir.sh b/prepare_debug_dir.sh index 04dd8df..d266716 100755 --- a/prepare_debug_dir.sh +++ b/prepare_debug_dir.sh @@ -28,12 +28,13 @@ SCRIPT_PATH=$(readlink -f "$0") SOWATCH_ROOT=$(dirname "$SCRIPT_PATH") BUILD_ROOT=$(pwd) -rm -r drivers notifications watchlets +rm -r drivers notifications watchlets com mkdir -p drivers notifications watchlets +mkdir -p com/javispedro/sowatch make_symlinks $BUILD_ROOT/*/lib*driver.so drivers make_symlinks $BUILD_ROOT/*/lib*notification.so notifications -make_symlinks $BUILD_ROOT/*/lib*watchlet.so watchlets +make_symlinks $BUILD_ROOT/*/lib*watchlet{s,}.so watchlets for i in $SOWATCH_ROOT/*; do b="$BUILD_ROOT/$(basename $i)" @@ -42,6 +43,12 @@ for i in $SOWATCH_ROOT/*; do if [ -d "$i/res" ]; then make_symlinks $i/res/* "$b" fi + if [ -d "$i/qml" ]; then + make_symlinks $i/qml/* "$b" + fi + if [ -d "$i/qml/com/javispedro/sowatch" ]; then + make_symlinks $i/qml/com/javispedro/sowatch/* com/javispedro/sowatch + fi fi done diff --git a/testnotification/testnotification.cpp b/testnotification/testnotification.cpp index d5fe985..fe1b30f 100644 --- a/testnotification/testnotification.cpp +++ b/testnotification/testnotification.cpp @@ -8,7 +8,7 @@ TestNotification::TestNotification(Type type, const QString &title, const QStrin _time(QDateTime::currentDateTime()), _title(title), _body(body) { - const int high = 10000, low = 5000; + const int high = 60 * 1000, low = 30 * 1000; int rand = qrand() % ((high + 1) - low) + low; QTimer::singleShot(rand, this, SIGNAL(dismissed())); } diff --git a/testnotification/testnotification.h b/testnotification/testnotification.h index f54623d..ecaacb4 100644 --- a/testnotification/testnotification.h +++ b/testnotification/testnotification.h @@ -31,4 +31,6 @@ private: } +QML_DECLARE_TYPE(sowatch::TestNotification) + #endif // TESTNOTIFICATION_H diff --git a/testnotification/testnotification.pro b/testnotification/testnotification.pro index 525fdac..099c148 100644 --- a/testnotification/testnotification.pro +++ b/testnotification/testnotification.pro @@ -5,10 +5,12 @@ CONFIG += mobility MOBILITY += systeminfo SOURCES += testnotificationplugin.cpp testnotificationprovider.cpp \ - testnotification.cpp + testnotification.cpp \ + testweathernotification.cpp HEADERS += testnotificationplugin.h testnotificationprovider.h \ - testnotification.h + testnotification.h \ + testweathernotification.h unix: LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch INCLUDEPATH += $$PWD/../libsowatch diff --git a/testnotification/testnotificationprovider.cpp b/testnotification/testnotificationprovider.cpp index 687780b..8f1db76 100644 --- a/testnotification/testnotificationprovider.cpp +++ b/testnotification/testnotificationprovider.cpp @@ -1,4 +1,5 @@ #include "testnotification.h" +#include "testweathernotification.h" #include "testnotificationprovider.h" using namespace sowatch; @@ -10,10 +11,11 @@ TestNotificationProvider::TestNotificationProvider(QObject *parent) : _timer(new QTimer(this)) { const int initial_delay = 2000; - const int burst_num = 0; + const int burst_num = 1; const int burst_delay = 500; const int extra_delay = 100 * 1000; QTimer::singleShot(initial_delay, this, SLOT(generateInitialNotification())); + QTimer::singleShot(initial_delay + 100, this, SLOT(generateWeatherNotification())); for (int i = 0; i < burst_num; i++) { QTimer::singleShot(initial_delay + burst_delay * (i+1), this, SLOT(generateNotification())); } @@ -34,6 +36,12 @@ void TestNotificationProvider::generateInitialNotification() emit incomingNotification(n); } +void TestNotificationProvider::generateWeatherNotification() +{ + TestWeatherNotification *n = new TestWeatherNotification; + emit incomingNotification(n); +} + void TestNotificationProvider::generateNotification() { TestNotification *n = new TestNotification(Notification::ImNotification, diff --git a/testnotification/testnotificationprovider.h b/testnotification/testnotificationprovider.h index 7bca1f3..5813a9b 100644 --- a/testnotification/testnotificationprovider.h +++ b/testnotification/testnotificationprovider.h @@ -18,6 +18,7 @@ public: private slots: void generateInitialNotification(); + void generateWeatherNotification(); void generateNotification(); private: diff --git a/testnotification/testweathernotification.cpp b/testnotification/testweathernotification.cpp new file mode 100644 index 0000000..98c0713 --- /dev/null +++ b/testnotification/testweathernotification.cpp @@ -0,0 +1,59 @@ +#include "testweathernotification.h" + +using namespace sowatch; + +TestWeatherNotification::TestWeatherNotification(QObject *parent) + : WeatherNotification(parent) +{ +} + + +Notification::Type TestWeatherNotification::type() const +{ + return Notification::WeatherNotification; +} + +uint TestWeatherNotification::count() const +{ + return 1; +} + +QDateTime TestWeatherNotification::dateTime() const +{ + return QDateTime::currentDateTime(); +} + +QString TestWeatherNotification::title() const +{ + return "My city"; +} + +QString TestWeatherNotification::body() const +{ + return "Mostly sunny"; +} + +WeatherNotification::WeatherType TestWeatherNotification::forecast() const +{ + return Sunny; +} + +int TestWeatherNotification::temperature() const +{ + return 30; +} + +WeatherNotification::Unit TestWeatherNotification::temperatureUnits() const +{ + return Celsius; +} + +void TestWeatherNotification::activate() +{ + // Do nothing +} + +void TestWeatherNotification::dismiss() +{ + deleteLater(); // We do not want to keep those around. +} diff --git a/testnotification/testweathernotification.h b/testnotification/testweathernotification.h new file mode 100644 index 0000000..1236f31 --- /dev/null +++ b/testnotification/testweathernotification.h @@ -0,0 +1,34 @@ +#ifndef TESTWEATHERNOTIFICATION_H +#define TESTWEATHERNOTIFICATION_H + +#include + +namespace sowatch +{ + +class TestWeatherNotification : public WeatherNotification +{ + Q_OBJECT + +public: + explicit TestWeatherNotification(QObject *parent = 0); + + Type type() const; + uint count() const; + QDateTime dateTime() const; + QString title() const; + QString body() const; + + WeatherType forecast() const; + int temperature() const; + Unit temperatureUnits() const; + + void activate(); + void dismiss(); +}; + +} + +QML_DECLARE_TYPE(sowatch::TestWeatherNotification) + +#endif // TESTWEATHERNOTIFICATION_H -- cgit v1.2.3