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.");