From 327dab50c887d2818cac9109049bf5fc1f391a17 Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Sat, 27 Sep 2014 18:15:22 +0200 Subject: enable all the builtin watchfaces --- src/availablewidgetsmodel.cpp | 31 ++++++++++- src/widgetinfomodel.cpp | 125 ++++++++++++++++++++++++++++++++++++++---- src/widgetinfomodel.h | 7 ++- 3 files changed, 146 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/availablewidgetsmodel.cpp b/src/availablewidgetsmodel.cpp index 37232dc..77304b9 100644 --- a/src/availablewidgetsmodel.cpp +++ b/src/availablewidgetsmodel.cpp @@ -53,17 +53,42 @@ void AvailableWidgetsModel::reload() // Load builtin widgets WidgetInfo info; + info.setUrl(SailfishApp::pathTo("qml/watch/faces/builtinface0.qml")); + info.setDescription(tr("Watchface: 1x1 Small")); + info.setSize(WidgetInfo::Size1Q); + Q_ASSERT(info.builtinClockfaceId() == 0); // Ensure face ID is autodetected from passed URL + _widgets.append(info); + + + info.setUrl(SailfishApp::pathTo("qml/watch/faces/builtinface1.qml")); + info.setDescription(tr("Watchface: 2x1 Horizontal")); + info.setSize(WidgetInfo::Size2QHorizontal); + Q_ASSERT(info.builtinClockfaceId() == 1); + _widgets.append(info); + + info.setUrl(SailfishApp::pathTo("qml/watch/faces/builtinface2.qml")); + info.setDescription(tr("Watchface: 2x2 MetaWatch logo")); + info.setSize(WidgetInfo::Size4Q); + Q_ASSERT(info.builtinClockfaceId() == 2); + _widgets.append(info); + info.setUrl(SailfishApp::pathTo("qml/watch/faces/builtinface3.qml")); - info.setDescription("Builtin watchface #3"); + info.setDescription(tr("Watchface: 2x2 Big numbers")); info.setSize(WidgetInfo::Size4Q); - Q_ASSERT(info.builtinClockfaceId() == 3); // Autodetected from passed URL + Q_ASSERT(info.builtinClockfaceId() == 3); _widgets.append(info); info.setUrl(SailfishApp::pathTo("qml/watch/faces/builtinface4.qml")); - info.setDescription("Builtin watchface #4"); + info.setDescription(tr("Watchface: 2x2 Fish")); info.setSize(WidgetInfo::Size4Q); Q_ASSERT(info.builtinClockfaceId() == 4); _widgets.append(info); + info.setUrl(SailfishApp::pathTo("qml/watch/faces/builtinface5.qml")); + info.setDescription(tr("Watchface: 2x2 Hanzi")); + info.setSize(WidgetInfo::Size4Q); + Q_ASSERT(info.builtinClockfaceId() == 5); + _widgets.append(info); + endResetModel(); } diff --git a/src/widgetinfomodel.cpp b/src/widgetinfomodel.cpp index e2f145f..9bb53e4 100644 --- a/src/widgetinfomodel.cpp +++ b/src/widgetinfomodel.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "widgetinfomodel.h" @@ -10,6 +11,82 @@ inline QString get_widget_dconf_base(int index) return QString("widget%1_").arg(index); } +WidgetInfo::WidgetPosition canonicalize_widget_pos(WidgetInfo::WidgetPosition pos, WidgetInfo::WidgetSize size) +{ + switch (size) { + case WidgetInfo::Size1Q: + return pos; // Any position is valid + case WidgetInfo::Size2QHorizontal: + switch (pos) { + case WidgetInfo::PosNW: + case WidgetInfo::PosNE: + return WidgetInfo::PosNW; + case WidgetInfo::PosSW: + case WidgetInfo::PosSE: + return WidgetInfo::PosSW; + } + break; + case WidgetInfo::Size2QVertical: + switch (pos) { + case WidgetInfo::PosNW: + case WidgetInfo::PosSW: + return WidgetInfo::PosNW; + case WidgetInfo::PosNE: + case WidgetInfo::PosSE: + return WidgetInfo::PosNE; + } + break; + case WidgetInfo::Size4Q: + return WidgetInfo::PosNW; // 4Q widgets use entire screen + } + + return pos; +} + +QBitArray used_positions(WidgetInfo::WidgetPosition pos, WidgetInfo::WidgetSize size) +{ + QBitArray used(4, false); + + switch (size) { + case WidgetInfo::Size1Q: + used[pos] = true; + break; + case WidgetInfo::Size2QHorizontal: + switch (pos) { + case WidgetInfo::PosNW: + case WidgetInfo::PosNE: + used[WidgetInfo::PosNW] = true; + used[WidgetInfo::PosNE] = true; + break; + case WidgetInfo::PosSW: + case WidgetInfo::PosSE: + used[WidgetInfo::PosNW] = true; + used[WidgetInfo::PosNE] = true; + break; + } + break; + case WidgetInfo::Size2QVertical: + switch (pos) { + case WidgetInfo::PosNW: + case WidgetInfo::PosSW: + used[WidgetInfo::PosNW] = true; + used[WidgetInfo::PosSW] = true; + break; + case WidgetInfo::PosNE: + case WidgetInfo::PosSE: + used[WidgetInfo::PosNE] = true; + used[WidgetInfo::PosSE] = true; + break; + } + break; + case WidgetInfo::Size4Q: + used.fill(true); + break; + } + + return used; +} + } WidgetInfoModel::WidgetInfoModel(const QString &settingsPrefix, QObject *parent) : @@ -69,23 +146,21 @@ QList WidgetInfoModel::toList() const return _widgets.toList(); } -void WidgetInfoModel::reload() +bool WidgetInfoModel::widgetOverlaps(int page, WidgetInfo::WidgetPosition pos, WidgetInfo::WidgetSize size) const { - beginResetModel(); - _widgets.resize(16); + QBitArray usedPos = used_positions(pos, size); for (int i = 0; i < _widgets.size(); i++) { - WidgetInfo &info = _widgets[i]; - const QString base = get_widget_dconf_base(i); + if (_widgets[i].url().isEmpty()) continue; + if (_widgets[i].page() != page) continue; - info.setInvert(_settings->value(base + "invert").toBool()); - info.setPage(_settings->value(base + "page").toInt()); - info.setSize(static_cast(_settings->value(base + "size").toInt())); - info.setPosition(static_cast(_settings->value(base + "position").toInt())); - info.setUrl(_settings->value(base + "url").toUrl()); + QBitArray intersection = usedPos & used_positions(_widgets[i].position(), _widgets[i].size()); + if (intersection.count(true) > 0) { + return true; + } } - endResetModel(); + return false; } int WidgetInfoModel::addWidget(const QUrl &url, int page, WidgetInfo::WidgetPosition pos, WidgetInfo::WidgetSize size) @@ -93,11 +168,18 @@ int WidgetInfoModel::addWidget(const QUrl &url, int page, WidgetInfo::WidgetPosi int slot = findEmptySlot(); if (slot == -1) { qWarning() << "No empty slots!"; // This shouldn't happen - return slot; + return -1; } + pos = canonicalize_widget_pos(pos, size); + qDebug() << "Adding widget" << url << page << pos << size; + if (widgetOverlaps(page, pos, size)) { + qWarning() << "Can't add the widget: it overlaps with an existing one!"; + return -1; + } + const QString base = get_widget_dconf_base(slot); _settings->setValue(base + "invert", QVariant::fromValue(false)); @@ -122,6 +204,25 @@ void WidgetInfoModel::removeWidget(int widgetId) _settings->setValue(base + "position", QVariant()); } +void WidgetInfoModel::reload() +{ + beginResetModel(); + _widgets.resize(16); + + for (int i = 0; i < _widgets.size(); i++) { + WidgetInfo &info = _widgets[i]; + const QString base = get_widget_dconf_base(i); + + info.setInvert(_settings->value(base + "invert").toBool()); + info.setPage(_settings->value(base + "page").toInt()); + info.setSize(static_cast(_settings->value(base + "size").toInt())); + info.setPosition(static_cast(_settings->value(base + "position").toInt())); + info.setUrl(_settings->value(base + "url").toUrl()); + } + + endResetModel(); +} + int WidgetInfoModel::findEmptySlot() { for (int i = 0; i < _widgets.size(); i++) { diff --git a/src/widgetinfomodel.h b/src/widgetinfomodel.h index 4b2a700..bc3cd67 100644 --- a/src/widgetinfomodel.h +++ b/src/widgetinfomodel.h @@ -27,12 +27,15 @@ public: QList toList() const; + Q_INVOKABLE bool widgetOverlaps(int page, WidgetInfo::WidgetPosition pos, WidgetInfo::WidgetSize size) const; + + Q_INVOKABLE int addWidget(const QUrl &url, int page, WidgetInfo::WidgetPosition pos, WidgetInfo::WidgetSize size); + Q_INVOKABLE void removeWidget(int widgetId); + signals: public slots: void reload(); - int addWidget(const QUrl &url, int page, WidgetInfo::WidgetPosition pos, WidgetInfo::WidgetSize size); - void removeWidget(int widgetId); private: int findEmptySlot(); -- cgit v1.2.3