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 --- qml/pages/AddWidget.qml | 5 +- qml/pages/MainPage.qml | 2 +- qml/watch/faces/builtinface0.qml | 11 +++ qml/watch/faces/builtinface1.qml | 11 +++ qml/watch/faces/builtinface2.png | Bin 0 -> 906 bytes qml/watch/faces/builtinface2.qml | 11 +++ qml/watch/faces/builtinface4.qml | 2 +- qml/watch/faces/builtinface5.png | Bin 0 -> 1663 bytes qml/watch/faces/builtinface5.qml | 11 +++ qml/watch/faces/builtinface_what.png | Bin 906 -> 0 bytes salmeta.pro | 3 +- src/availablewidgetsmodel.cpp | 31 ++++++++- src/widgetinfomodel.cpp | 125 +++++++++++++++++++++++++++++++---- src/widgetinfomodel.h | 7 +- translations/salmeta.ts | 34 ++++++++++ 15 files changed, 231 insertions(+), 22 deletions(-) create mode 100644 qml/watch/faces/builtinface0.qml create mode 100644 qml/watch/faces/builtinface1.qml create mode 100644 qml/watch/faces/builtinface2.png create mode 100644 qml/watch/faces/builtinface2.qml create mode 100644 qml/watch/faces/builtinface5.png create mode 100644 qml/watch/faces/builtinface5.qml delete mode 100644 qml/watch/faces/builtinface_what.png diff --git a/qml/pages/AddWidget.qml b/qml/pages/AddWidget.qml index 5c3086e..c854c7c 100644 --- a/qml/pages/AddWidget.qml +++ b/qml/pages/AddWidget.qml @@ -19,13 +19,14 @@ Page { } delegate : BackgroundItem { + id: widgetDelegate contentHeight: Theme.itemSizeSmall Label { anchors.left: parent.left anchors.margins: Theme.paddingLarge anchors.verticalCenter: parent.verticalCenter - text: model.description + text: model.description + (!widgetDelegate.enabled ? qsTr(" (does not fit)") : "") truncationMode: TruncationMode.Elide color: highlighted ? Theme.highlightColor : Theme.primaryColor } @@ -34,6 +35,8 @@ Page { curWidgets.addWidget(model.url, addToPage, addToPos, model.size); pageStack.pop(); } + + enabled: !curWidgets.widgetOverlaps(addToPage, addToPos, model.size); } } } diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml index b25ff06..20d602f 100644 --- a/qml/pages/MainPage.qml +++ b/qml/pages/MainPage.qml @@ -227,7 +227,7 @@ Page { Label { x: Theme.paddingLarge - text: "TODO" + text: "TODO: List of notification types" } } } diff --git a/qml/watch/faces/builtinface0.qml b/qml/watch/faces/builtinface0.qml new file mode 100644 index 0000000..a8df091 --- /dev/null +++ b/qml/watch/faces/builtinface0.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + width: 96/2 + height: 96/2 + + Image { + anchors.fill: parent + source: "builtinface0.png" + } +} diff --git a/qml/watch/faces/builtinface1.qml b/qml/watch/faces/builtinface1.qml new file mode 100644 index 0000000..3d4bb57 --- /dev/null +++ b/qml/watch/faces/builtinface1.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + width: 96 + height: 96/2 + + Image { + anchors.fill: parent + source: "builtinface3.png" + } +} diff --git a/qml/watch/faces/builtinface2.png b/qml/watch/faces/builtinface2.png new file mode 100644 index 0000000..3ade62b Binary files /dev/null and b/qml/watch/faces/builtinface2.png differ diff --git a/qml/watch/faces/builtinface2.qml b/qml/watch/faces/builtinface2.qml new file mode 100644 index 0000000..7c4542a --- /dev/null +++ b/qml/watch/faces/builtinface2.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + width: 96 + height: 96 + + Image { + anchors.fill: parent + source: "builtinface2.png" + } +} diff --git a/qml/watch/faces/builtinface4.qml b/qml/watch/faces/builtinface4.qml index f9eff50..ca542d4 100644 --- a/qml/watch/faces/builtinface4.qml +++ b/qml/watch/faces/builtinface4.qml @@ -6,6 +6,6 @@ Rectangle { Image { anchors.fill: parent - source: "builtinface4.png" + source: "builtinface3.png" } } diff --git a/qml/watch/faces/builtinface5.png b/qml/watch/faces/builtinface5.png new file mode 100644 index 0000000..d084bb0 Binary files /dev/null and b/qml/watch/faces/builtinface5.png differ diff --git a/qml/watch/faces/builtinface5.qml b/qml/watch/faces/builtinface5.qml new file mode 100644 index 0000000..e64703c --- /dev/null +++ b/qml/watch/faces/builtinface5.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + width: 96 + height: 96 + + Image { + anchors.fill: parent + source: "builtinface5.png" + } +} diff --git a/qml/watch/faces/builtinface_what.png b/qml/watch/faces/builtinface_what.png deleted file mode 100644 index 3ade62b..0000000 Binary files a/qml/watch/faces/builtinface_what.png and /dev/null differ diff --git a/salmeta.pro b/salmeta.pro index 550925f..86ccf52 100644 --- a/salmeta.pro +++ b/salmeta.pro @@ -45,8 +45,7 @@ OTHER_FILES += qml/salmeta.qml \ qml/pages/MainPage.qml \ qml/watch/WidgetView.qml \ qml/watch/WatchView.qml qml/watch/add_widget.png \ - qml/watch/faces/builtinface3.qml qml/watch/faces/builtinface3.png \ - qml/watch/faces/builtinface4.qml qml/watch/faces/builtinface4.png \ + qml/watch/faces/*.qml qml/watch/faces/*.png \ qml/watch/icons/*.png \ qml/pages/AddWidget.qml \ qml/watch/notification.png 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(); diff --git a/translations/salmeta.ts b/translations/salmeta.ts index 786af13..605d20c 100644 --- a/translations/salmeta.ts +++ b/translations/salmeta.ts @@ -1,6 +1,40 @@ + + AddWidget + + (does not fit) + + + + + AvailableWidgetsModel + + Watchface: 1x1 Small + + + + Watchface: 2x1 Horizontal + + + + Watchface: 2x2 MetaWatch logo + + + + Watchface: 2x2 Big numbers + + + + Watchface: 2x2 Fish + + + + Watchface: 2x2 Hanzi + + + MainPage -- cgit v1.2.3