fix(labels): 标签界面基于新后端实现
This commit is contained in:
parent
fba597ce54
commit
e29052607f
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ MouseArea {
|
|||
|
||||
ListView {
|
||||
id: listView
|
||||
cacheBuffer: itemHeight * listView.count
|
||||
cacheBuffer: count * root.itemHeight
|
||||
spacing: 4
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
SelectionPage {
|
||||
onLabelItemClicked: {
|
||||
labelPage.labelBottle = AppPageBackend.appModel.labelBottle;
|
||||
labelPage.currentIndex = 0;
|
||||
selectionPage.state = "viewShowed";
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -36,5 +36,6 @@
|
|||
<file>AppUI/AppPageSearch.qml</file>
|
||||
<file>AppUI/FullScreenAppList.qml</file>
|
||||
<file>AppUI/FullScreenAppItem.qml</file>
|
||||
<file>AppUI/AppLabelPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -17,49 +17,3 @@
|
|||
*/
|
||||
|
||||
#include "commons.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
// ====== 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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 <QAction>
|
||||
|
@ -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<QString, QVariant> 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<QString, QVariant> 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<LabelItem> labels;
|
||||
if (m_recentlyModel->rowCount() > 0) {
|
||||
labels << LabelItem(tr("Recently Installed"), "search-symbolic", LabelItem::Icon);
|
||||
}
|
||||
|
||||
QHash<QString, int> 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
|
||||
|
|
|
@ -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<QAction *> actions() override;
|
||||
QAbstractItemModel *dataModel() override;
|
||||
LabelBottle *labelBottle() override;
|
||||
|
||||
private:
|
||||
void setTitle(const QString &title);
|
||||
void updateLabelBottle();
|
||||
|
||||
private:
|
||||
QString m_title;
|
||||
QList<QAction *> m_actions;
|
||||
LabelBottle *m_labelBottle {nullptr};
|
||||
|
||||
AppCategoryModel *m_categoryModel {nullptr};
|
||||
RecentlyInstalledModel *m_recentlyModel {nullptr};
|
||||
|
||||
CombinedListModel *m_dataModel {nullptr};
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
QHash<int, QByteArray> 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<int> &roles);
|
||||
void onLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<int, QByteArray> 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};
|
||||
|
|
|
@ -20,13 +20,15 @@
|
|||
|
||||
#include "app-list-plugin.h"
|
||||
#include <QDebug>
|
||||
#include <utility>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
// ====== AppListPluginInterface ====== //
|
||||
AppListPluginInterface::AppListPluginInterface(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
qRegisterMetaType<UkuiMenu::LabelItem>("LabelItem");
|
||||
qRegisterMetaType<UkuiMenu::LabelBottle*>("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<UkuiMenu::LabelItem> 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<UkuiMenu::LabelItem> &labels)
|
||||
{
|
||||
m_labels.clear();
|
||||
m_labels.append(labels);
|
||||
Q_EMIT labelsChanged();
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
||||
|
|
|
@ -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<UkuiMenu::LabelItem> labels READ labels NOTIFY labelsChanged)
|
||||
public:
|
||||
explicit LabelBottle(QObject *parent = nullptr);
|
||||
|
||||
int column() const;
|
||||
QList<UkuiMenu::LabelItem> labels() const;
|
||||
|
||||
void setColumn(int column);
|
||||
void setLabels(const QList<UkuiMenu::LabelItem> &labels);
|
||||
|
||||
Q_SIGNALS:
|
||||
void columnChanged();
|
||||
void labelsChanged();
|
||||
|
||||
private:
|
||||
int m_column {2};
|
||||
QList<LabelItem> m_labels;
|
||||
};
|
||||
|
||||
class AppListPluginGroup
|
||||
{
|
||||
Q_GADGET
|
||||
|
@ -52,6 +100,7 @@ public:
|
|||
virtual QList<QAction*> 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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -74,6 +74,7 @@ void UkuiMenuApplication::registerQmlTypes()
|
|||
qmlRegisterUncreatableType<Display>(uri, versionMajor, versionMinor, "Display", "Use enums only.");
|
||||
qmlRegisterUncreatableType<UkuiMenu::DataType>(uri, versionMajor, versionMinor, "DataType", "Use enums only");
|
||||
qmlRegisterUncreatableType<UkuiMenu::MenuInfo>(uri, versionMajor, versionMinor, "MenuInfo", "Use enums only.");
|
||||
qmlRegisterUncreatableType<UkuiMenu::LabelItem>(uri, versionMajor, versionMinor, "LabelItem", "Use enums only.");
|
||||
// qmlRegisterUncreatableType<UkuiMenu::DataEntity>(uri, versionMajor, versionMinor, "DataEntity", "unknown");
|
||||
|
||||
qmlRegisterUncreatableType<EventTrack>(uri, versionMajor, versionMinor, "EventTrack", "Attached only.");
|
||||
|
|
Loading…
Reference in New Issue