summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/availablewidgetsmodel.cpp31
-rw-r--r--src/widgetinfomodel.cpp125
-rw-r--r--src/widgetinfomodel.h7
3 files changed, 146 insertions, 17 deletions
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 <QtCore/QDebug>
+#include <QtCore/QBitArray>
#include <QtCore/QStringList>
#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<WidgetInfo> 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<WidgetInfo::WidgetSize>(_settings->value(base + "size").toInt()));
- info.setPosition(static_cast<WidgetInfo::WidgetPosition>(_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<bool>(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<WidgetInfo::WidgetSize>(_settings->value(base + "size").toInt()));
+ info.setPosition(static_cast<WidgetInfo::WidgetPosition>(_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<WidgetInfo> 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();