summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier S. Pedro <maemo@javispedro.com>2012-08-17 04:57:27 +0200
committerJavier S. Pedro <maemo@javispedro.com>2012-08-17 04:57:27 +0200
commit659c53b0d8faf26e6f06334833b2e105a4c4193d (patch)
tree8dced84e65f3c662622159acb6ab096bfc005976
parenta2059b5cfaa600402dfbec5d63099fd724998e9f (diff)
downloadsowatch-659c53b0d8faf26e6f06334833b2e105a4c4193d.tar.gz
sowatch-659c53b0d8faf26e6f06334833b2e105a4c4193d.zip
trying to make the map watchlet more useful
-rw-r--r--qmapwatchlet/mapview.cc175
-rw-r--r--qmapwatchlet/mapview.h57
-rw-r--r--qmapwatchlet/metawatch-digital.qml21
-rw-r--r--qmapwatchlet/qmapwatchlet.cpp5
-rw-r--r--qmapwatchlet/qmapwatchlet.h2
-rw-r--r--qmapwatchlet/qmapwatchlet.pro10
-rw-r--r--qmapwatchlet/qmapwatchletplugin.cpp24
-rw-r--r--qmapwatchlet/qmapwatchletplugin.h6
8 files changed, 274 insertions, 26 deletions
diff --git a/qmapwatchlet/mapview.cc b/qmapwatchlet/mapview.cc
new file mode 100644
index 0000000..30e7775
--- /dev/null
+++ b/qmapwatchlet/mapview.cc
@@ -0,0 +1,175 @@
+#include <QtCore/QDebug>
+#include <QtGui/QMainWindow>
+#include <QtGui/QLabel>
+#include <QtLocation/QGeoMapData>
+#include <QtLocation/QGraphicsGeoMap>
+#include "qmapwatchletplugin.h"
+#include "mapview.h"
+
+QTM_USE_NAMESPACE
+using namespace sowatch;
+
+MapView::MapView(QDeclarativeItem *parent) :
+ QDeclarativeItem(parent),
+ _enabled(false),
+ _mapData(0),
+ _pos(QGeoPositionInfoSource::createDefaultSource(this))
+{
+ QGeoServiceProvider *provider = QMapWatchletPlugin::geoServiceProvider();
+ if (!provider) {
+ qWarning() << "No geo service provider for map watchlet!";
+ }
+
+ QGeoMappingManager *manager = provider->mappingManager();
+ _mapData = manager->createMapData();
+
+ if (_mapData) {
+ _mapData->init();
+ _mapData->setMapType(QGraphicsGeoMap::StreetMap);
+
+ _mapData->setZoomLevel(10);
+
+ connect(_mapData, SIGNAL(zoomLevelChanged(qreal)), SIGNAL(zoomLevelChanged()));
+ connect(_mapData, SIGNAL(updateMapDisplay(QRectF)), SLOT(handleMapChanged(QRectF)));
+ } else {
+ qWarning() << "No mapdata!";
+ }
+
+ if (_pos) {
+ connect(_pos, SIGNAL(positionUpdated(QGeoPositionInfo)),
+ SLOT(handlePositionUpdate(QGeoPositionInfo)));
+ _pos->lastKnownPosition();
+ } else {
+ qWarning() << "No position source for moving map!";
+ }
+
+ setFlag(QGraphicsItem::ItemHasNoContents, false);
+}
+
+MapView::~MapView()
+{
+ delete _mapData;
+}
+
+bool MapView::updateEnabled() const
+{
+ return _enabled;
+}
+
+void MapView::setUpdateEnabled(bool enabled)
+{
+ if (_pos && _enabled != enabled) {
+ if (enabled) {
+ qDebug() << "Start position updates";
+ _pos->startUpdates();
+ } else {
+ qDebug() << "Stop position updates";
+ _pos->stopUpdates();
+ }
+ _enabled = enabled;
+
+ emit updateEnabledChanged();
+ }
+
+}
+
+int MapView::updateInterval() const
+{
+ if (_pos) {
+ return _pos->updateInterval();
+ } else {
+ return 0;
+ }
+}
+
+void MapView::setUpdateInterval(int msec)
+{
+ if (_pos) {
+ _pos->setUpdateInterval(msec);
+ emit updateIntervalChanged();
+ }
+}
+
+qreal MapView::zoomLevel() const
+{
+ if (_mapData) {
+ return _mapData->zoomLevel();
+ } else {
+ return -1.0;
+ }
+}
+
+void MapView::setZoomLevel(qreal level)
+{
+ if (_mapData) {
+ _mapData->setZoomLevel(level);
+ qDebug() << "new zoom level" << level;
+ }
+}
+
+void MapView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ if (_mapData) {
+ // Render to an image first
+ const QSize size(_mapData->windowSize().toSize());
+ QImage image(size, QImage::Format_RGB32);
+ QImage pixmap(size, QImage::Format_MonoLSB);
+
+ const int w = image.width(), h = image.height();
+ const int npixels = w * h;
+ QScopedArrayPointer<qreal> greys(new qreal[npixels]);
+
+ {
+ QPainter p(&image);
+ _mapData->paint(&p, option);
+ }
+
+ // Convert to a bitmap using some ad-hoc ugly algorithm...
+ qreal sum = 0;
+ for (int y = 0; y < h; y++) {
+ QRgb *l = reinterpret_cast<QRgb*>(image.scanLine(y));
+ for (int x = 0; x < w; x++) {
+ const int r = qRed(l[x]), g = qGreen(l[x]), b = qBlue(l[x]);
+ const qreal grey = r * 0.299f + g * 0.587f + b * 0.114f;
+
+ greys[y * w + x] = grey;
+
+ sum += grey;
+ }
+ }
+
+ const qreal avg = sum / npixels;
+ const qreal thr = avg * 0.9;
+
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < w; x++) {
+ // TODO: Optimize
+ pixmap.setPixel(x, y, greys[y * w + x] >= thr ? Qt::color1 : Qt::color0);
+ }
+ }
+
+ // And render into the watch
+ painter->drawImage(0, 0, pixmap);
+ }
+}
+
+void MapView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ Q_UNUSED(oldGeometry);
+ if (_mapData) {
+ _mapData->setWindowSize(newGeometry.size());
+ }
+}
+
+void MapView::handlePositionUpdate(const QGeoPositionInfo& info)
+{
+ if (_mapData) {
+ qDebug() << "Got pos for map";
+ _mapData->setCenter(info.coordinate());
+ }
+}
+
+void MapView::handleMapChanged(const QRectF &rect)
+{
+ update(); // Always do full updates
+}
diff --git a/qmapwatchlet/mapview.h b/qmapwatchlet/mapview.h
new file mode 100644
index 0000000..f3e457f
--- /dev/null
+++ b/qmapwatchlet/mapview.h
@@ -0,0 +1,57 @@
+#ifndef MAPVIEW_H
+#define MAPVIEW_H
+
+#include <QtDeclarative/QDeclarativeItem>
+#include <QtLocation/QGeoMappingManager>
+#include <QtLocation/QGeoPositionInfoSource>
+
+namespace sowatch
+{
+
+using QTM_PREPEND_NAMESPACE(QGeoPositionInfo);
+using QTM_PREPEND_NAMESPACE(QGeoMapData);
+using QTM_PREPEND_NAMESPACE(QGeoPositionInfoSource);
+
+class MapView : public QDeclarativeItem
+{
+ Q_OBJECT
+ Q_PROPERTY(bool updateEnabled READ updateEnabled WRITE setUpdateEnabled NOTIFY updateEnabledChanged)
+ Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval NOTIFY updateIntervalChanged)
+ Q_PROPERTY(qreal zoomLevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged)
+
+public:
+ explicit MapView(QDeclarativeItem *parent = 0);
+ ~MapView();
+
+ bool updateEnabled() const;
+ void setUpdateEnabled(bool enabled);
+
+ int updateInterval() const;
+ void setUpdateInterval(int msec);
+
+ qreal zoomLevel() const;
+ void setZoomLevel(qreal level);
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+
+signals:
+ void updateEnabledChanged();
+ void updateIntervalChanged();
+ void zoomLevelChanged();
+
+protected:
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+
+private slots:
+ void handlePositionUpdate(const QGeoPositionInfo& info);
+ void handleMapChanged(const QRectF& rect);
+
+private:
+ bool _enabled;
+ QGeoMapData *_mapData;
+ QGeoPositionInfoSource *_pos;
+};
+
+}
+
+#endif // MAPVIEW_H
diff --git a/qmapwatchlet/metawatch-digital.qml b/qmapwatchlet/metawatch-digital.qml
index 16206db..9c054a4 100644
--- a/qmapwatchlet/metawatch-digital.qml
+++ b/qmapwatchlet/metawatch-digital.qml
@@ -1,23 +1,14 @@
import QtQuick 1.0
import QtMobility.location 1.2
+import com.javispedro.sowatch.metawatch 1.0
+import com.javispedro.sowatch.qmap 1.0
-Rectangle {
- width: 96
- height: 96
-
- color: "white"
-
- PositionSource {
- id: pos
- updateInterval: 5000
- active: watch.active
- }
-
- Map {
+MWPage {
+ MapView {
id: map
anchors.fill: parent;
- plugin : Plugin { name : "nokia" }
- center: pos.position.coordinate
+ updateEnabled: watch.active
+ updateInterval: 5000;
}
Connections {
diff --git a/qmapwatchlet/qmapwatchlet.cpp b/qmapwatchlet/qmapwatchlet.cpp
index 6f39641..82132db 100644
--- a/qmapwatchlet/qmapwatchlet.cpp
+++ b/qmapwatchlet/qmapwatchlet.cpp
@@ -2,9 +2,12 @@
using namespace sowatch;
+const QLatin1String QMapWatchlet::myId("com.javispedro.sowatch.qmap");
+
QMapWatchlet::QMapWatchlet(WatchServer* server) :
- DeclarativeWatchlet(server, "com.javispedro.sowatch.qmap")
+ DeclarativeWatchlet(server, myId)
{
+ setFullUpdateMode(true);
setSource(QUrl(SOWATCH_QML_DIR "/qmapwatchlet/" + server->watch()->model() + ".qml"));
}
diff --git a/qmapwatchlet/qmapwatchlet.h b/qmapwatchlet/qmapwatchlet.h
index ae8e7ea..8683aae 100644
--- a/qmapwatchlet/qmapwatchlet.h
+++ b/qmapwatchlet/qmapwatchlet.h
@@ -11,6 +11,8 @@ class QMapWatchlet : public DeclarativeWatchlet
Q_OBJECT
public:
explicit QMapWatchlet(WatchServer* server);
+
+ static const QLatin1String myId;
};
}
diff --git a/qmapwatchlet/qmapwatchlet.pro b/qmapwatchlet/qmapwatchlet.pro
index 734e536..72f588a 100644
--- a/qmapwatchlet/qmapwatchlet.pro
+++ b/qmapwatchlet/qmapwatchlet.pro
@@ -5,17 +5,13 @@ CONFIG += plugin
CONFIG += mobility
MOBILITY += location
-SOURCES += qmapwatchletplugin.cpp qmapwatchlet.cpp
+SOURCES += qmapwatchletplugin.cpp qmapwatchlet.cpp mapview.cc
-HEADERS += qmapwatchletplugin.h qmapwatchlet.h
+HEADERS += qmapwatchletplugin.h qmapwatchlet.h mapview.h
qml_files.files = metawatch-digital.qml icon.png
-win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../libsowatch/release/ -lsowatch
-else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../libsowatch/debug/ -lsowatch
-else:symbian: LIBS += -lsowatch
-else:unix: LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch
-
+LIBS += -L$$OUT_PWD/../libsowatch/ -lsowatch
INCLUDEPATH += $$PWD/../libsowatch
DEPENDPATH += $$PWD/../libsowatch
diff --git a/qmapwatchlet/qmapwatchletplugin.cpp b/qmapwatchlet/qmapwatchletplugin.cpp
index e8e1c43..517d167 100644
--- a/qmapwatchlet/qmapwatchletplugin.cpp
+++ b/qmapwatchlet/qmapwatchletplugin.cpp
@@ -1,28 +1,41 @@
#include "qmapwatchlet.h"
+#include "mapview.h"
#include "qmapwatchletplugin.h"
using namespace sowatch;
+QTM_USE_NAMESPACE
+
+QGeoServiceProvider* QMapWatchletPlugin::_provider;
QMapWatchletPlugin::QMapWatchletPlugin(QObject *parent) :
QObject(parent)
{
+ QStringList avail = QGeoServiceProvider::availableServiceProviders();
+ if (!avail.isEmpty()) {
+ _provider = new QGeoServiceProvider(avail.first());
+ } else {
+ _provider = 0;
+ }
+ qmlRegisterType<MapView>("com.javispedro.sowatch.qmap", 1, 0, "MapView");
}
QMapWatchletPlugin::~QMapWatchletPlugin()
{
+ delete _provider;
+ _provider = 0;
}
QStringList QMapWatchletPlugin::watchlets()
{
QStringList l;
- l << "com.javispedro.sowatch.qmap";
+ l << QMapWatchlet::myId;
return l;
}
WatchletPluginInterface::WatchletInfo QMapWatchletPlugin::describeWatchlet(const QString &id)
{
WatchletInfo info;
- if (id != "com.javispedro.sowatch.qmap") return info;
+ if (id != QMapWatchlet::myId) return info;
info.name = "Moving map";
info.icon = QUrl::fromLocalFile(SOWATCH_QML_DIR "/qmapwatchlet/icon.png");
return info;
@@ -31,8 +44,13 @@ WatchletPluginInterface::WatchletInfo QMapWatchletPlugin::describeWatchlet(const
Watchlet* QMapWatchletPlugin::getWatchlet(const QString &id, ConfigKey *config, WatchServer *server)
{
Q_UNUSED(config);
- if (id != "com.javispedro.sowatch.qmap") return 0;
+ if (id != QMapWatchlet::myId) return 0;
return new QMapWatchlet(server);
}
+QGeoServiceProvider *QMapWatchletPlugin::geoServiceProvider()
+{
+ return _provider;
+}
+
Q_EXPORT_PLUGIN2(qmapwatchlet, QMapWatchletPlugin)
diff --git a/qmapwatchlet/qmapwatchletplugin.h b/qmapwatchlet/qmapwatchletplugin.h
index 04ff348..3d10213 100644
--- a/qmapwatchlet/qmapwatchletplugin.h
+++ b/qmapwatchlet/qmapwatchletplugin.h
@@ -1,6 +1,7 @@
#ifndef QMAPWATCHLETPLUGIN_H
#define QMAPWATCHLETPLUGIN_H
+#include <QtLocation/QGeoServiceProvider>
#include <sowatch.h>
namespace sowatch
@@ -18,6 +19,11 @@ public:
QStringList watchlets();
WatchletInfo describeWatchlet(const QString &id);
Watchlet* getWatchlet(const QString &id, ConfigKey *config, WatchServer *server);
+
+ static QtMobility::QGeoServiceProvider * geoServiceProvider();
+
+private:
+ static QtMobility::QGeoServiceProvider *_provider;
};
}