Skip to content

Commit

Permalink
feat: add ListView to support hover animations
Browse files Browse the repository at this point in the history
- item enter / leave animation
- item hover changed animation
- fix backgroundVisible not work
  • Loading branch information
kegechen committed Jul 31, 2024
1 parent 599d329 commit 3ac175c
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 11 deletions.
1 change: 1 addition & 0 deletions chameleon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ set(QML_FILES
Frame.qml
GroupBox.qml
ItemDelegate.qml
ListView.qml
MenuItem.qml
Menu.qml
MenuSeparator.qml
Expand Down
9 changes: 9 additions & 0 deletions chameleon/ListView.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

import org.deepin.dtk 1.0 as D

D.ListView {

}
1 change: 1 addition & 0 deletions qt6/src/dtkdeclarative_qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
<file>qml/private/ButtonPanel.qml</file>
<file>qml/ActionButton.qml</file>
<file>qml/ItemDelegate.qml</file>
<file>qml/ListView.qml</file>
<file>qml/CheckDelegate.qml</file>
<file>qml/TipsSlider.qml</file>
<file>qml/SliderTipItem.qml</file>
Expand Down
1 change: 1 addition & 0 deletions qt6/src/qml.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ set(QML_DTK_CONTROLS
"qml/ComboBox.qml"
"qml/ActionButton.qml"
"qml/ItemDelegate.qml"
"qml/ListView.qml"
"qml/CheckDelegate.qml"
"qml/TipsSlider.qml"
"qml/SliderTipItem.qml"
Expand Down
22 changes: 11 additions & 11 deletions qt6/src/qml/ItemDelegate.qml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2022-2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

Expand All @@ -7,6 +7,7 @@ import QtQuick.Templates as T
import QtQuick.Layouts 1.11
import org.deepin.dtk 1.0 as D
import org.deepin.dtk.style 1.0 as DS
import org.deepin.dtk.private 1.0 as P

T.ItemDelegate {
id: control
Expand Down Expand Up @@ -35,7 +36,7 @@ T.ItemDelegate {
spacing: DS.Style.control.spacing
checkable: true
autoExclusive: true
palette.windowText: checked && !control.cascadeSelected ? D.ColorSelector.checkedTextColor : undefined
palette.windowText: checked && !control.cascadeSelected && control.backgroundVisible ? D.ColorSelector.checkedTextColor : undefined

D.DciIcon.mode: D.ColorSelector.controlState
D.DciIcon.theme: D.ColorSelector.controlTheme
Expand Down Expand Up @@ -83,6 +84,7 @@ T.ItemDelegate {
}

background: Item {
visible: backgroundVisible
implicitWidth: DS.Style.itemDelegate.width
implicitHeight: DS.Style.itemDelegate.height

Expand All @@ -101,15 +103,13 @@ T.ItemDelegate {
corners: control.corners
}
}
}

Loader {
anchors.fill: parent
active: !checked && control.backgroundVisible
sourceComponent: D.RoundRectangle {
color: DS.Style.itemDelegate.normalColor
radius: DS.Style.control.radius
corners: control.corners
}
}
onHoveredChanged: {
if (checked || control.cascadeSelected || !backgroundVisible)
return

if (ListView.view)
ListView.view.setHoverItem(control.hovered ? control : null)
}
}
165 changes: 165 additions & 0 deletions qt6/src/qml/ListView.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

import QtQuick 2.11
import QtQuick.Templates as T
import org.deepin.dtk.style 1.0 as DS
import org.deepin.dtk.private 1.0 as P

ListView {
id: control
property int duration: 100
property bool bgVisible: false
property Item hoveredItem

onContentXChanged: {
if (hoveredItem && hoveredItem.hovered && background)
background.x = hoveredItem.x - contentX
}

onContentYChanged: {
if (hoveredItem && hoveredItem.hovered && background)
background.y = hoveredItem.y - contentY
}

function setHoverItem(item) {
if (item) {
hoveredItem = item
// if hover from null to item do not show animation
bgVisible = (background.x <= 0 && background.y <= 0) ? false : hoveredItem.hovered
background.x = hoveredItem.x - contentX
background.y = hoveredItem.y - contentY
background.width = hoveredItem.implicitWidth
background.height = hoveredItem.implicitHeight
bgVisible = hoveredItem.hovered
control.state = bgVisible ? "Visible" : "Invisible"
} else {
hideTimer.start()
}
}

// ItemDelegate hover item0 ==> item1, add timer ignore [item0.unhovered]
// item0.hovered, item0.unhovered, item1.hovered
Timer {
id: hideTimer
interval: control.duration
onTriggered: {
bgVisible = hoveredItem ? hoveredItem.hovered : false
control.state = bgVisible ? "Visible" : "Invisible"
}
}

// visible animation
states: [
State{
name: "Visible"
PropertyChanges { target: background; opacity: 1.0 }
PropertyChanges { target: background; scale: 1.0 }
PropertyChanges { target: background; visible: true }
},
State{
name:"Invisible"
PropertyChanges { target: background; opacity: 0.0 }
PropertyChanges { target: background; scale: 0.5 }
PropertyChanges { target: background; visible: false }
}
]

transitions: [
Transition {
from: "Visible"
to: "Invisible"

SequentialAnimation {
ParallelAnimation {
NumberAnimation {
target: background
property: "opacity"
duration: control.duration
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: background
property: "scale"
duration: control.duration
easing.type: Easing.InOutQuad
}
}
NumberAnimation {
target: background
property: "visible"
duration: 0
}
}
},
Transition {
from: "Invisible"
to: "Visible"
SequentialAnimation {
NumberAnimation {
target: background
property: "visible"
duration: 0
}
ParallelAnimation {
NumberAnimation {
target: background
property: "opacity"
duration: control.duration
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: background
property: "scale"
duration: control.duration
easing.type: Easing.InOutQuad
}
}
}
}
]

Item {
id: background
implicitWidth: DS.Style.itemDelegate.width
implicitHeight: DS.Style.itemDelegate.height
z: -1

Loader {
anchors.fill: parent
active: hoveredItem
sourceComponent: P.ButtonPanel {
button: hoveredItem
outsideBorderColor: null
visible: hoveredItem && !hoveredItem.checked && hoveredItem.enabled
}
}

onVisibleChanged: {
if (!visible) {
// ensure do not show animation when hoveredItem from null to item
background.x = -1
background.y = -1
}
}

// move and resize animation
Behavior on x {
enabled: bgVisible
NumberAnimation { duration: control.duration }
}
Behavior on y {
enabled: bgVisible
NumberAnimation { duration: control.duration }
}
Behavior on width {
enabled: bgVisible
NumberAnimation { duration: control.duration }
}
Behavior on height {
enabled: bgVisible
NumberAnimation { duration: control.duration }
}
}
}

0 comments on commit 3ac175c

Please sign in to comment.