From 0f7dc0cf0596d56aa3422c59472f3400d537cd1c Mon Sep 17 00:00:00 2001 From: Yari Polla Date: Sat, 7 May 2022 19:10:02 +0200 Subject: [PATCH] quicksettings: implement swipe view --- components/mobileshell/CMakeLists.txt | 1 + components/mobileshell/mobileshellplugin.cpp | 2 + components/mobileshell/paginatemodel.cpp | 384 ++++++++++++++++++ components/mobileshell/paginatemodel.h | 122 ++++++ .../quicksettings/QuickSettings.qml | 117 ++++-- components/mobileshell/quicksettingsmodel.h | 6 +- 6 files changed, 602 insertions(+), 30 deletions(-) create mode 100644 components/mobileshell/paginatemodel.cpp create mode 100644 components/mobileshell/paginatemodel.h diff --git a/components/mobileshell/CMakeLists.txt b/components/mobileshell/CMakeLists.txt index 577bea2d..209c5cf4 100644 --- a/components/mobileshell/CMakeLists.txt +++ b/components/mobileshell/CMakeLists.txt @@ -8,6 +8,7 @@ set(mobileshellplugin_SRCS mobileshellplugin.cpp mobileshellsettings.cpp quicksetting.cpp + paginatemodel.cpp quicksettingsmodel.cpp savedquicksettings.cpp savedquicksettingsmodel.cpp diff --git a/components/mobileshell/mobileshellplugin.cpp b/components/mobileshell/mobileshellplugin.cpp index 5e73d76e..b6113b4b 100644 --- a/components/mobileshell/mobileshellplugin.cpp +++ b/components/mobileshell/mobileshellplugin.cpp @@ -20,6 +20,7 @@ #include "taskswitcher/displaysmodel.h" #include "mobileshellsettings.h" +#include "paginatemodel.h" #include "quicksetting.h" #include "quicksettingsmodel.h" #include "shellutil.h" @@ -44,6 +45,7 @@ void MobileShellPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 1, 0, "QuickSetting"); qmlRegisterType(uri, 1, 0, "QuickSettingsModel"); + qmlRegisterType(uri, 1, 0, "PaginateModel"); qmlRegisterType(uri, 1, 0, "SavedQuickSettings"); qmlRegisterType(uri, 1, 0, "SavedQuickSettingsModel"); qmlRegisterSingletonType(uri, 1, 0, "WindowUtil", [](QQmlEngine *, QJSEngine *) -> QObject * { diff --git a/components/mobileshell/paginatemodel.cpp b/components/mobileshell/paginatemodel.cpp new file mode 100644 index 00000000..874ff48f --- /dev/null +++ b/components/mobileshell/paginatemodel.cpp @@ -0,0 +1,384 @@ +/* + * SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +#include "paginatemodel.h" +#include + +class PaginateModel::PaginateModelPrivate +{ +public: + int m_firstItem = 0; + int m_pageSize = 0; + QAbstractItemModel *m_sourceModel = nullptr; + bool m_hasStaticRowCount = false; +}; + +PaginateModel::PaginateModel(QObject *object) + : QAbstractListModel(object) + , d(new PaginateModelPrivate) +{ +} + +PaginateModel::~PaginateModel() = default; + +int PaginateModel::firstItem() const +{ + return d->m_firstItem; +} + +void PaginateModel::setFirstItem(int row) +{ + Q_ASSERT(row >= 0 && row < d->m_sourceModel->rowCount()); + if (row != d->m_firstItem) { + beginResetModel(); + d->m_firstItem = row; + endResetModel(); + Q_EMIT firstItemChanged(); + } +} + +int PaginateModel::pageSize() const +{ + return d->m_pageSize; +} + +void PaginateModel::setPageSize(int count) +{ + if (count != d->m_pageSize) { + const int oldSize = rowsByPageSize(d->m_pageSize); + const int newSize = rowsByPageSize(count); + const int difference = newSize - oldSize; + if (difference == 0) { + d->m_pageSize = count; + } else if (difference > 0) { + beginInsertRows(QModelIndex(), d->m_pageSize, d->m_pageSize + difference - 1); + d->m_pageSize = count; + endInsertRows(); + } else { + beginRemoveRows(QModelIndex(), d->m_pageSize + difference, d->m_pageSize - 1); + d->m_pageSize = count; + endRemoveRows(); + } + Q_EMIT pageSizeChanged(); + } +} + +QAbstractItemModel *PaginateModel::sourceModel() const +{ + return d->m_sourceModel; +} + +void PaginateModel::setSourceModel(QAbstractItemModel *model) +{ + if (d->m_sourceModel) { + disconnect(d->m_sourceModel, nullptr, this, nullptr); + } + + if (model != d->m_sourceModel) { + beginResetModel(); + d->m_sourceModel = model; + if (model) { + connect(d->m_sourceModel, &QAbstractItemModel::rowsAboutToBeInserted, this, &PaginateModel::_k_sourceRowsAboutToBeInserted); + connect(d->m_sourceModel, &QAbstractItemModel::rowsInserted, this, &PaginateModel::_k_sourceRowsInserted); + connect(d->m_sourceModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &PaginateModel::_k_sourceRowsAboutToBeRemoved); + connect(d->m_sourceModel, &QAbstractItemModel::rowsRemoved, this, &PaginateModel::_k_sourceRowsRemoved); + connect(d->m_sourceModel, &QAbstractItemModel::rowsAboutToBeMoved, this, &PaginateModel::_k_sourceRowsAboutToBeMoved); + connect(d->m_sourceModel, &QAbstractItemModel::rowsMoved, this, &PaginateModel::_k_sourceRowsMoved); + + connect(d->m_sourceModel, &QAbstractItemModel::columnsAboutToBeInserted, this, &PaginateModel::_k_sourceColumnsAboutToBeInserted); + connect(d->m_sourceModel, &QAbstractItemModel::columnsInserted, this, &PaginateModel::_k_sourceColumnsInserted); + connect(d->m_sourceModel, &QAbstractItemModel::columnsAboutToBeRemoved, this, &PaginateModel::_k_sourceColumnsAboutToBeRemoved); + connect(d->m_sourceModel, &QAbstractItemModel::columnsRemoved, this, &PaginateModel::_k_sourceColumnsRemoved); + connect(d->m_sourceModel, &QAbstractItemModel::columnsAboutToBeMoved, this, &PaginateModel::_k_sourceColumnsAboutToBeMoved); + connect(d->m_sourceModel, &QAbstractItemModel::columnsMoved, this, &PaginateModel::_k_sourceColumnsMoved); + + connect(d->m_sourceModel, &QAbstractItemModel::dataChanged, this, &PaginateModel::_k_sourceDataChanged); + connect(d->m_sourceModel, &QAbstractItemModel::headerDataChanged, this, &PaginateModel::_k_sourceHeaderDataChanged); + + connect(d->m_sourceModel, &QAbstractItemModel::modelAboutToBeReset, this, &PaginateModel::_k_sourceModelAboutToBeReset); + connect(d->m_sourceModel, &QAbstractItemModel::modelReset, this, &PaginateModel::_k_sourceModelReset); + + connect(d->m_sourceModel, &QAbstractItemModel::rowsInserted, this, &PaginateModel::pageCountChanged); + connect(d->m_sourceModel, &QAbstractItemModel::rowsRemoved, this, &PaginateModel::pageCountChanged); + connect(d->m_sourceModel, &QAbstractItemModel::modelReset, this, &PaginateModel::pageCountChanged); + } + endResetModel(); + Q_EMIT sourceModelChanged(); + } +} + +QHash PaginateModel::roleNames() const +{ + return d->m_sourceModel ? d->m_sourceModel->roleNames() : QAbstractItemModel::roleNames(); +} + +int PaginateModel::rowsByPageSize(int size) const +{ + return d->m_hasStaticRowCount ? size : !d->m_sourceModel ? 0 : qMin(d->m_sourceModel->rowCount() - d->m_firstItem, size); +} + +int PaginateModel::rowCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : rowsByPageSize(d->m_pageSize); +} + +QModelIndex PaginateModel::mapToSource(const QModelIndex &idx) const +{ + if (!d->m_sourceModel) + return QModelIndex(); + return d->m_sourceModel->index(idx.row() + d->m_firstItem, idx.column()); +} + +QModelIndex PaginateModel::mapFromSource(const QModelIndex &idx) const +{ + Q_ASSERT(idx.model() == d->m_sourceModel); + if (!d->m_sourceModel) + return QModelIndex(); + return index(idx.row() - d->m_firstItem, idx.column()); +} + +QVariant PaginateModel::data(const QModelIndex &index, int role) const +{ + if (!d->m_sourceModel) + return QVariant(); + QModelIndex idx = mapToSource(index); + return idx.data(role); +} + +void PaginateModel::firstPage() +{ + setFirstItem(0); +} + +void PaginateModel::lastPage() +{ + setFirstItem((pageCount() - 1) * d->m_pageSize); +} + +void PaginateModel::nextPage() +{ + setFirstItem(d->m_firstItem + d->m_pageSize); +} + +void PaginateModel::previousPage() +{ + setFirstItem(d->m_firstItem - d->m_pageSize); +} + +int PaginateModel::currentPage() const +{ + return d->m_firstItem / d->m_pageSize; +} + +int PaginateModel::pageCount() const +{ + if (!d->m_sourceModel) + return 0; + const int rc = d->m_sourceModel->rowCount(); + const int r = (rc % d->m_pageSize == 0) ? 1 : 0; + return qMax(qCeil(float(rc) / d->m_pageSize) - r, 1); +} + +bool PaginateModel::hasStaticRowCount() const +{ + return d->m_hasStaticRowCount; +} + +void PaginateModel::setStaticRowCount(bool src) +{ + if (src == d->m_hasStaticRowCount) { + return; + } + + beginResetModel(); + d->m_hasStaticRowCount = src; + endResetModel(); + + Q_EMIT staticRowCountChanged(); +} + +////////////////////////////// + +void PaginateModel::_k_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(end) + if (parent.isValid() || start != 0) { + return; + } + beginResetModel(); +} + +void PaginateModel::_k_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + beginResetModel(); +} + +void PaginateModel::_k_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(end) + if (parent.isValid() || start != 0) { + return; + } + beginResetModel(); +} + +void PaginateModel::_k_sourceColumnsInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(end) + if (parent.isValid() || start != 0) { + return; + } + endResetModel(); +} + +void PaginateModel::_k_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + endResetModel(); +} + +void PaginateModel::_k_sourceColumnsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(end) + if (parent.isValid() || start != 0) { + return; + } + endResetModel(); +} + +void PaginateModel::_k_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +{ + if (topLeft.parent().isValid() || bottomRight.row() < d->m_firstItem || topLeft.row() > lastItem()) { + return; + } + + QModelIndex idxTop = mapFromSource(topLeft); + QModelIndex idxBottom = mapFromSource(bottomRight); + if (!idxTop.isValid()) + idxTop = index(0); + if (!idxBottom.isValid()) + idxBottom = index(rowCount() - 1); + + Q_EMIT dataChanged(idxTop, idxBottom, roles); +} + +void PaginateModel::_k_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last) +{ + Q_UNUSED(last) + if (first == 0) + Q_EMIT headerDataChanged(orientation, 0, 0); +} + +void PaginateModel::_k_sourceModelAboutToBeReset() +{ + beginResetModel(); +} + +void PaginateModel::_k_sourceModelReset() +{ + endResetModel(); +} + +bool PaginateModel::isIntervalValid(const QModelIndex &parent, int start, int /*end*/) const +{ + return !parent.isValid() && start <= lastItem(); +} + +bool PaginateModel::canSizeChange() const +{ + return !d->m_hasStaticRowCount && currentPage() == pageCount() - 1; +} + +void PaginateModel::_k_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end) +{ + if (!isIntervalValid(parent, start, end)) { + return; + } + + if (canSizeChange()) { + const int newStart = qMax(start - d->m_firstItem, 0); + const int insertedCount = qMin(end - start, pageSize() - newStart - 1); + beginInsertRows(QModelIndex(), newStart, newStart + insertedCount); + } else { + beginResetModel(); + } +} + +void PaginateModel::_k_sourceRowsInserted(const QModelIndex &parent, int start, int end) +{ + if (!isIntervalValid(parent, start, end)) { + return; + } + + if (canSizeChange()) { + endInsertRows(); + } else { + endResetModel(); + } +} + +void PaginateModel::_k_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + // NOTE could optimize, unsure if it makes sense + beginResetModel(); +} + +void PaginateModel::_k_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + endResetModel(); +} + +void PaginateModel::_k_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + if (!isIntervalValid(parent, start, end)) { + return; + } + + if (canSizeChange()) { + const int removedCount = end - start; + const int newStart = qMax(start - d->m_firstItem, 0); + beginRemoveRows(QModelIndex(), newStart, newStart + removedCount); + } else { + beginResetModel(); + } +} + +void PaginateModel::_k_sourceRowsRemoved(const QModelIndex &parent, int start, int end) +{ + if (!isIntervalValid(parent, start, end)) { + return; + } + + if (canSizeChange()) { + endRemoveRows(); + } else { + beginResetModel(); + } +} + +int PaginateModel::lastItem() const +{ + return d->m_firstItem + rowCount(); +} diff --git a/components/mobileshell/paginatemodel.h b/components/mobileshell/paginatemodel.h new file mode 100644 index 00000000..b8c99b15 --- /dev/null +++ b/components/mobileshell/paginatemodel.h @@ -0,0 +1,122 @@ +/* + * SPDX-FileCopyrightText: 2014 Aleix Pol Gonzalez + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ + +#ifndef PAGINATEMODEL_H +#define PAGINATEMODEL_H + +#include + +/** + * @class PaginateModel + * + * This class can be used to create representations of only a chunk of a model. + * + * With this component it will be possible to create views that only show a page + * of a model, instead of drawing all the elements in the model. + */ +class PaginateModel : public QAbstractListModel +{ + Q_OBJECT + /** Holds the number of elements that will fit in a page */ + Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize NOTIFY pageSizeChanged) + + /** Tells what is the first row shown in the model */ + Q_PROPERTY(int firstItem READ firstItem WRITE setFirstItem NOTIFY firstItemChanged) + + /** The model we will be proxying */ + Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged) + + /** Among the totality of elements, indicates the one we're currently offering */ + Q_PROPERTY(int currentPage READ currentPage NOTIFY firstItemChanged) + + /** Provides the number of pages available, given the sourceModel size */ + Q_PROPERTY(int pageCount READ pageCount NOTIFY pageCountChanged) + + /** If enabled, ensures that pageCount and pageSize are the same. */ + Q_PROPERTY(bool staticRowCount READ hasStaticRowCount WRITE setStaticRowCount NOTIFY staticRowCountChanged) + +public: + explicit PaginateModel(QObject *object = nullptr); + ~PaginateModel() override; + + int pageSize() const; + void setPageSize(int count); + + int firstItem() const; + void setFirstItem(int row); + + /** + * @returns Last visible item. + * + * Convenience function + */ + int lastItem() const; + + QAbstractItemModel *sourceModel() const; + void setSourceModel(QAbstractItemModel *model); + + QModelIndex mapToSource(const QModelIndex &idx) const; + QModelIndex mapFromSource(const QModelIndex &idx) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + int currentPage() const; + int pageCount() const; + QHash roleNames() const override; + + void setStaticRowCount(bool src); + bool hasStaticRowCount() const; + + /** Display the first rows of the model */ + Q_SCRIPTABLE void firstPage(); + + /** Display the rows right after the ones that are currently being served */ + Q_SCRIPTABLE void nextPage(); + + /** Display the rows right before the ones that are currently being served */ + Q_SCRIPTABLE void previousPage(); + + /** Display the last set of rows of the source model */ + Q_SCRIPTABLE void lastPage(); + +private Q_SLOTS: + void _k_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void _k_sourceRowsInserted(const QModelIndex &parent, int start, int end); + void _k_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _k_sourceRowsRemoved(const QModelIndex &parent, int start, int end); + void _k_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + void _k_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + + void _k_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void _k_sourceColumnsInserted(const QModelIndex &parent, int start, int end); + void _k_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _k_sourceColumnsRemoved(const QModelIndex &parent, int start, int end); + void _k_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + void _k_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + + void _k_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); + void _k_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last); + + void _k_sourceModelAboutToBeReset(); + void _k_sourceModelReset(); + +Q_SIGNALS: + void pageSizeChanged(); + void firstItemChanged(); + void sourceModelChanged(); + void pageCountChanged(); + void staticRowCountChanged(); + +private: + bool canSizeChange() const; + bool isIntervalValid(const QModelIndex &parent, int start, int end) const; + int rowsByPageSize(int size) const; + + class PaginateModelPrivate; + QScopedPointer d; +}; + +#endif diff --git a/components/mobileshell/qml/actiondrawer/quicksettings/QuickSettings.qml b/components/mobileshell/qml/actiondrawer/quicksettings/QuickSettings.qml index 8d049503..90130c96 100644 --- a/components/mobileshell/qml/actiondrawer/quicksettings/QuickSettings.qml +++ b/components/mobileshell/qml/actiondrawer/quicksettings/QuickSettings.qml @@ -27,7 +27,7 @@ Item { readonly property real columns: Math.round(Util.applyMinMaxRange(3, 6, width / intendedColumnWidth)) readonly property real columnWidth: Math.floor(width / columns) - readonly property real minimizedColumns: Math.round(Util.applyMinMaxRange(5, 8, width / intendedMinimizedColumnWidth)) + readonly property int minimizedColumns: Math.round(Util.applyMinMaxRange(5, 8, width / intendedMinimizedColumnWidth)) readonly property real minimizedColumnWidth: Math.floor(width / minimizedColumns) readonly property real rowHeight: columnWidth * 0.7 @@ -40,11 +40,31 @@ Item { property real minimizedViewProgress: 0 property real fullViewProgress: 1 - readonly property var quickSettingsModel: MobileShell.QuickSettingsModel {} + readonly property int settingsPerPage: Math.max(6, Math.floor(width/columnWidth) * 2) + readonly property real quickSettingsHeight: 2 * rowHeight + + readonly property MobileShell.QuickSettingsModel quickSettingsModel: MobileShell.QuickSettingsModel {} + + + function resetSwipeView() { + swipeView.currentIndex = 0; + } + + // return to the first page when the action drawer is closed + Connections { + target: actionDrawer + + onOpenedChanged: { + if(!actionDrawer.opened) { + resetSwipeView(); + } + } + } // view when fully open ColumnLayout { id: fullView + height: 1 opacity: root.fullViewProgress visible: opacity !== 0 transform: Translate { y: (1 - fullView.opacity) * root.rowHeight } @@ -53,39 +73,77 @@ Item { anchors.left: parent.left anchors.right: parent.right - // TODO add pages - Flow { - id: flow - spacing: 0 + SwipeView { + id: swipeView + Layout.fillWidth: true - + Layout.preferredHeight: quickSettingsHeight + Repeater { - model: root.quickSettingsModel - delegate: Components.BaseItem { - required property var modelData + model: Math.ceil(quickSettingsModel.count / settingsPerPage) + delegate: Flow { + id: flow + spacing: 0 - height: root.rowHeight - width: root.columnWidth - padding: PlasmaCore.Units.smallSpacing + required property int index - contentItem: QuickSettingsFullDelegate { - restrictedPermissions: actionDrawer.restrictedPermissions - - text: modelData.text - status: modelData.status - icon: modelData.icon - enabled: modelData.enabled - settingsCommand: modelData.settingsCommand - toggleFunction: modelData.toggle - - onCloseRequested: { - actionDrawer.close(); + Repeater { + model: MobileShell.PaginateModel { + sourceModel: quickSettingsModel + pageSize: settingsPerPage + firstItem: settingsPerPage * flow.index + } + delegate: Components.BaseItem { + + required property var modelData + + height: root.rowHeight + width: root.columnWidth + padding: PlasmaCore.Units.smallSpacing + + contentItem: QuickSettingsFullDelegate { + restrictedPermissions: actionDrawer.restrictedPermissions + + text: modelData.text + status: modelData.status + icon: modelData.icon + enabled: modelData.enabled + settingsCommand: modelData.settingsCommand + toggleFunction: modelData.toggle + + onCloseRequested: { + actionDrawer.close(); + } + } } } } } } - + PageIndicator { + id: indicator + + count: swipeView.count + currentIndex: swipeView.currentIndex + + Layout.alignment: Qt.AlignHCenter + + delegate: Rectangle { + implicitWidth: 8 + implicitHeight: 8 + + radius: width / 2 + color: PlasmaCore.Theme.buttonFocusColor + + opacity: index === indicator.currentIndex ? 0.95 : 0.45 + + Behavior on opacity { + OpacityAnimator { + duration: MobileShell.MobileShellSettings.animationsEnabled ? 100 : 0 + } + } + } + } BrightnessItem { id: brightnessItem Layout.topMargin: PlasmaCore.Units.smallSpacing * 2 @@ -109,16 +167,17 @@ Item { anchors.right: parent.right Repeater { - model: root.quickSettingsModel + model: MobileShell.PaginateModel { + sourceModel: quickSettingsModel + pageSize: minimizedColumns + } delegate: Components.BaseItem { required property var modelData - required property var index implicitHeight: root.minimizedRowHeight implicitWidth: root.minimizedColumnWidth horizontalPadding: (width - PlasmaCore.Units.gridUnit * 3) / 2 verticalPadding: (height - PlasmaCore.Units.gridUnit * 3) / 2 - visible: index <= root.minimizedColumns contentItem: QuickSettingsMinimizedDelegate { restrictedPermissions: actionDrawer.restrictedPermissions diff --git a/components/mobileshell/quicksettingsmodel.h b/components/mobileshell/quicksettingsmodel.h index b6924546..6e7ba9d9 100644 --- a/components/mobileshell/quicksettingsmodel.h +++ b/components/mobileshell/quicksettingsmodel.h @@ -21,16 +21,20 @@ class QuickSettingsModel : public QAbstractListModel, public QQmlParserStatus Q_INTERFACES(QQmlParserStatus) QML_ELEMENT + Q_PROPERTY(int count READ rowCount NOTIFY countChanged) + public: QuickSettingsModel(QObject *parent = nullptr); QVariant data(const QModelIndex &index, int role) const override; - int rowCount(const QModelIndex &parent) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; QHash roleNames() const override; void classBegin() override; void componentComplete() override; + Q_SIGNAL void countChanged(); + private: void loadQuickSettings();