ukui-menu/qml/AppUI/FullScreenUI.qml

275 lines
10 KiB
QML
Raw Normal View History

2022-12-23 11:32:21 +08:00
import QtQuick 2.0
2023-03-17 17:25:50 +08:00
import QtQuick.Layouts 1.12
import QtQml.Models 2.12
2023-03-20 15:33:32 +08:00
import org.ukui.menu.core 1.0
import "../extensions" as Extension
import AppControls2 1.0 as AppControls2
import org.ukui.quick.items 1.0 as UkuiItems
import org.ukui.quick.platform 1.0 as Platform
2023-03-20 15:33:32 +08:00
FocusScope {
id: fullScreenUI
2024-01-09 07:31:27 +08:00
Component.onCompleted: {
forceFocus();
mainWindow.visibleChanged.connect(forceFocus);
}
Component.onDestruction: {
mainWindow.visibleChanged.disconnect(forceFocus);
}
function forceFocus() {
fullScreenUI.focus = true;
if (mainWindow.visible) {
searchInputBar.textInputFocus();
}
}
Item {
anchors.fill: parent
MouseArea {
anchors.fill: parent
onClicked: {
if (mainWindow.editMode) {
mainWindow.editMode = false;
2024-02-06 09:54:18 +08:00
} else {
if (mainContainer.visible) {
//执行全屏退出操作
mainWindow.hide();
} else {
folderLoader.isFolderOpened = false;
}
2024-02-06 09:54:18 +08:00
}
}
}
2023-03-20 15:33:32 +08:00
Extension.FullScreenFolder {
id: folderLoader
anchors.fill: parent
folderModel: FolderModel
Component.onCompleted: fullScreenAppList.openFolderSignal.connect(initFolder)
Component.onDestruction: fullScreenAppList.openFolderSignal.disconnect(initFolder)
}
Item {
id: mainContainer
anchors.fill: parent
z: 10
state: !fullScreenAppList.isContentShow ? "contentShow" : "contentHidden"
states: [
State {
name: "contentHidden"
PropertyChanges { target: mainContainer; opacity: 0; scale: 0.95 }
},
State {
name: "contentShow"
PropertyChanges { target: mainContainer; opacity: 1; scale: 1 }
}
]
transitions: [
Transition {
to:"contentHidden"
SequentialAnimation {
PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic }
ScriptAction { script: mainContainer.visible = false }
}
},
Transition {
to: "contentShow"
SequentialAnimation {
ScriptAction { script: mainContainer.visible = true }
PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic }
}
}
]
// 两行三列
GridLayout {
anchors.fill: parent
// anchors.margins: 36
anchors.leftMargin: 36
anchors.topMargin: 36
anchors.rightMargin: 36
anchors.bottomMargin: 5
rowSpacing: 5
columnSpacing: 5
rows: 2
columns: 3
// 应用列表模式选择按钮: [row: 0, column: 0] [rowspan: 2, columnSpan: 1]
Item {
Layout.row: 0
Layout.column: 0
Layout.preferredWidth: Math.max(actionsItem.width, labelsItem.width)
Layout.preferredHeight: 40
// TODO: 设计最小保持宽度
AppListActions {
id: actionsItem
anchors.centerIn: parent
height: parent.height
actions: AppPageBackend.appModel.header.actions
visible: count > 0
}
2024-01-09 07:31:27 +08:00
}
// 搜索框: [row: 0, column: 1]
Item {
Layout.row: 0
Layout.column: 1
Layout.fillWidth: true
Layout.preferredHeight: 40
SearchInputBar {
id: searchInputBar
width: 372; height: 36
anchors.centerIn: parent
radius: Platform.Theme.minRadius
visible: opacity
onTextChanged: {
if (text === "") {
AppPageBackend.group = PluginGroup.Display;
} else {
AppPageBackend.group = PluginGroup.Search;
AppPageBackend.startSearch(text);
}
2024-01-09 07:31:27 +08:00
}
Component.onCompleted: {
text = root.currentSearchText;
}
2024-01-09 07:31:27 +08:00
}
}
2022-12-23 11:32:21 +08:00
// 右侧按钮区域: [row: 0, column: 2] [rowspan: 2, columnSpan: 1]
Sidebar {
Layout.row: 0
Layout.column: 2
Layout.rowSpan: 2
Layout.columnSpan: 1
Layout.preferredWidth: 60
Layout.fillHeight: true
}
2024-01-09 07:31:27 +08:00
// 左侧标签列表: [row: 1, column: 0]
2024-01-09 07:31:27 +08:00
Item {
Layout.row: 1
Layout.column: 0
Layout.preferredWidth: Math.max(actionsItem.width, labelsItem.width)
Layout.fillHeight: true
Item {
id: labelsItem
anchors.centerIn: parent
width: 120
height: parent.height
clip: true
AppLabelPage {
id: appLabelPage
anchors.centerIn: parent
height: (contentHeight > parent.height) ? parent.height : contentHeight
width: parent.width
labelBottle: AppPageBackend.appModel.labelBottle
labelColum: 1
cellHeight: 34
// TODO: 潜在的优化点尝试组合widget的model和应用model
model: {
if (labelBottle !== null) {
let labelItems = [], i = 0, item = null;
let widgetInfos = fullScreenAppList.headerItem.widgetInfos;
for (i = 0; i < widgetInfos.length; ++i) {
item = widgetInfos[i];
labelItems.push({label: item.label, type: item.type, display: item.display});
}
let labels = labelBottle.labels;
for (i = 0; i < labels.length; ++i) {
item = labels[i];
labelItems.push({label: item.label, type: item.type, display: item.display});
}
return labelItems;
}
return [];
}
boundsBehavior: Flickable.StopAtBounds
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
isContentShow: folderLoader.isFolderOpened
function positionLabel(label) {
// 如果是Widget那么直接滚动到最顶上
// console.log("=positionLabel=", label)
if (headerItem.widgets.includes(label)) {
positionViewAtBeginning();
} else {
let index = model.findLabelIndex(label);
if (index >= 0) {
positionViewAtIndex(index, ListView.Beginning)
}
}
}
2024-01-09 07:31:27 +08:00
onContentYChanged: {
// 向下偏移200, 计算偏移后在那个item里
let index = indexAt(10, contentY + 200);
if (index >= 0) {
appLabelPage.currentIndex = index + headerItem.widgetCount;
} else if (contentY < 0) {
appLabelPage.currentIndex = 0;
}
}
Component.onCompleted: {
positionViewAtBeginning();
folderLoader.turnPageFinished.connect(contentShowFinished)
}
Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished)
}
2024-01-09 07:31:27 +08:00
}
2022-12-23 11:32:21 +08:00
}
}
2022-12-23 11:32:21 +08:00
}