From e29052607f9fcd783b72e1c6b06aefa35b961c5b Mon Sep 17 00:00:00 2001 From: hewenfei Date: Mon, 22 Jan 2024 16:03:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(labels):=20=E6=A0=87=E7=AD=BE=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E5=9F=BA=E4=BA=8E=E6=96=B0=E5=90=8E=E7=AB=AF=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qml/AppUI/AppLabelPage.qml | 111 ++++++++++++++++++++ qml/AppUI/AppListActions.qml | 2 +- qml/AppUI/AppListView.qml | 2 +- qml/AppUI/AppPageContent.qml | 95 +++++++++++++++-- qml/AppUI/FullScreenUI.qml | 43 ++++++++ qml/AppUI/qmldir | 1 + qml/qml.qrc | 1 + src/commons.cpp | 46 -------- src/commons.h | 37 ------- src/libappdata/app-category-plugin.cpp | 47 +++++++-- src/libappdata/app-category-plugin.h | 9 ++ src/libappdata/app-group-model.cpp | 14 ++- src/libappdata/app-group-model.h | 2 + src/libappdata/app-list-model.cpp | 26 +++++ src/libappdata/app-list-model.h | 4 + src/libappdata/app-list-plugin.cpp | 64 ++++++++++- src/libappdata/app-list-plugin.h | 51 +++++++++ src/libappdata/recently-installed-model.cpp | 2 +- src/ukui-menu-application.cpp | 1 + 19 files changed, 456 insertions(+), 102 deletions(-) create mode 100644 qml/AppUI/AppLabelPage.qml diff --git a/qml/AppUI/AppLabelPage.qml b/qml/AppUI/AppLabelPage.qml new file mode 100644 index 0000000..0c372ca --- /dev/null +++ b/qml/AppUI/AppLabelPage.qml @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2024, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +import QtQuick 2.12 + +import org.ukui.menu.core 1.0 + +import org.ukui.quick.items 1.0 as UkuiItems +import org.ukui.quick.platform 1.0 as Platform + +GridView { + property var labelBottle: null + property int labelColum: labelBottle === null ? 0 : labelBottle.column + property int labelRow: Math.ceil(count / labelColum) + + signal labelSelected(string label) + + // 默认为小屏幕下尺寸 + width: 200 + height: childrenRect.height + cellWidth: width / labelColum + cellHeight: 40 + + model: labelBottle === null ? [] : labelBottle.labels + delegate: MouseArea { + width: GridView.view.cellWidth + height: GridView.view.cellHeight + focus: true + hoverEnabled: true + + onClicked: { + GridView.view.labelSelected(modelData.label); + GridView.view.currentIndex = model.index + } + + Keys.onPressed: (event) => { + if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { + GridView.view.labelSelected(modelData.label); + } + } + + UkuiItems.StyleBackground { + anchors.fill: parent + + radius: Platform.Theme.normalRadius + useStyleTransparency: false + paletteRole: Platform.Theme.WindowText + alpha: parent.containsPress ? 0.15 : parent.containsMouse ? 0.08 : 0.0 + + border.width: (parent.GridView.isCurrentItem && !mainWindow.isFullScreen) ? 2 : 0 + borderColor: Platform.Theme.Highlight + + Text { + anchors.fill: parent + visible: modelData.type === LabelItem.Text + text: modelData.display + elide: Text.ElideRight + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + + UkuiItems.Icon { + anchors.centerIn: parent + width: parent.height/2 + height: parent.height/2 + visible: modelData.type === LabelItem.Icon + source: modelData.type === LabelItem.Icon ? modelData.display : "" + } + } + } + + Keys.onRightPressed: { + if(currentIndex === count - 1) { + currentIndex = 0; + } else { + currentIndex++; + } + } + Keys.onLeftPressed: { + if(currentIndex === 0) { + currentIndex = count - 1; + } else { + currentIndex--; + } + } + Keys.onDownPressed: { + if(Math.floor(currentIndex / labelColum) < labelRow - 1) { + currentIndex = currentIndex + labelColum; + } + } + Keys.onUpPressed: { + if(Math.floor(currentIndex / labelColum) > 0) { + currentIndex = currentIndex - labelColum; + } + } +} diff --git a/qml/AppUI/AppListActions.qml b/qml/AppUI/AppListActions.qml index d6f7411..94e5f0c 100644 --- a/qml/AppUI/AppListActions.qml +++ b/qml/AppUI/AppListActions.qml @@ -70,7 +70,7 @@ UkuiItems.StyleBackground { } Keys.onPressed: { if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) { - pluginSortButtonRoot.model.changeProvider(0); + modelData.trigger(); } } } diff --git a/qml/AppUI/AppListView.qml b/qml/AppUI/AppListView.qml index bc7a658..f3289d8 100644 --- a/qml/AppUI/AppListView.qml +++ b/qml/AppUI/AppListView.qml @@ -52,7 +52,7 @@ MouseArea { ListView { id: listView - cacheBuffer: itemHeight * listView.count + cacheBuffer: count * root.itemHeight spacing: 4 Layout.fillHeight: true Layout.fillWidth: true diff --git a/qml/AppUI/AppPageContent.qml b/qml/AppUI/AppPageContent.qml index 3de8c24..4351b37 100644 --- a/qml/AppUI/AppPageContent.qml +++ b/qml/AppUI/AppPageContent.qml @@ -29,7 +29,8 @@ Item { if (appList.visible) { appList.resetListFocus(); } else { - selectionPage.viewFocusEnable(); + selectionPage.focus = true; + labelPage.focus = true; } } @@ -51,7 +52,7 @@ Item { AppList { id: appList anchors.fill: parent - visible: true + visible: !selectionPage.visible model: AppPageBackend.appModel view.onContentYChanged: { @@ -61,15 +62,95 @@ Item { appListHeader.title = view.currentSection; } } + + function positionLabel(label) { + let index = model.findLabelIndex(label); + if (index >= 0) { + view.positionViewAtIndex(index, ListView.Beginning) + } + } + + onLabelItemClicked: { + labelPage.labelBottle = AppPageBackend.appModel.labelBottle; + labelPage.currentIndex = 0; + selectionPage.state = "viewShowed"; + } } - SelectionPage { + MouseArea { id: selectionPage anchors.fill: parent - anchors.bottomMargin: 54 - visible: !appList.visible - onViewHideFinished: appList.visible = true - onLabelSelected: appList.labelSelection(labelId) + visible: false + + onClicked: state = "viewHid"; + + state: "viewHid" + states: [ + State { + name: "viewShowed" + changes: [ + PropertyChanges {target: selectionPage; scale: 1; opacity: 1; focus: true } + ] + }, + State { + name: "viewHid" + changes: [ + PropertyChanges {target: selectionPage; scale: 1.5; opacity: 0; focus: false } + ] + } + ] + + transitions: [ + Transition { + from: "*"; to: "viewShowed" + SequentialAnimation { + ScriptAction { script: selectionPage.visible = true; } + NumberAnimation { properties: "scale,opacity"; easing.type: Easing.InOutCubic; duration: 300} + } + }, + Transition { + from: "*"; to: "viewHid" + SequentialAnimation { + NumberAnimation { properties: "scale,opacity"; easing.type: Easing.InOutCubic; duration: 300} + ScriptAction { + script: { + selectionPage.visible = false; + labelPage.labelBottle = null; + labelPage.focus = false; + appList.focus = false; + } + } + } + } + ] + + AppLabelPage { + id: labelPage + anchors.centerIn: parent + interactive: height > parent.height + + onLabelSelected: (label) => { + appList.positionLabel(label); + selectionPage.state = "viewHid"; + } + + onModelChanged: { + currentIndex = -1; + } + } + + function hidePage() { + state = "viewHid"; + visible = false; + } + + Component.onCompleted: { + mainWindow.visibleChanged.connect(hidePage) + } + + Component.onDestruction: { + mainWindow.visibleChanged.disconnect(hidePage) + } } } } diff --git a/qml/AppUI/FullScreenUI.qml b/qml/AppUI/FullScreenUI.qml index fd47b2f..ca42007 100644 --- a/qml/AppUI/FullScreenUI.qml +++ b/qml/AppUI/FullScreenUI.qml @@ -107,17 +107,60 @@ UkuiItems.StyleBackground { anchors.centerIn: parent width: 120 height: parent.height + + AppLabelPage { + id: appLabelPage + anchors.centerIn: parent + + width: parent.width + labelBottle: AppPageBackend.appModel.labelBottle + labelColum: 1 + cellHeight: 34 + + interactive: height > parent.height + highlightMoveDuration: 300 + highlight: UkuiItems.StyleBackground { + width: appLabelPage.cellWidth + height: appLabelPage.cellHeight + useStyleTransparency: false + radius: Platform.Theme.minRadius + paletteRole: Platform.Theme.Light + alpha: 0.15; borderAlpha: 0.5 + border.width: 1 + borderColor: Platform.Theme.Highlight + } + + onLabelSelected: (label) => { + fullScreenAppList.positionLabel(label); + } + } } } // 应用列表: [row: 1, column: 1] FullScreenAppList { + id: fullScreenAppList Layout.row: 1 Layout.column: 1 Layout.fillWidth: true Layout.fillHeight: true sourceModel: AppPageBackend.appModel + + function positionLabel(label) { + let index = model.findLabelIndex(label); + if (index >= 0) { + positionViewAtIndex(index, ListView.Beginning) + } + } + + onContentYChanged: { + // 向下偏移200 + let index = indexAt(10, contentY + 200); + if (index >= 0) { + appLabelPage.currentIndex = index + 1; + } + } } } } diff --git a/qml/AppUI/qmldir b/qml/AppUI/qmldir index fad4b71..fa0fdb5 100644 --- a/qml/AppUI/qmldir +++ b/qml/AppUI/qmldir @@ -15,4 +15,5 @@ FullScreenContent 1.0 FullScreenContent.qml FullScreenFooter 1.0 FullScreenFooter.qml FullScreenAppList 1.0 FullScreenAppList.qml FullScreenAppItem 1.0 FullScreenAppItem.qml +AppLabelPage 1.0 AppLabelPage.qml Folder 1.0 Folder.qml diff --git a/qml/qml.qrc b/qml/qml.qrc index 378958b..89e7a32 100644 --- a/qml/qml.qrc +++ b/qml/qml.qrc @@ -36,5 +36,6 @@ AppUI/AppPageSearch.qml AppUI/FullScreenAppList.qml AppUI/FullScreenAppItem.qml + AppUI/AppLabelPage.qml diff --git a/src/commons.cpp b/src/commons.cpp index 32b29e1..06539d6 100644 --- a/src/commons.cpp +++ b/src/commons.cpp @@ -17,49 +17,3 @@ */ #include "commons.h" - -#include - -// ====== LabelItem ====== // -UkuiMenu::LabelItem::LabelItem(bool disable, int index, QString id, QString displayName) -: m_disable(disable), m_index(index), m_id(std::move(id)), m_displayName(std::move(displayName)) {} - -bool UkuiMenu::LabelItem::isDisable() const -{ - return m_disable; -} - -void UkuiMenu::LabelItem::setDisable(bool disable) -{ - LabelItem::m_disable = disable; -} - -int UkuiMenu::LabelItem::index() const -{ - return m_index; -} - -void UkuiMenu::LabelItem::setIndex(int index) -{ - LabelItem::m_index = index; -} - -const QString &UkuiMenu::LabelItem::displayName() const -{ - return m_id; -} - -void UkuiMenu::LabelItem::setDisplayName(const QString &name) -{ - LabelItem::m_id = name; -} - -const QString &UkuiMenu::LabelItem::id() const -{ - return m_id; -} - -void UkuiMenu::LabelItem::setId(const QString &id) -{ - m_id = id; -} diff --git a/src/commons.h b/src/commons.h index 0dcb2dc..b6562e0 100644 --- a/src/commons.h +++ b/src/commons.h @@ -23,43 +23,6 @@ namespace UkuiMenu { -// 标签项 -class LabelItem -{ - Q_GADGET -public: - enum PropertyName { - IsDisable = 0, - Index, - Id, - DisplayName - }; - LabelItem() = default; - explicit LabelItem(bool disable, int index, QString id, QString displayName); - - friend inline bool operator==(const LabelItem& a, const LabelItem& b) { - return QString::compare(a.id(), b.id(), Qt::CaseInsensitive); - } - - bool isDisable() const; - void setDisable(bool disable); - - int index() const; - void setIndex(int index); - - const QString &id() const; - void setId(const QString &id); - - const QString &displayName() const; - void setDisplayName(const QString &name); - -private: - bool m_disable{true}; - int m_index{0}; - QString m_id; - QString m_displayName; -}; - class Display { Q_GADGET public: diff --git a/src/libappdata/app-category-plugin.cpp b/src/libappdata/app-category-plugin.cpp index 5ca5aba..af3fbd9 100644 --- a/src/libappdata/app-category-plugin.cpp +++ b/src/libappdata/app-category-plugin.cpp @@ -22,6 +22,7 @@ #include "combined-list-model.h" #include "app-category-model.h" #include "recently-installed-model.h" +#include "data-entity.h" #include "event-track.h" #include @@ -30,13 +31,13 @@ namespace UkuiMenu { AppCategoryPlugin::AppCategoryPlugin(QObject *parent) : AppListPluginInterface(parent) - , m_dataModel(new CombinedListModel(this)) + , m_dataModel(new CombinedListModel(this)), m_labelBottle(new LabelBottle(this)) { - auto categoryModel = new AppCategoryModel(this); - auto recentlyModel = new RecentlyInstalledModel(this); + m_categoryModel = new AppCategoryModel(this); + m_recentlyModel = new RecentlyInstalledModel(this); - m_dataModel->insertSubModel(recentlyModel); - m_dataModel->insertSubModel(categoryModel); + m_dataModel->insertSubModel(m_recentlyModel); + m_dataModel->insertSubModel(m_categoryModel); auto categoryAction = new QAction(QIcon::fromTheme("applications-utilities-symbolic"), tr("Category"), this); auto firstLatterAction = new QAction(QIcon::fromTheme("ukui-capslock-symbolic"), tr("Letter Sort"), this); @@ -45,20 +46,22 @@ AppCategoryPlugin::AppCategoryPlugin(QObject *parent) : AppListPluginInterface(p firstLatterAction->setCheckable(true); connect(categoryAction, &QAction::triggered, this, [=] { - categoryModel->setMode(AppCategoryModel::Category); + m_categoryModel->setMode(AppCategoryModel::Category); categoryAction->setChecked(true); firstLatterAction->setChecked(false); setTitle(categoryAction->text()); + updateLabelBottle(); QMap map; map.insert(QStringLiteral("viewName"), QStringLiteral("category")); EventTrack::instance()->sendClickEvent("switch_app_view", "AppView", map); }); connect(firstLatterAction, &QAction::triggered, this, [=] { - categoryModel->setMode(AppCategoryModel::FirstLatter); + m_categoryModel->setMode(AppCategoryModel::FirstLatter); categoryAction->setChecked(false); firstLatterAction->setChecked(true); setTitle(firstLatterAction->text()); + updateLabelBottle(); QMap map; map.insert(QStringLiteral("viewName"), QStringLiteral("letter")); @@ -70,6 +73,7 @@ AppCategoryPlugin::AppCategoryPlugin(QObject *parent) : AppListPluginInterface(p categoryAction->setChecked(true); setTitle(categoryAction->text()); + m_labelBottle->setColumn(2); } QString AppCategoryPlugin::name() @@ -107,4 +111,33 @@ void AppCategoryPlugin::setTitle(const QString &title) Q_EMIT titleChanged(); } +LabelBottle *AppCategoryPlugin::labelBottle() +{ + updateLabelBottle(); + return m_labelBottle; +} + +void AppCategoryPlugin::updateLabelBottle() +{ + QList labels; + if (m_recentlyModel->rowCount() > 0) { + labels << LabelItem(tr("Recently Installed"), "search-symbolic", LabelItem::Icon); + } + + QHash groups; + int rowCount = m_categoryModel->rowCount(); + for (int row = 0; row < rowCount; ++row) { + QString group = m_categoryModel->index(row, 0, QModelIndex()).data(DataEntity::Group).toString(); + if (groups.contains(group)) { + continue; + } + + groups.insert(group, 0); + labels.append(LabelItem(group, group)); + } + + m_labelBottle->setLabels(labels); + m_labelBottle->setColumn(m_categoryModel->mode() == AppCategoryModel::FirstLatter ? 5 : 2); +} + } // UkuiMenu diff --git a/src/libappdata/app-category-plugin.h b/src/libappdata/app-category-plugin.h index 74b72ee..9d7e1de 100644 --- a/src/libappdata/app-category-plugin.h +++ b/src/libappdata/app-category-plugin.h @@ -26,6 +26,8 @@ namespace UkuiMenu { class CombinedListModel; +class AppCategoryModel; +class RecentlyInstalledModel; class AppCategoryPlugin : public AppListPluginInterface { @@ -38,13 +40,20 @@ public: QString title() override; QList actions() override; QAbstractItemModel *dataModel() override; + LabelBottle *labelBottle() override; private: void setTitle(const QString &title); + void updateLabelBottle(); private: QString m_title; QList m_actions; + LabelBottle *m_labelBottle {nullptr}; + + AppCategoryModel *m_categoryModel {nullptr}; + RecentlyInstalledModel *m_recentlyModel {nullptr}; + CombinedListModel *m_dataModel {nullptr}; }; diff --git a/src/libappdata/app-group-model.cpp b/src/libappdata/app-group-model.cpp index debe302..4974175 100644 --- a/src/libappdata/app-group-model.cpp +++ b/src/libappdata/app-group-model.cpp @@ -194,7 +194,7 @@ QVariant AppGroupModel::data(const QModelIndex &proxyIndex, int role) const return QAbstractProxyModel::data(proxyIndex, role); } - if (role == DataEntity::Name) { + if (role == DataEntity::Name || role == DataEntity::Group) { return sourceModel()->index(m_groups.at(proxyIndex.row())->first(), 0).data(DataEntity::Group); } @@ -345,4 +345,16 @@ void AppGroupModel::onRowsAboutToBeRemoved(const QModelIndex &parent, int first, } } +int AppGroupModel::findLabelIndex(const QString &label) const +{ + int rowCount = AppGroupModel::rowCount(QModelIndex()); + for (int i = 0; i < rowCount; ++i) { + if (index(i, 0, QModelIndex()).data(DataEntity::Group).toString() == label) { + return i; + } + } + + return -1; +} + } // UkuiMenu diff --git a/src/libappdata/app-group-model.h b/src/libappdata/app-group-model.h index 4d70636..52411bb 100644 --- a/src/libappdata/app-group-model.h +++ b/src/libappdata/app-group-model.h @@ -54,6 +54,8 @@ public: QHash roleNames() const override; QVariant data(const QModelIndex &proxyIndex, int role) const override; + Q_INVOKABLE int findLabelIndex(const QString &label) const; + private Q_SLOTS: void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles); void onLayoutChanged(const QList &parents, QAbstractItemModel::LayoutChangeHint hint); diff --git a/src/libappdata/app-list-model.cpp b/src/libappdata/app-list-model.cpp index 2b85098..8b051ac 100644 --- a/src/libappdata/app-list-model.cpp +++ b/src/libappdata/app-list-model.cpp @@ -128,6 +128,8 @@ void AppListModel::installPlugin(AppListPluginInterface *plugin) connect(m_plugin, &AppListPluginInterface::titleChanged, this, [this, plugin] { m_header->setTitle(plugin->title()); }); + + Q_EMIT labelBottleChanged(); } void AppListModel::unInstallPlugin() @@ -141,6 +143,8 @@ void AppListModel::unInstallPlugin() QSortFilterProxyModel::setSourceModel(nullptr); disconnect(m_plugin, nullptr, this, nullptr); m_plugin = nullptr; + + Q_EMIT labelBottleChanged(); } void AppListModel::openMenu(const int &index, MenuInfo::Location location) const @@ -151,4 +155,26 @@ void AppListModel::openMenu(const int &index, MenuInfo::Location location) const } } +LabelBottle *AppListModel::labelBottle() const +{ + if (m_plugin) { + return m_plugin->labelBottle(); + } + + return nullptr; +} + +int AppListModel::findLabelIndex(const QString &label) const +{ + // TODO: 潜在的优化空间 + int count = AppListModel::rowCount(); + for (int i = 0; i < count; ++i) { + if (AppListModel::sourceModel()->index(i, 0).data(DataEntity::Group).toString() == label) { + return i; + } + } + + return -1; +} + } // UkuiMenu diff --git a/src/libappdata/app-list-model.h b/src/libappdata/app-list-model.h index a2df63d..9fd11ad 100644 --- a/src/libappdata/app-list-model.h +++ b/src/libappdata/app-list-model.h @@ -71,6 +71,7 @@ class AppListModel : public QSortFilterProxyModel { Q_OBJECT Q_PROPERTY(UkuiMenu::AppListHeader *header READ getHeader NOTIFY headerChanged) + Q_PROPERTY(UkuiMenu::LabelBottle *labelBottle READ labelBottle NOTIFY labelBottleChanged) public: explicit AppListModel(QObject *parent = nullptr); @@ -81,15 +82,18 @@ public: QHash roleNames() const override; AppListHeader *getHeader() const; + LabelBottle *labelBottle() const; void installPlugin(AppListPluginInterface *plugin); // reset void unInstallPlugin(); Q_INVOKABLE void openMenu(const int &index, MenuInfo::Location location) const; + Q_INVOKABLE int findLabelIndex(const QString &label) const; Q_SIGNALS: void headerChanged(); + void labelBottleChanged(); private: AppListHeader *m_header {nullptr}; diff --git a/src/libappdata/app-list-plugin.cpp b/src/libappdata/app-list-plugin.cpp index e321fa3..eeab72c 100644 --- a/src/libappdata/app-list-plugin.cpp +++ b/src/libappdata/app-list-plugin.cpp @@ -20,13 +20,15 @@ #include "app-list-plugin.h" #include +#include namespace UkuiMenu { // ====== AppListPluginInterface ====== // AppListPluginInterface::AppListPluginInterface(QObject *parent) : QObject(parent) { - + qRegisterMetaType("LabelItem"); + qRegisterMetaType("LabelBottle*"); } void AppListPluginInterface::search(const QString &keyword) @@ -34,4 +36,64 @@ void AppListPluginInterface::search(const QString &keyword) Q_UNUSED(keyword) } +LabelBottle *AppListPluginInterface::labelBottle() +{ + return nullptr; +} + +// ====== LabelItem ====== // +LabelItem::LabelItem(QString labelName, QString displayName, LabelItem::Type type) + : m_type(type), m_labelName(std::move(labelName)), m_displayName(std::move(displayName)) +{ + +} + +QString LabelItem::labelName() const +{ + return m_labelName; +} + +LabelItem::Type LabelItem::type() const +{ + return m_type; +} + +QString LabelItem::displayName() const +{ + return m_displayName; +} + +// ====== LabelBottle ====== // +LabelBottle::LabelBottle(QObject *parent) : QObject(parent) +{ + +} + +int LabelBottle::column() const +{ + return m_column; +} + +QList LabelBottle::labels() const +{ + return m_labels; +} + +void LabelBottle::setColumn(int column) +{ + if (m_column == column) { + return; + } + + m_column = column; + Q_EMIT columnChanged(); +} + +void LabelBottle::setLabels(const QList &labels) +{ + m_labels.clear(); + m_labels.append(labels); + Q_EMIT labelsChanged(); +} + } // UkuiMenu diff --git a/src/libappdata/app-list-plugin.h b/src/libappdata/app-list-plugin.h index 53f56ca..057503f 100644 --- a/src/libappdata/app-list-plugin.h +++ b/src/libappdata/app-list-plugin.h @@ -29,6 +29,54 @@ class QAbstractItemModel; namespace UkuiMenu { +class LabelItem +{ + Q_GADGET + Q_PROPERTY(UkuiMenu::LabelItem::Type type READ type) + Q_PROPERTY(QString label READ labelName) + Q_PROPERTY(QString display READ displayName) +public: + enum Type { + Text, + Icon + }; + Q_ENUM(Type) + + explicit LabelItem(QString labelName = "", QString displayName = "", Type type = Text); + + Type type() const; + QString labelName() const; + QString displayName() const; + +private: + Type m_type; + QString m_labelName; + QString m_displayName; +}; + +class LabelBottle : public QObject +{ + Q_OBJECT + Q_PROPERTY(int column READ column NOTIFY columnChanged) + Q_PROPERTY(QList labels READ labels NOTIFY labelsChanged) +public: + explicit LabelBottle(QObject *parent = nullptr); + + int column() const; + QList labels() const; + + void setColumn(int column); + void setLabels(const QList &labels); + +Q_SIGNALS: + void columnChanged(); + void labelsChanged(); + +private: + int m_column {2}; + QList m_labels; +}; + class AppListPluginGroup { Q_GADGET @@ -52,6 +100,7 @@ public: virtual QList actions() = 0; virtual QAbstractItemModel *dataModel() = 0; virtual void search(const QString &keyword); + virtual LabelBottle *labelBottle(); Q_SIGNALS: void titleChanged(); @@ -60,5 +109,7 @@ Q_SIGNALS: } // UkuiMenu Q_DECLARE_METATYPE(UkuiMenu::AppListPluginGroup::Group) +Q_DECLARE_METATYPE(UkuiMenu::LabelItem) +Q_DECLARE_METATYPE(UkuiMenu::LabelBottle*) #endif //UKUI_MENU_APP_LIST_PLUGIN_H diff --git a/src/libappdata/recently-installed-model.cpp b/src/libappdata/recently-installed-model.cpp index cf5cb96..7c383a9 100644 --- a/src/libappdata/recently-installed-model.cpp +++ b/src/libappdata/recently-installed-model.cpp @@ -86,7 +86,7 @@ bool RecentlyInstalledModel::event(QEvent *event) QVariant RecentlyInstalledModel::data(const QModelIndex &index, int role) const { if (role == DataEntity::Group) { - return QStringLiteral("RecentlyInstalled"); + return tr("Recently Installed"); } return QSortFilterProxyModel::data(index, role); diff --git a/src/ukui-menu-application.cpp b/src/ukui-menu-application.cpp index e0ca741..d23bcdb 100644 --- a/src/ukui-menu-application.cpp +++ b/src/ukui-menu-application.cpp @@ -74,6 +74,7 @@ void UkuiMenuApplication::registerQmlTypes() qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "Display", "Use enums only."); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataType", "Use enums only"); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "MenuInfo", "Use enums only."); + qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "LabelItem", "Use enums only."); // qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataEntity", "unknown"); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "EventTrack", "Attached only.");