diff --git a/qml/AppControls2/IconLabel.qml b/qml/AppControls2/IconLabel.qml
index f3ffe53..a4e2245 100644
--- a/qml/AppControls2/IconLabel.qml
+++ b/qml/AppControls2/IconLabel.qml
@@ -1,5 +1,7 @@
import QtQuick 2.0
import org.ukui.menu.core 1.0
+import org.ukui.quick.platform 1.0 as Platform
+import org.ukui.quick.items 1.0 as UkuiItems
Item {
id: root
@@ -66,10 +68,10 @@ Item {
cache: false
}
- StyleText {
+ UkuiItems.StyleText {
id: iconText
text: root.appName
elide: Text.ElideRight
- paletteRole: root.textHighLight ? Palette.HighlightedText : Palette.Text
+ paletteRole: root.textHighLight ? Platform.Theme.HighlightedText : Platform.Theme.Text
}
}
diff --git a/qml/AppUI/EditText.qml b/qml/AppUI/EditText.qml
index 2a91d61..c3d3afd 100644
--- a/qml/AppUI/EditText.qml
+++ b/qml/AppUI/EditText.qml
@@ -28,7 +28,8 @@ Item {
property bool textCenterIn: false
property bool editStatus: false
property string textEdited: title
- property bool isFullScreenFolder: false
+ property bool isFullScreen: false
+ property bool isFolder: false
property real textInputSize: 14
Component {
@@ -39,9 +40,13 @@ Item {
horizontalAlignment: contain.textCenterIn ? Text.AlignHCenter : Text.AlignLeft
elide: Text.ElideRight
text: contain.textEdited
- paletteRole: isFullScreenFolder ? Platform.Theme.HighlightedText : Platform.Theme.Text
- font.bold: !isFullScreenFolder
- font.pointSize: isFullScreenFolder ? textUltra : systemFontSize
+ paletteRole: isFullScreen ? Platform.Theme.HighlightedText : Platform.Theme.Text
+ font.bold: !isFolder
+ // AppControls2 StyleText
+ property real textUltra: 2*systemFontSize
+ property real systemFontSize: 10
+
+ font.pointSize: isFolder ? textUltra : systemFontSize
MouseArea {
id: textArea
@@ -78,7 +83,7 @@ Item {
text: contain.textEdited
selectByMouse: true
maximumLength: 14
- font.bold: !isFullScreenFolder
+ font.bold: !isFolder
font.pointSize: contain.textInputSize
onEditingFinished: {
@@ -87,7 +92,7 @@ Item {
contain.editStatus = false;
}
- property int textColor: isFullScreenFolder ? Palette.HighlightedText : Palette.Text
+ property int textColor: isFullScreen ? Palette.HighlightedText : Palette.Text
function updateTextInputColor() {
color = themePalette.paletteColor(textColor);
selectionColor = themePalette.paletteColor(Palette.Highlight);
diff --git a/qml/AppUI/FullScreenFolder.qml b/qml/AppUI/Folder.qml
similarity index 95%
rename from qml/AppUI/FullScreenFolder.qml
rename to qml/AppUI/Folder.qml
index 26ab7ca..01affd4 100644
--- a/qml/AppUI/FullScreenFolder.qml
+++ b/qml/AppUI/Folder.qml
@@ -35,7 +35,8 @@ Loader {
property int viewMaxRow: 0
property bool isFolderOpened: false
- property int margins: 20
+ property bool isFullScreen: true
+ property int margins: isFullScreen? 20 : 0
property int animationDuration: 300
property bool mouseEnable: false
signal turnPageFinished()
@@ -72,17 +73,17 @@ Loader {
name: "folderOpened"
PropertyChanges {
target: folderIconBase
- width: 720
- height: viewMaxRow * 170 + margins * 2
+ width: isFullScreen ? 720 : 348
+ height: isFullScreen ? (viewMaxRow * 170 + margins * 2) : (viewMaxRow * 85 + margins * 2)
radius: Platform.Theme.maxRadius
gridViewMargin: margins
- x: (parent.width - width) / 2
- y: (parent.height - height) / 2
+ x: isFullScreen ? (parent.width - width) / 2 : 56
+ y: isFullScreen ? (parent.height - height) / 2 : 104
// 内部图标尺寸和布局
- folderIconSize: 96
+ folderIconSize:isFullScreen ? 96 : 48
iconSpacing: 8
- imageX: 37
- imageY: 17
+ imageX: isFullScreen ? 37 : 13
+ imageY: isFullScreen ? 17 : 8
}
PropertyChanges { target: folderNameText; opacity: 1 }
},
@@ -275,7 +276,7 @@ Loader {
}
onClicked: {
if (mouse.button === Qt.RightButton) {
- menuManager.showMenu(id, MenuInfo.FullScreenFolder);
+ menuManager.showMenu(id, MenuInfo.Folder);
return;
}
if (mouse.button === Qt.LeftButton) {
@@ -299,7 +300,8 @@ Loader {
height: 47; width: folderIconBase.width
textEdited: folderName
textCenterIn: true
- isFullScreenFolder: true
+ isFolder: true
+ isFullScreen: isFullScreen
}
}
}
diff --git a/qml/AppUI/FullScreenUI.qml b/qml/AppUI/FullScreenUI.qml
index 91d4438..e048d9c 100644
--- a/qml/AppUI/FullScreenUI.qml
+++ b/qml/AppUI/FullScreenUI.qml
@@ -45,7 +45,7 @@ UkuiItems.StyleBackground {
Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished)
}
- FullScreenFolder {
+ Folder {
id: folderLoader
anchors.fill: parent
Component.onCompleted: fullScreenContent.openFolderSignal.connect(initFolder)
diff --git a/qml/AppUI/qmldir b/qml/AppUI/qmldir
index edf547f..bae0b10 100644
--- a/qml/AppUI/qmldir
+++ b/qml/AppUI/qmldir
@@ -12,3 +12,4 @@ PluginSelectButton 1.0 PluginSelectButton.qml
FullScreenHeader 1.0 FullScreenHeader.qml
FullScreenContent 1.0 FullScreenContent.qml
FullScreenFooter 1.0 FullScreenFooter.qml
+Folder 1.0 Folder.qml
diff --git a/qml/extensions/FavoriteExtension.qml b/qml/extensions/FavoriteExtension.qml
index 31fa758..6cd6b09 100644
--- a/qml/extensions/FavoriteExtension.qml
+++ b/qml/extensions/FavoriteExtension.qml
@@ -24,17 +24,20 @@ import org.ukui.menu.extension 1.0
import AppControls2 1.0 as AppControls2
import org.ukui.quick.platform 1.0 as Platform
import org.ukui.quick.items 1.0 as UkuiItems
+import AppUI 1.0 as AppUI
UkuiMenuExtension {
- Component.onCompleted: {
- visualModel.model = extensionData.favoriteAppsModel
- }
-
MouseArea {
id: viewMouseArea
anchors.fill: parent
hoverEnabled: true
+ onClicked: {
+ folderLoader.isFolderOpened = false;
+ favoriteView.visible = true;
+ favoriteView.isContentShow = true;
+ }
+
UkuiItems.StyleBackground {
anchors.top: parent.top
width: parent.width; height: 1
@@ -45,187 +48,26 @@ UkuiMenuExtension {
z: 1
}
- GridView {
+ AppUI.Folder {
+ id: folderLoader
+ anchors.fill: parent
+
+ isFullScreen: false
+ Component.onCompleted: favoriteView.openFolderSignal.connect(initFolder)
+ Component.onDestruction: favoriteView.openFolderSignal.disconnect(initFolder)
+ }
+
+ FavoriteGridView {
id: favoriteView
anchors.fill: parent
anchors.leftMargin: 16
anchors.topMargin: 12
anchors.bottomMargin: 6
- cellWidth: itemHeight + spacing; cellHeight: cellWidth
- property int exchangedStartIndex: 0
- property int spacing: 4
- property int itemHeight: 104
- property int column: Math.floor(width / cellWidth)
-
- // 按键导航处理(左右键可以循环)
- focus: true
- onActiveFocusChanged: currentIndex = 0
- onCountChanged: currentIndex = 0
- Keys.onRightPressed: {
- if(currentIndex === count - 1) {
- currentIndex = 0;
- return;
- }
- currentIndex++;
+ Component.onCompleted: {
+ favoriteView.viewModel.model = extensionData.favoriteAppsModel
+ folderLoader.turnPageFinished.connect(contentShowFinished)
}
- Keys.onLeftPressed: {
- if(currentIndex === 0) {
- currentIndex = count - 1;
- return;
- }
- currentIndex--;
- }
- Keys.onDownPressed: {
- if(currentIndex > count - 1 - column) {
- return;
- }
- currentIndex = currentIndex + column;
- }
- Keys.onUpPressed: {
- if(currentIndex < column) {
- return;
- }
- currentIndex = currentIndex - column;
- }
-
- ScrollBar.vertical: AppControls2.ScrollBar {
- id: scrollBar
- visible: viewMouseArea.containsMouse
- width: 14; height: favoriteView.height
- }
-
- displaced: Transition {
- NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 }
- }
-
- model: DelegateModel {
- id: visualModel
- delegate: DropArea {
- id: delegateRoot
- property int visualIndex: DelegateModel.itemsIndex
- width: favoriteView.cellWidth; height: favoriteView.cellHeight
- onEntered: {
- visualModel.items.move(drag.source.visualIndex, icon.visualIndex)
- }
- Binding { target: icon; property: "visualIndex"; value: visualIndex }
-
- focus: true
- Keys.onReturnPressed: {
- var data = {"id": model.id};
- send(data);
- }
- states: State {
- when: delegateRoot.activeFocus
- PropertyChanges {
- target: icon
- alpha: 0.6
- }
- }
- UkuiItems.StyleBackground {
- id: icon
- height: favoriteView.itemHeight; width: height
- property bool hold: false
- property int visualIndex: 0
- x: 0; y: 0
- radius: Platform.Theme.maxRadius
- useStyleTransparency: false
- scale: icon.hold ? 1.1 :1.0
- alpha: control.containsPress ? 0.75 : control.containsMouse ? 0.6 : 0.40
-
- Behavior on scale {
- NumberAnimation { duration: 300; easing.type: Easing.InOutCubic }
- }
- AppControls2.IconLabel {
- height: icon.height
- width: icon.width - 14
- anchors.centerIn: parent
- appName: model.name
- appIcon: model.icon
- display: Display.TextUnderIcon
- scale: (control.containsPress && !icon.hold) ? 1.1 : 1.0
- ToolTip.visible: textTruncated && control.containsMouse
- ToolTip.text: model.name
- ToolTip.delay: 500
-
- Behavior on scale {
- NumberAnimation { duration: 300; easing.type: Easing.InOutCubic }
- }
- }
-
- MouseArea {
- id: control
- anchors.fill: parent
- hoverEnabled: true
- pressAndHoldInterval: 300
- acceptedButtons: Qt.LeftButton | Qt.RightButton
-
- onClicked: {
- if (mouse.button === Qt.RightButton) {
- visualModel.model.openMenu(index)
- } else if (mouse.button === Qt.LeftButton) {
- var data = {"id": model.id};
- send(data);
- }
- }
- onPressAndHold: {
- if (mouse.button === Qt.LeftButton) {
- drag.target = icon;
- icon.hold = true;
- favoriteView.exchangedStartIndex = icon.visualIndex;
- }
- }
- onReleased: {
- icon.hold = false;
- drag.target = null;
- }
- }
-
- onHoldChanged: {
- if (hold) {
- favoriteView.interactive = false;
- } else {
- favoriteView.interactive = true;
- visualModel.model.exchangedAppsOrder(favoriteView.exchangedStartIndex, icon.visualIndex);
- }
- }
-
- Drag.active: control.drag.active
- Drag.source: icon
- Drag.hotSpot.x: icon.width / 2
- Drag.hotSpot.y: icon.height / 2
-
- Drag.onActiveChanged: {
- if (Drag.active) {
- icon.parent = favoriteView;
- } else {
- iconResetAnimation.start();
- }
- }
- ParallelAnimation {
- id: iconResetAnimation
- NumberAnimation {
- target: icon
- property: "x"
- to: delegateRoot.x
- easing.type: Easing.OutQuad
- duration: 300
- }
- NumberAnimation {
- target: icon
- property: "y"
- to: delegateRoot.y - favoriteView.contentY
- easing.type: Easing.OutQuad
- duration: 300
- }
-
- onFinished: {
- icon.parent = delegateRoot;
- icon.x = 0; icon.y = 0;
- }
- }
- }
- }
- }
- }
+ Component.onDestruction: folderLoader.turnPageFinished.disconnect(contentShowFinished)
+ }
}
}
diff --git a/qml/extensions/FavoriteGridView.qml b/qml/extensions/FavoriteGridView.qml
new file mode 100644
index 0000000..3bb85f6
--- /dev/null
+++ b/qml/extensions/FavoriteGridView.qml
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2023, 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.15
+import QtQml.Models 2.1
+import QtQuick.Controls 2.5
+import QtQuick.Layouts 1.15
+import org.ukui.menu.core 1.0
+import org.ukui.menu.extension 1.0
+import org.ukui.quick.platform 1.0 as Platform
+import org.ukui.quick.items 1.0 as UkuiItems
+import AppControls2 1.0 as AppControls2
+
+GridView {
+ id: favoriteView
+ cellWidth: itemHeight + spacing; cellHeight: cellWidth
+ signal openFolderSignal(string folderId, string folderName, int x, int y)
+ signal contentShowFinished()
+ property bool isContentShow: true
+
+ property int exchangedStartIndex: 0
+ property int spacing: 4
+ property int itemHeight: 84
+ property int column: Math.floor(width / cellWidth)
+ property alias viewModel: visualModel
+ property string mergeToAppId: ""
+ property bool isMergeToFolder: false
+ property bool dragTypeIsMerge: false
+
+ state: isContentShow ? "contentShow" : "contentHidden"
+ states: [
+ State {
+ name: "contentHidden"
+ PropertyChanges { target: favoriteView; opacity: 0; scale: 0.95 }
+ },
+ State {
+ name: "contentShow"
+ PropertyChanges { target: favoriteView; opacity: 1; scale: 1 }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ to:"contentHidden"
+ SequentialAnimation {
+ PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic }
+ ScriptAction { script: favoriteView.visible = false }
+ }
+ },
+ Transition {
+ to: "contentShow"
+ PropertyAnimation { properties: "opacity, scale"; duration: 300; easing.type: Easing.InOutCubic }
+ }
+ ]
+ // 按键导航处理(左右键可以循环)
+ focus: true
+ onActiveFocusChanged: currentIndex = 0
+ onCountChanged: currentIndex = 0
+ Keys.onRightPressed: {
+ if(currentIndex === count - 1) {
+ currentIndex = 0;
+ return;
+ }
+ currentIndex++;
+ }
+ Keys.onLeftPressed: {
+ if(currentIndex === 0) {
+ currentIndex = count - 1;
+ return;
+ }
+ currentIndex--;
+ }
+ Keys.onDownPressed: {
+ if(currentIndex > count - 1 - column) {
+ return;
+ }
+ currentIndex = currentIndex + column;
+ }
+ Keys.onUpPressed: {
+ if(currentIndex < column) {
+ return;
+ }
+ currentIndex = currentIndex - column;
+ }
+
+ ScrollBar.vertical: AppControls2.ScrollBar {
+ id: scrollBar
+ visible: viewMouseArea.containsMouse
+ width: 14; height: favoriteView.height
+ }
+
+ displaced: Transition {
+ NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad; duration: 200 }
+ }
+
+ model: DelegateModel {
+ id: visualModel
+ delegate: Item {
+ id: container
+ focus: true
+ width: favoriteView.cellWidth
+ height: favoriteView.cellHeight
+ property int visualIndex: DelegateModel.itemsIndex
+ Binding { target: iconItem; property: "visualIndex"; value: visualIndex }
+ states: State {
+ when: activeFocus
+ PropertyChanges {
+ target: iconItem
+ alpha: 0.6
+ }
+ }
+ Keys.onReturnPressed: {
+ var data = {"id": model.id};
+ send(data);
+ }
+
+ Timer {
+ id: delegateDropTimer
+ property int timeOutCount: 0
+ interval: 300
+ repeat: true
+
+ onTriggered: {
+ ++timeOutCount;
+ if (timeOutCount == 1) {
+ mergeToAppId = model.id;
+ isMergeToFolder = (model.type === DataType.Folder);
+ dragTypeIsMerge = true;
+ }
+ }
+ onRunningChanged:timeOutCount = 0
+ }
+
+ DropArea {
+ id: delegateDropArea
+ width: 48; height: 48
+ anchors.top: parent.top
+ anchors.topMargin: 8
+ anchors.horizontalCenter: parent.horizontalCenter
+ property string enterSourceId: ""
+
+ onEntered: {
+ if (drag.source.isFolder) {
+ return;
+ }
+
+ enterSourceId = drag.source.sourceId;
+ delegateDropTimer.running = true;
+ }
+ onExited: {
+ if (delegateDropTimer.timeOutCount < 1) {
+ dragTypeIsMerge = false;
+ visualModel.items.move(drag.source.visualIndex, iconItem.visualIndex);
+ }
+
+ delegateDropTimer.running = false;
+ enterSourceId = "";
+ }
+ }
+
+ UkuiItems.StyleBackground {
+ id: iconItem
+ height: favoriteView.itemHeight; width: height
+ property bool hold: false
+ property int visualIndex: 0
+ property string sourceId: ""
+ property bool isFolder: model.type === DataType.Folder
+ x: 0; y: 0
+ radius: 8
+ useStyleTransparency: false
+ paletteRole: Platform.Theme.Text
+ alpha: hold ? 0 : control.containsPress ? 0.15 : control.containsMouse ? 0.08 : 0
+
+ Behavior on scale {
+ NumberAnimation { duration: 300; easing.type: Easing.InOutCubic }
+ }
+
+ UkuiItems.StyleBackground {
+ width: 52
+ height: width
+ radius: 14
+ anchors.top: parent.top
+ anchors.margins: 6
+ anchors.horizontalCenter: parent.horizontalCenter
+ paletteRole: Platform.Theme.Text
+ useStyleTransparency: false
+ alpha: (delegateDropArea.enterSourceId !== model.id)
+ && delegateDropArea.containsDrag && dragTypeIsMerge ? 0.15 : 0
+ z: -1
+ }
+
+ Loader {
+ id: itemLoader
+ anchors.centerIn: parent
+ property int index: model.index
+ property int type: model.type
+ property string id: model.id
+ property string name: model.name
+ property string icon: model.icon
+ sourceComponent: {
+ if (type === DataType.Normal) {
+ return appItemComponent;
+ }
+ if (type === DataType.Folder) {
+ return folderItemComponent;
+ }
+ }
+ }
+ Component {
+ id: appItemComponent
+ Item {
+ height: iconItem.height
+ width: iconItem.width
+ ToolTip.visible: iconText.truncated && control.containsMouse
+ ToolTip.text: model.name
+ ToolTip.delay: 500
+
+ function itemClicked(mouseButton) {
+ if (mouseButton === Qt.RightButton) {
+ visualModel.model.openMenu(index)
+ } else {
+ var data = {"id": model.id};
+ send(data);
+ }
+ }
+ ColumnLayout {
+ width: parent.width
+ anchors.top: parent.top
+ anchors.topMargin: 8
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 6
+ Image {
+ id: iconImage
+ Layout.preferredHeight: 48
+ Layout.preferredWidth: 48
+ sourceSize.height: height
+ sourceSize.width: width
+ source: icon
+ cache: false
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+ }
+
+ UkuiItems.StyleText {
+ id: iconText
+ Layout.fillWidth: true
+ text: name
+ elide: Text.ElideRight
+ paletteRole: Platform.Theme.Text
+ horizontalAlignment: Text.AlignHCenter
+ }
+
+ }
+ Loader {
+ id: tag
+ visible: mainWindow.editMode
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.rightMargin: 10
+ Component {
+ id: editImage
+ UkuiItems.Button {
+ width: 28
+ height: 28
+ icon.width: 16
+ icon.height: 16
+ background.paletteRole: Platform.Theme.Light
+ background.alpha: 1
+ activeFocusOnTab: false
+
+ onClicked: {
+ visualModel.model.removeAppFromFavorites(id);
+ }
+
+ background.radius: width / 2
+ icon.source: "ukui-cancel-star-symbolic"
+ }
+ }
+ sourceComponent: mainWindow.editMode ? editImage : null
+ }
+ }
+ }
+ Component {
+ id: folderItemComponent
+ UkuiItems.StyleBackground {
+ height: iconItem.height
+ width: iconItem.width - 14
+ useStyleTransparency: false
+ paletteRole: Platform.Theme.Light
+ radius: 6
+ alpha: parent.containsPress ? 0.25 : parent.containsMouse ? 0.15 : 0.00
+
+ function itemClicked(mouseButton) {
+ if (mouseButton === Qt.RightButton) {
+ visualModel.model.openMenu(index);
+ } else {
+ var x = mapToGlobal(0,0).x;
+ var y = mapToGlobal(0,0).y
+ openFolderSignal(id, name, x, y);
+ // 执行隐藏动画,并且当前图标消失且鼠标区域不可用
+ favoriteView.isContentShow = false;
+ opacity = 0;
+ control.enabled = false;
+ control.hoverEnabled = false;
+ }
+ }
+
+ Item {
+ id: folderItem
+ property bool isSelect: false
+ anchors.horizontalCenter: parent.horizontalCenter
+ height: 40; width: 40
+ anchors.top: parent.top
+ anchors.topMargin: 12
+
+ UkuiItems.StyleBackground {
+ anchors.fill: parent
+ paletteRole: Palette.Text
+ useStyleTransparency: false
+ alpha: 0.25
+ radius: 24
+ visible: folderItem.isSelect
+ }
+
+ AppControls2.FolderIcon {
+ id: folderIcon
+ anchors.fill: parent
+ rows: 2; columns: 2
+ spacing: 2; padding: 2
+ icons: icon
+ radius: 4; alpha: folderItem.isSelect ? 0 : 0.25
+ anchors.centerIn: parent
+ }
+ }
+
+ UkuiItems.StyleText {
+ id: folderText
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 14
+ width: parent.width
+ horizontalAlignment: Text.AlignHCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ elide: Text.ElideRight
+ text: name
+ }
+ }
+ }
+
+ MouseArea {
+ id: control
+ anchors.fill: parent
+ hoverEnabled: true
+ pressAndHoldInterval: 300
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+
+ onClicked: {
+ itemLoader.item.itemClicked(mouse.button);
+ }
+ onPressAndHold: {
+ if (mouse.button === Qt.LeftButton) {
+ drag.target = iconItem;
+ iconItem.hold = true;
+ exchangedStartIndex = iconItem.visualIndex;
+ iconItem.sourceId = model.id;
+ }
+ }
+ onReleased: {
+ iconItem.hold = false;
+ drag.target = null;
+ }
+
+ }
+ // folderFunction
+ function resetOpacity() {
+ itemLoader.item.opacity = 1;
+ control.enabled = true;
+ control.hoverEnabled = true;
+ }
+ Component.onCompleted: favoriteView.contentShowFinished.connect(resetOpacity)
+ Component.onDestruction: favoriteView.contentShowFinished.disconnect(resetOpacity)
+
+ onHoldChanged: {
+ if (hold) {
+ favoriteView.interactive = false;
+ } else {
+ favoriteView.interactive = true;
+ if (dragTypeIsMerge && (model.id !== mergeToAppId) && (model.type === DataType.Normal)) {
+ if (isMergeToFolder) {
+ visualModel.model.addAppToFolder(model.id, mergeToAppId);
+ } else {
+ visualModel.model.addAppsToNewFolder(model.id, mergeToAppId);
+ }
+
+ } else if (exchangedStartIndex != iconItem.visualIndex) {
+ visualModel.model.exchangedAppsOrder(exchangedStartIndex, iconItem.visualIndex);
+ }
+ }
+ }
+
+ Drag.active: control.drag.active
+ Drag.source: iconItem
+ Drag.hotSpot.x: iconItem.width / 2
+ Drag.hotSpot.y: iconItem.height / 2
+
+ Drag.onActiveChanged: {
+ if (Drag.active) {
+ iconItem.parent = favoriteView;
+ } else {
+ iconResetAnimation.start();
+ }
+ }
+ ParallelAnimation {
+ id: iconResetAnimation
+ NumberAnimation {
+ target: iconItem
+ property: "x"
+ to: container.x
+ easing.type: Easing.OutQuad
+ duration: 300
+ }
+ NumberAnimation {
+ target: iconItem
+ property: "y"
+ to: container.y - favoriteView.contentY
+ easing.type: Easing.OutQuad
+ duration: 300
+ }
+
+ onFinished: {
+ iconItem.parent = container;
+ iconItem.x = 0; iconItem.y = 0;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/qml/extensions/FolderGridView.qml b/qml/extensions/FolderGridView.qml
new file mode 100644
index 0000000..b7de905
--- /dev/null
+++ b/qml/extensions/FolderGridView.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.12
+import QtQml.Models 2.1
+import QtQuick.Controls 2.5
+import org.ukui.menu.core 1.0
+import org.ukui.menu.extension 1.0
+import AppControls2 1.0 as AppControls2
+
+Item {
+
+}
diff --git a/qml/qml.qrc b/qml/qml.qrc
index 61faa3d..a0fc9d5 100644
--- a/qml/qml.qrc
+++ b/qml/qml.qrc
@@ -25,13 +25,15 @@
AppControls2/LabelItem.qml
AppControls2/FolderItem.qml
extensions/FavoriteExtension.qml
+ extensions/FavoriteGridView.qml
+ extensions/FolderGridView.qml
AppControls2/RoundButton.qml
AppControls2/FolderIcon.qml
AppUI/SelectionPage.qml
AppUI/AppPageContent.qml
AppUI/PluginSelectButton.qml
AppUI/EditText.qml
- AppUI/FullScreenFolder.qml
+ AppUI/Folder.qml
AppUI/AppPageSearch.qml
diff --git a/src/extension/favorite/app-favorite-model.cpp b/src/extension/favorite/app-favorite-model.cpp
index ac4edb5..bc28c06 100644
--- a/src/extension/favorite/app-favorite-model.cpp
+++ b/src/extension/favorite/app-favorite-model.cpp
@@ -122,6 +122,10 @@ void AppFavoritesModel::updateFavoritesApps(const DataEntity &app, const QModelI
addFavoriteApp(index);
} else if (app.favorite() == 0) {
+ if (FavoriteFolderHelper::instance()->containApp(app.id())) {
+ FavoriteFolderHelper::instance()->removeAppFromFolder(app.id());
+ }
+
QPersistentModelIndex index(sourceIndex);
removeFavoriteApp(index);
}