添加全屏收藏夹动画; 搜索框点击叉号失焦清空

This commit is contained in:
qiqi 2023-04-08 18:42:31 +08:00 committed by hewenfei
parent 06b11926bd
commit 386bb7700b
11 changed files with 341 additions and 32 deletions

View File

@ -26,10 +26,8 @@ StyleBackground {
property alias padding: iconGrid.padding property alias padding: iconGrid.padding
property alias spacing: iconGrid.spacing property alias spacing: iconGrid.spacing
radius: 4
paletteRole: Palette.Text paletteRole: Palette.Text
useStyleTransparent: false useStyleTransparent: false
alpha: 0.12
Grid { Grid {
id: iconGrid id: iconGrid

View File

@ -27,6 +27,7 @@ MouseArea {
rows: 2; columns: 2 rows: 2; columns: 2
spacing: 2; padding: 2 spacing: 2; padding: 2
icons: icon icons: icon
alpha: 0.12; radius: 4
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: 32 Layout.preferredWidth: 32
Layout.preferredHeight: 32 Layout.preferredHeight: 32

View File

@ -5,7 +5,8 @@ MouseArea {
id: buttonMouseArea id: buttonMouseArea
hoverEnabled: true hoverEnabled: true
property string buttonIcon: "" property string buttonIcon: ""
property bool highlight: false property alias highlight: themeIcon.highLight
property alias autoHighLight: themeIcon.autoHighLight
StyleBackground { StyleBackground {
useStyleTransparent: false useStyleTransparent: false
@ -16,9 +17,9 @@ MouseArea {
} }
ThemeIcon { ThemeIcon {
id: themeIcon
anchors.centerIn: parent anchors.centerIn: parent
width: 16; height: width width: 16; height: width
source: buttonIcon source: buttonIcon
highLight: buttonMouseArea.highlight
} }
} }

View File

@ -142,7 +142,6 @@ Item {
delegate: AppControls2.RoundButton { delegate: AppControls2.RoundButton {
width: height; height: ListView.view ? ListView.view.height : 0 width: height; height: ListView.view ? ListView.view.height : 0
buttonIcon: model.icon buttonIcon: model.icon
onClicked: { onClicked: {
root.state = "search"; root.state = "search";
searchInputBar.providerId = model.id; searchInputBar.providerId = model.id;

View File

@ -27,6 +27,7 @@ Item {
property bool textCenterIn: false property bool textCenterIn: false
property bool editStatus: false property bool editStatus: false
property string textEdited: title property string textEdited: title
property bool isFullScreenFolder: false
Component { Component {
id: unEditText id: unEditText
@ -36,18 +37,18 @@ Item {
horizontalAlignment: contain.textCenterIn ? Text.AlignHCenter : Text.AlignLeft horizontalAlignment: contain.textCenterIn ? Text.AlignHCenter : Text.AlignLeft
elide: Text.ElideRight elide: Text.ElideRight
text: contain.textEdited text: contain.textEdited
paletteRole: isFullScreenFolder ? Palette.HighlightedText : Palette.Text
font.bold: !isFullScreenFolder
font.pixelSize: isFullScreenFolder ? 32 : 14
MouseArea { MouseArea {
id: textArea id: textArea
anchors.fill: parent anchors.fill: parent
onDoubleClicked: { onDoubleClicked: contain.editStatus = true;
contain.editStatus = true;
} }
} }
} }
}
Component { Component {
id: editText id: editText
AppControls2.StyleBackground { AppControls2.StyleBackground {
@ -72,6 +73,8 @@ Item {
text: contain.textEdited text: contain.textEdited
selectByMouse: true selectByMouse: true
maximumLength: 14 maximumLength: 14
font.bold: !isFullScreenFolder
font.pixelSize: isFullScreenFolder ? 32 : 14
onEditingFinished: { onEditingFinished: {
modelManager.getFolderModel().renameFolder(text); modelManager.getFolderModel().renameFolder(text);
@ -79,8 +82,9 @@ Item {
contain.editStatus = false; contain.editStatus = false;
} }
property int textColor: isFullScreenFolder ? Palette.HighlightedText : Palette.Text
function updateTextInputColor() { function updateTextInputColor() {
color = themePalette.paletteColor(Palette.Text); color = themePalette.paletteColor(textColor);
selectionColor = themePalette.paletteColor(Palette.Highlight); selectionColor = themePalette.paletteColor(Palette.Highlight);
} }
@ -107,10 +111,12 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
width: 16; height: width width: 16; height: width
source: "image://appicon/edit-clear-symbolic" source: "image://appicon/edit-clear-symbolic"
highLight: isFullScreenFolder
autoHighLight: !isFullScreenFolder
} }
onClicked: { onClicked: {
textEdit.text = title; textEdit.text = textEdited;
contain.editStatus = false; contain.editStatus = false;
} }
} }

View File

@ -24,7 +24,41 @@ import org.ukui.menu.core 1.0
import AppControls2 1.0 as AppControls2 import AppControls2 1.0 as AppControls2
RowLayout { RowLayout {
id: root
clip: true clip: true
signal openFolderSignal(string folderId, string folderName, int x, int y)
signal contentShowFinished()
property bool isContentShow: true
property int animationDuration: 300
state: isContentShow ? "contentShow" : "contentHidden"
states: [
State {
name: "contentHidden"
PropertyChanges { target: root; opacity: 0; scale: 0.95 }
},
State {
name: "contentShow"
PropertyChanges { target: root; opacity: 1; scale: 1 }
}
]
transitions: [
Transition {
to:"contentHidden"
SequentialAnimation {
PropertyAnimation { properties: "opacity, scale"; duration: animationDuration; easing.type: Easing.InOutCubic }
ScriptAction { script: root.visible = false }
}
},
Transition {
to: "contentShow"
SequentialAnimation {
PropertyAnimation { properties: "opacity, scale"; duration: animationDuration; easing.type: Easing.InOutCubic }
ScriptAction { script: root.contentShowFinished() }
}
}
]
Item { Item {
Layout.preferredWidth: 145 Layout.preferredWidth: 145
@ -42,7 +76,7 @@ RowLayout {
interactive: contentHeight > parent.height interactive: contentHeight > parent.height
spacing: 5 spacing: 5
highlightMoveDuration: 300 highlightMoveDuration: animationDuration
highlight: AppControls2.StyleBackground { highlight: AppControls2.StyleBackground {
width: labelListView.maxLabelWidth; height: 30 width: labelListView.maxLabelWidth; height: 30
radius: 4 radius: 4
@ -73,7 +107,6 @@ RowLayout {
model: modelManager.getLabelModel() model: modelManager.getLabelModel()
delegate: MouseArea { delegate: MouseArea {
id: labelMouseArea
width: labelListView.maxLabelWidth width: labelListView.maxLabelWidth
height: 30 height: 30
hoverEnabled: true hoverEnabled: true
@ -82,6 +115,7 @@ RowLayout {
paletteRole: Palette.HighlightedText paletteRole: Palette.HighlightedText
elide: Text.ElideRight elide: Text.ElideRight
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: model.displayName text: model.displayName
} }
onClicked: { onClicked: {
@ -136,6 +170,7 @@ RowLayout {
ScrollBar.vertical: fullScreenScrollBar ScrollBar.vertical: fullScreenScrollBar
cellWidth: contentViewBase.cellWidth cellWidth: contentViewBase.cellWidth
cellHeight: contentViewBase.cellHeight cellHeight: contentViewBase.cellHeight
boundsBehavior: Flickable.StopAtBounds
model: modelManager.getAppModel() model: modelManager.getAppModel()
delegate: Loader { delegate: Loader {
@ -143,6 +178,7 @@ RowLayout {
height: width height: width
property int index: model.index property int index: model.index
property int type: model.type property int type: model.type
property string id: model.id
property string name: model.name property string name: model.name
property string icon: model.icon property string icon: model.icon
sourceComponent: { sourceComponent: {
@ -150,7 +186,7 @@ RowLayout {
return appComponent; return appComponent;
} }
if (type === DataType.Folder) { if (type === DataType.Folder) {
return folderComponent; return normalFolderComponent;
} }
} }
} }
@ -159,17 +195,17 @@ RowLayout {
id: appComponent id: appComponent
Item { Item {
MouseArea { MouseArea {
id: appMouseArea
anchors.centerIn: parent anchors.centerIn: parent
hoverEnabled: true hoverEnabled: true
width: 170; height: width width: 170; height: width
acceptedButtons: Qt.LeftButton | Qt.RightButton
AppControls2.StyleBackground { AppControls2.StyleBackground {
anchors.fill: parent anchors.fill: parent
useStyleTransparent: false useStyleTransparent: false
paletteRole: Palette.Light paletteRole: Palette.Light
radius: 16 radius: 16
alpha: appMouseArea.containsPress ? 0.25 : appMouseArea.containsMouse ? 0.15 : 0.00 alpha: parent.containsPress ? 0.25 : parent.containsMouse ? 0.15 : 0.00
AppControls2.IconLabel { AppControls2.IconLabel {
anchors.fill: parent anchors.fill: parent
iconWidth: 96; iconHeight: 96 iconWidth: 96; iconHeight: 96
@ -180,7 +216,14 @@ RowLayout {
} }
onClicked: { onClicked: {
if (mouse.button === Qt.RightButton) {
parent.parent.GridView.view.model.openMenu(index);
return;
}
if (mouse.button === Qt.LeftButton) {
parent.parent.GridView.view.model.appClicked(index); parent.parent.GridView.view.model.appClicked(index);
return;
}
} }
} }
} }
@ -188,18 +231,65 @@ RowLayout {
} }
Component { Component {
id: folderComponent id: normalFolderComponent
Item { Item {
MouseArea { MouseArea {
anchors.centerIn: parent anchors.centerIn: parent
width: 100; height: 140 hoverEnabled: true
AppControls2.IconLabel { width: 170; height: width
acceptedButtons: Qt.LeftButton | Qt.RightButton
AppControls2.StyleBackground {
anchors.fill: parent anchors.fill: parent
iconWidth: 96 useStyleTransparent: false
iconHeight: 96 paletteRole: Palette.Light
appName: name radius: 16
appIcon: icon alpha: parent.containsPress ? 0.25 : parent.containsMouse ? 0.15 : 0.00
ColumnLayout {
height: 128; width: parent.width
anchors.centerIn: parent
spacing: 8
AppControls2.FolderIcon {
id: folderIcon
Layout.margins: 5
rows: 4; columns: 4
spacing: 2; padding: 8
icons: icon
radius: 16; alpha: 0.25
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: 86; Layout.preferredHeight: 86
} }
AppControls2.StyleText {
Layout.fillWidth: true; Layout.fillHeight: true
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
text: name
font.pixelSize: 14
paletteRole: Palette.HighlightedText
}
}
}
onClicked: {
if (mouse.button === Qt.RightButton) {
parent.parent.GridView.view.model.openMenu(index);
return;
}
if (mouse.button === Qt.LeftButton) {
var x = folderIcon.mapToGlobal(0,0).x;
var y = folderIcon.mapToGlobal(0,0).y
openFolderSignal(id, name, x, y);
root.isContentShow = false;
opacity = 0;
return;
}
}
function resetOpacity() {
opacity = 1;
}
Component.onCompleted: root.contentShowFinished.connect(resetOpacity)
Component.onDestruction: root.contentShowFinished.disconnect(resetOpacity)
} }
} }
} }
@ -214,6 +304,7 @@ RowLayout {
ScrollBar.vertical: fullScreenScrollBar ScrollBar.vertical: fullScreenScrollBar
contentHeight: labelColumn.height contentHeight: labelColumn.height
flickableDirection: Flickable.VerticalFlick flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
interactive: !contentYAnimation.running interactive: !contentYAnimation.running
Column { Column {
@ -268,7 +359,6 @@ RowLayout {
height: GridView.view.cellHeight height: GridView.view.cellHeight
MouseArea { MouseArea {
id: labelAppMouseArea
anchors.centerIn: parent anchors.centerIn: parent
hoverEnabled: true hoverEnabled: true
width: 170; height: width width: 170; height: width
@ -278,7 +368,7 @@ RowLayout {
useStyleTransparent: false useStyleTransparent: false
paletteRole: Palette.Light paletteRole: Palette.Light
radius: 16 radius: 16
alpha: labelAppMouseArea.containsPress ? 0.25 : labelAppMouseArea.containsMouse ? 0.15 : 0.00 alpha: parent.containsPress ? 0.25 : parent.containsMouse ? 0.15 : 0.00
AppControls2.IconLabel { AppControls2.IconLabel {
anchors.fill: parent anchors.fill: parent
iconWidth: 96; iconHeight: 96 iconWidth: 96; iconHeight: 96
@ -303,7 +393,7 @@ RowLayout {
id: contentYAnimation id: contentYAnimation
target: labelViewFlickable target: labelViewFlickable
property: "contentY" property: "contentY"
duration: 300 duration: animationDuration
onFinished: { onFinished: {
labelViewFlickable.returnToBounds(); labelViewFlickable.returnToBounds();
} }

View File

@ -0,0 +1,165 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*
*/
import QtQuick 2.0
import QtQuick.Layouts 1.12
import org.ukui.menu.core 1.0
import AppControls2 1.0 as AppControls2
Item {
property alias model: folderGridView.model
property string folderName: ""
property int margins: 20
property int folderX: 0
property int folderY: 0
property bool isFolderOpened: false
property int animationDuration: 300
AppControls2.StyleBackground {
id: folderIconBase
paletteRole: Palette.Text
useStyleTransparent: false
property int folderIconSize: 0
property int iconSpacing: 0
property int imageX: 0
property int imageY: 0
alpha: 0.25
state: isFolderOpened ? "folderOpened" : "folderHidden"
states: [
State {
name: "folderOpened"
PropertyChanges {
target: folderIconBase
width: 720; height: folderGridView.viewMaxHeight; radius: 36
x: (parent.width - width) / 2; y: (parent.height - height) / 2
folderIconSize: 96; iconSpacing: 8
imageX: 37; imageY: 17
}
PropertyChanges { target: folderGridView; anchors.margins: margins }
PropertyChanges { target: folderNameText; opacity: 1 }
},
State {
name: "folderHidden"
PropertyChanges {
target: folderIconBase
width: 86; height: width; radius: 16
x: parent.parent.mapFromGlobal(folderX, 0).x; y: parent.parent.mapFromGlobal(0, folderY).y
folderIconSize: 16; iconSpacing: 0
imageX: 0; imageY: 0
}
PropertyChanges { target: folderGridView; anchors.margins: 8 }
PropertyChanges { target: folderNameText; opacity: 0 }
}
]
transitions: [
Transition {
to: "folderHidden"
SequentialAnimation {
ScriptAction { script: folderGridView.positionViewAtBeginning() }
ParallelAnimation {
PropertyAnimation {
duration: animationDuration; easing.type: Easing.InOutCubic
properties: "x, y, width, height, folderIconSize, iconSpacing, radius, imageX, imageY, anchors.margins"
}
PropertyAnimation {
duration: animationDuration; easing.type: Easing.OutQuint
properties: "opacity"
}
}
ScriptAction { script: parent.active = false }
}
},
Transition {
to: "folderOpened"
ParallelAnimation {
PropertyAnimation {
duration: animationDuration; easing.type: Easing.InOutCubic
properties: "x, y, width, height, folderIconSize, iconSpacing, radius, imageX, imageY, anchors.margins"
}
PropertyAnimation {
duration: animationDuration; easing.type: Easing.InQuint
properties: "opacity"
}
}
}
]
GridView {
id: folderGridView
anchors.fill: parent
cellHeight: width / 4; cellWidth: cellHeight
boundsBehavior: Flickable.StopAtBounds
property int viewMaxHeight: Math.ceil(count / 4) * 170 > width ? width + margins*2 : (Math.ceil(count / 4) * 170 + margins*2)
model: modelManager.getFolderModel()
delegate: MouseArea {
hoverEnabled: true
width: GridView.view.cellHeight; height: width
acceptedButtons: Qt.LeftButton | Qt.RightButton
AppControls2.StyleBackground {
anchors.fill: parent
useStyleTransparent: false
paletteRole: Palette.Light
radius: 16
alpha: parent.containsPress ? 0.25 : parent.containsMouse ? 0.15 : 0.00
Image {
id: iconImage
source: icon
height: folderIconBase.folderIconSize; width: height
x: folderIconBase.imageX; y: folderIconBase.imageY
}
AppControls2.StyleText {
width: parent.width
horizontalAlignment: Text.AlignHCenter
anchors.top: iconImage.bottom
anchors.topMargin: folderIconBase.iconSpacing
anchors.horizontalCenter: parent.horizontalCenter
text: name
font.pixelSize: 14
elide: Text.ElideRight
paletteRole: Palette.HighlightedText
}
}
onClicked: {
if (mouse.button === Qt.RightButton) {
menuManager.showMenu(id);
return;
}
if (mouse.button === Qt.LeftButton) {
appManager.launchApp(id);
return;
}
}
}
}
}
EditText {
id: folderNameText
anchors.bottom: folderGridView.parent.top
anchors.bottomMargin: 30
anchors.horizontalCenter: folderGridView.parent.horizontalCenter
height: 47; width: folderGridView.width
textEdited: folderName
textCenterIn: true
isFullScreenFolder: true
}
}

View File

@ -7,10 +7,13 @@ import org.ukui.menu.utils 1.0
Item { Item {
clip: true clip: true
property alias searchOpacity: searchInputBar.opacity
SearchInputBar { SearchInputBar {
id: searchInputBar
width: 372; height: 36 width: 372; height: 36
anchors.centerIn: parent anchors.centerIn: parent
radius: height / 2 radius: height / 2
visible: opacity
onTextChanged: { onTextChanged: {
if (text === "") { if (text === "") {
@ -20,6 +23,9 @@ Item {
appPageHeaderUtils.startSearch(text); appPageHeaderUtils.startSearch(text);
} }
} }
Behavior on opacity {
NumberAnimation { duration: 300; easing.type: Easing.InOutCubic }
}
} }
PluginSelectMenu { PluginSelectMenu {

View File

@ -5,6 +5,20 @@ import org.ukui.menu.core 1.0
AppControls2.StyleBackground { AppControls2.StyleBackground {
paletteRole: Palette.Dark paletteRole: Palette.Dark
MouseArea {
anchors.fill: parent
onClicked: {
if (fullScreenContent.visible) {
//退
forceActiveFocus();
mainWindow.hide();
} else {
folderLoader.item.isFolderOpened = false;
fullScreenContent.visible = true;
fullScreenContent.isContentShow = true;
}
}
}
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
@ -12,20 +26,43 @@ AppControls2.StyleBackground {
anchors.rightMargin: 35 anchors.rightMargin: 35
FullScreenHeader { FullScreenHeader {
// full screen header id: fullScreenHeader
Layout.preferredHeight: 130 Layout.preferredHeight: 130
Layout.fillWidth: true Layout.fillWidth: true
Layout.maximumHeight: 130 Layout.maximumHeight: 130
searchOpacity: fullScreenContent.isContentShow ? 1 : 0
} }
FullScreenContent { Item {
// full screen content
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
FullScreenContent {
id: fullScreenContent
anchors.fill: parent
}
Loader {
id: folderLoader
active: false
anchors.fill: parent
sourceComponent: FullScreenFolder {}
function openFolder(id, name, x, y) {
active = true;
item.model.setFolderId(id);
item.folderName = name;
item.folderX = x;
item.folderY = y;
item.isFolderOpened = true;
}
Component.onCompleted: fullScreenContent.openFolderSignal.connect(openFolder)
Component.onDestruction: fullScreenContent.openFolderSignal.disconnect(openFolder)
}
} }
FullScreenFooter { FullScreenFooter {
// full screen footer
Layout.preferredHeight: 90 Layout.preferredHeight: 90
Layout.fillWidth: true Layout.fillWidth: true
} }

View File

@ -52,6 +52,7 @@ AppControls2.StyleBackground {
width: parent.height / 2; height: width width: parent.height / 2; height: width
source: "image://appicon/search-symbolic" source: "image://appicon/search-symbolic"
highLight: mainWindow.isFullScreen highLight: mainWindow.isFullScreen
autoHighLight: !mainWindow.isFullScreen
} }
} }
@ -119,7 +120,11 @@ AppControls2.StyleBackground {
visible: mainWindow.isFullScreen && textInput.activeFocus visible: mainWindow.isFullScreen && textInput.activeFocus
buttonIcon: "image://appicon/edit-clear-symbolic" buttonIcon: "image://appicon/edit-clear-symbolic"
highlight: true highlight: true
autoHighLight: false
onClicked: textInput.clear(); onClicked: {
textInput.clear();
textInput.focus = false;
}
} }
} }

View File

@ -34,5 +34,6 @@
<file>AppUI/AppPageContent.qml</file> <file>AppUI/AppPageContent.qml</file>
<file>AppUI/PluginSelectMenu.qml</file> <file>AppUI/PluginSelectMenu.qml</file>
<file>AppUI/EditText.qml</file> <file>AppUI/EditText.qml</file>
<file>AppUI/FullScreenFolder.qml</file>
</qresource> </qresource>
</RCC> </RCC>