diff --git a/examples/exhibition/ControlGroup.qml b/examples/exhibition/ControlGroup.qml
new file mode 100644
index 00000000..a0b83da3
--- /dev/null
+++ b/examples/exhibition/ControlGroup.qml
@@ -0,0 +1,52 @@
+// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+
+import QtQuick 2.0
+import QtQuick.Window 2.11
+import QtQuick.Layouts 1.11
+import org.deepin.dtk 1.0
+import ".."
+
+ ControlGroup {
+ title: "磁盘"
+ ControlGroupItem {
+ Label {
+ visible: true
+ text: "test0111111111111"
+ }
+ Label {
+ visible: true
+ text: "test13333333333"
+ }
+ }
+ ControlGroupItem {
+ Rectangle {
+ width: 100
+ height: 100
+ color: "red"
+ border.color: "black"
+ border.width: 5
+ radius: 10
+ }
+ Switch {
+ checked: true
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+ ControlGroupItem {
+ Rectangle {
+ width: 100
+ height: 100
+ color: "green"
+ border.color: "black"
+ border.width: 5
+ radius: 10
+ }
+ Button {
+ width: 100
+ height: 100
+ Layout.alignment: Qt.AlignHCenter
+ }
+ }
+ }
diff --git a/examples/exhibition/qml-qt6.qrc b/examples/exhibition/qml-qt6.qrc
index 8d9a8f2d..750b0636 100644
--- a/examples/exhibition/qml-qt6.qrc
+++ b/examples/exhibition/qml-qt6.qrc
@@ -25,5 +25,6 @@
ToolBar.qml
Dialog.qml
ProgressBar.qml
+ ControlGroup.qml
diff --git a/qt6/src/dtkdeclarative_qml.qrc b/qt6/src/dtkdeclarative_qml.qrc
index 2b88b5b3..fb83f85c 100644
--- a/qt6/src/dtkdeclarative_qml.qrc
+++ b/qt6/src/dtkdeclarative_qml.qrc
@@ -109,6 +109,8 @@
qml/ButtonIndicator.qml
qml/EmbeddedProgressBar.qml
qml/WaterProgressBar.qml
+ qml/ControlGroup.qml
+ qml/ControlGroupItem.qml
qml/private/ProgressBarImpl.qml
qml/private/ProgressBarPanel.qml
qml/PlaceholderText.qml
diff --git a/qt6/src/qml.cmake b/qt6/src/qml.cmake
index 965e28db..998efbbf 100644
--- a/qt6/src/qml.cmake
+++ b/qt6/src/qml.cmake
@@ -96,6 +96,8 @@ set(QML_DTK_CONTROLS
"qml/EmbeddedProgressBar.qml"
"qml/WaterProgressBar.qml"
"qml/PlaceholderText.qml"
+ "qml/ControlGroup.qml"
+ "qml/ControlGroupItem.qml"
)
foreach(QML_FILE ${QML_DTK_CONTROLS})
diff --git a/qt6/src/qml/ArrowListView.qml b/qt6/src/qml/ArrowListView.qml
index a7e53fb6..ec16f967 100644
--- a/qt6/src/qml/ArrowListView.qml
+++ b/qt6/src/qml/ArrowListView.qml
@@ -5,6 +5,7 @@
import QtQuick 2.11
import QtQuick.Window 2.11
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
@@ -48,6 +49,20 @@ FocusScope {
}
interactive: Window.window ? (contentHeight > Window.window.height || model.count > maxVisibleItems) : false
ScrollIndicator.vertical: ScrollIndicator { }
+ highlight: Rectangle {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: 6
+ anchors.rightMargin: 6
+ anchors.topMargin: 6
+ anchors.bottomMargin: 6
+ property D.Palette backgroundColor: DS.Style.highlightPanel.background
+ color: D.ColorSelector.backgroundColor
+ radius: 6 // TODO can't display background when using dtk's InWindowBlur.
+ }
+ highlightFollowsCurrentItem: true
+ highlightMoveDuration: -1
+ highlightMoveVelocity: 400
}
P.ArrowListViewButton {
diff --git a/qt6/src/qml/ControlGroup.qml b/qt6/src/qml/ControlGroup.qml
new file mode 100644
index 00000000..d3169a52
--- /dev/null
+++ b/qt6/src/qml/ControlGroup.qml
@@ -0,0 +1,171 @@
+// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.11
+import org.deepin.dtk 1.0 as D
+import org.deepin.dtk.style 1.0 as DS
+
+ColumnLayout {
+ id: root
+ spacing: 10
+ clip: true
+
+ property string title
+ property bool isExpanded: true
+ property int interval: 400 / (itemLayout.children.length)
+ property int index: 0
+ property int titleHeight: 36
+ default property alias childItem: itemLayout.children
+
+ Control {
+ id: title
+ Layout.fillWidth: true
+ Layout.preferredHeight: 36
+ property int inset: 4
+ leftInset: inset
+ rightInset: inset
+ topInset: inset
+ bottomInset: inset
+ state: "normal"
+ states: [
+ State {
+ name: "normal"
+ PropertyChanges {
+ target: title
+ inset:4
+ }
+ },
+ State {
+ name: "hovered"
+ PropertyChanges {
+ target: title
+ inset:0
+ }
+ },
+ State {
+ name: "pressed"
+ PropertyChanges {
+ target: title
+ inset: 4
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ from: "normal"
+ to: "hovered"
+ NumberAnimation {
+ properties: "inset"
+ easing.type: Easing.Linear
+ duration: 500
+ }
+ },
+ Transition {
+ from: "hovered"
+ to: "normal"
+ NumberAnimation {
+ properties: "inset"
+ easing.type: Easing.Linear
+ duration: 500
+ }
+ },
+ Transition {
+ from: "hovered"
+ to: "pressed"
+ NumberAnimation {
+ properties: "inset"
+ easing.type: Easing.Linear
+ duration: 500
+ }
+ },
+ Transition {
+ from: "pressed"
+ to: "hovered"
+ NumberAnimation {
+ properties: "inset"
+ easing.type: Easing.Linear
+ duration: 500
+ }
+ }
+ ]
+ RowLayout {
+ anchors.fill: parent
+ spacing: 0
+ Label {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ text: root.title
+ font: DTK.fontManager.t5
+ verticalAlignment: Qt.AlignVCenter
+ }
+ D.DciIcon {
+ Layout.preferredWidth: 36
+ Layout.preferredHeight: 36
+ rotation: root.isExpanded ? 0 : - 90
+ name: "arrow_ordinary_down"
+
+ Behavior on rotation {
+ NumberAnimation {
+ duration: root.interval
+ easing.type: Easing.Linear
+ }
+ }
+ }
+ }
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: root.isExpanded = !root.isExpanded
+ onPressed: title.state = "pressed"
+ onReleased: title.state = "hovered"
+ onEntered: title.state = "hovered"
+ onExited: title.state = "normal"
+ }
+ background: Item {
+ Loader {
+ anchors.fill: parent
+ active: title.hovered
+ sourceComponent: D.RoundRectangle {
+ color: DS.Style.itemDelegate.normalColor
+ radius: DS.Style.control.radius
+ corners: D.RoundRectangle.TopLeftCorner | D.RoundRectangle.TopRightCorner | D.RoundRectangle.BottomLeftCorner | D.RoundRectangle.BottomRightCorner
+ }
+ }
+ }
+ }
+
+ Timer {
+ id: timer
+ }
+
+ ColumnLayout {
+ id: itemLayout
+ }
+
+ onIsExpandedChanged: (isExpanded) => {
+ for(let i = 0; i < itemLayout.children.length; ++i) {
+ itemLayout.children[i].isExpanded = !itemLayout.children[i].isExpanded
+ }
+ // delay(0, timeout)
+ }
+
+ function timeout() {
+ itemLayout.children[index].isExpanded = !itemLayout.children[index].isExpanded
+ ++index
+ if (index === itemLayout.children.length) {
+ timer.stop()
+ timer.triggered.disconnect(timeout)
+ index = 0
+ }
+ }
+
+ function delay(delayTime, cb) {
+ timer.interval = delayTime
+ timer.repeat = true
+ timer.triggered.connect(cb)
+ timer.restart()
+ }
+}
diff --git a/qt6/src/qml/ControlGroupItem.qml b/qt6/src/qml/ControlGroupItem.qml
new file mode 100644
index 00000000..2a98212a
--- /dev/null
+++ b/qt6/src/qml/ControlGroupItem.qml
@@ -0,0 +1,39 @@
+// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.11
+import QtQml.Models 2.11
+import org.deepin.dtk 1.0
+
+RowLayout {
+ id: root
+
+ property int initY
+ property bool isExpanded: true
+
+ y: isExpanded ? initY : - parent.parent.titleHeight
+ opacity: isExpanded ? 1.0 : 0.0
+ visible: opacity === 0.0 ? false : true
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Behavior on y {
+ NumberAnimation {
+ duration: parent.parent.interval
+ easing.type: Easing.Linear
+ }
+ }
+ Behavior on opacity {
+ NumberAnimation {
+ duration: parent.parent.interval
+ easing.type: Easing.Linear
+ }
+ }
+
+ Component.onCompleted: {
+ root.initY = root.y
+ }
+}
diff --git a/qt6/src/qml/FloatingMessage.qml b/qt6/src/qml/FloatingMessage.qml
index 5b1d9cb9..65c90a9f 100644
--- a/qt6/src/qml/FloatingMessage.qml
+++ b/qt6/src/qml/FloatingMessage.qml
@@ -23,9 +23,18 @@ D.FloatingMessageContainer {
width: DS.Style.floatingMessage.closeButtonSize
height: DS.Style.floatingMessage.closeButtonSize
}
- onClicked: D.DTK.closeMessage(control)
+ onClicked: {
+ floatingPanel.state = "small"
+ destroyTimer.running = true
+ }
+ Timer {
+ id: destroyTimer
+ interval: 1200; running: false; repeat: true
+ onTriggered: D.DTK.closeMessage(control)
+ }
}
+
duration: 4000
panel: FloatingPanel {
id: floatingPanel
@@ -34,12 +43,24 @@ D.FloatingMessageContainer {
rightPadding: 10
topPadding: 0
bottomPadding: 0
-
+ opacity: 0.0
+ state: "small"
+ Timer {
+ id: timer
+ interval: 100; running: false; repeat: false
+ onTriggered: {
+ floatingPanel.y = floatingPanel.parent.height
+ floatingPanel.state = "normal"
+ console.log("onCompleted", floatingPanel.y, floatingPanel.parent.width, floatingPanel.parent.height)
+ }
+ }
+ Component.onCompleted: {
+ timer.running = true
+ }
contentItem: RowLayout {
height: DS.Style.floatingMessage.minimumHeight
width: Math.min(DS.Style.floatingMessage.maximumWidth, children.width + floatingPanel.leftPadding - floatingPanel.rightPadding)
spacing: 10
-
Loader {
id: iconLoader
Layout.alignment: Qt.AlignVCenter
@@ -77,6 +98,46 @@ D.FloatingMessageContainer {
visible: active
sourceComponent: button
}
+
+ ParallelAnimation {
+ running: closeButton.item.hovered
+ NumberAnimation { target: closeButton; property: "scale"; to: 1.25; duration: 500 }
+ NumberAnimation { target: closeButton; property: "rotation"; to: 90; duration: 500 }
+ }
+ ParallelAnimation {
+ running: !closeButton.item.hovered
+ NumberAnimation { target: closeButton; property: "scale"; to: 1; duration: 500 }
+ NumberAnimation { target: closeButton; property: "rotation"; to: 0; duration: 500 }
+ }
}
+
+ states: [
+ State {
+ name: "normal"
+ PropertyChanges {
+ target: floatingPanel
+ y: 0
+ opacity: 1.0
+ scale: 1.0
+ }
+ },
+ State {
+ name: "small"
+ PropertyChanges {
+ target: floatingPanel
+ y: floatingPanel.parent.height
+ opacity: 0.0
+ scale: 0.2
+ }
+ }
+ ]
+
+ transitions: Transition {
+ NumberAnimation {
+ properties: "y, opacity, scale"
+ easing.type: Easing.Linear
+ duration: 1000
+ }
+ }
}
}
diff --git a/qt6/src/qml/Menu.qml b/qt6/src/qml/Menu.qml
index 5c43d4d6..46038991 100644
--- a/qt6/src/qml/Menu.qml
+++ b/qt6/src/qml/Menu.qml
@@ -42,13 +42,14 @@ T.Menu {
}
contentItem: Control {
- topPadding: 10 // TODO how to clip radius
+ topPadding: 6 // TODO how to clip radius
bottomPadding: topPadding
leftPadding: 0
rightPadding: leftPadding
contentItem: ColumnLayout {
id: viewLayout
+ spacing: 0
Loader {
Layout.fillWidth: true
diff --git a/qt6/src/qml/MenuItem.qml b/qt6/src/qml/MenuItem.qml
index 0107be5a..8e22b1e6 100644
--- a/qt6/src/qml/MenuItem.qml
+++ b/qt6/src/qml/MenuItem.qml
@@ -102,15 +102,5 @@ T.MenuItem {
radius: DS.Style.control.radius
}
}
-
- Loader {
- anchors.fill: parent
- active: control.down || control.highlighted
- sourceComponent: Rectangle {
- property D.Palette backgroundColor: DS.Style.highlightPanel.background
- color: D.ColorSelector.backgroundColor
- radius: 1 // TODO can't display background when using dtk's InWindowBlur.
- }
- }
}
}
diff --git a/qt6/src/qml/private/ProgressBarImpl.qml b/qt6/src/qml/private/ProgressBarImpl.qml
index d9270975..a51c36aa 100644
--- a/qt6/src/qml/private/ProgressBarImpl.qml
+++ b/qt6/src/qml/private/ProgressBarImpl.qml
@@ -39,12 +39,34 @@ Item {
visible: progressBar.visualPosition > 0
Rectangle {
+ id: rect
anchors.fill: parent
radius: parent.cornerRadius
+ property int count
+ property real lightPosition
gradient: Gradient {
- GradientStop { position: 1 - 1 / progressBar.visualPosition; color: progressBar.palette.highlight }
- GradientStop {position: 1 - 0.28 / progressBar.visualPosition; color: progressBar.palette.highlight }
- GradientStop { position: 1; color: control.D.ColorSelector.handleGradientColor }
+ GradientStop { position: 0; color: progressBar.palette.highlight }
+ GradientStop { position: rect.lightPosition; color: control.D.ColorSelector.handleGradientColor }
+ GradientStop { position: 1; color: progressBar.palette.highlight }
+ }
+ Timer {
+ id: moveTimer
+ interval: 200
+ repeat: true
+ onTriggered: {
+ console.log("111111", rect.lightPosition)
+ moveTimer.interval = 200
+ if (rect.count === 10) {
+ rect.count = 0
+ moveTimer.interval = 2000
+ return;
+ }
+ rect.count += 1
+ rect.lightPosition = (rect.count % 10) * 0.1
+ }
+ }
+ Component.onCompleted: {
+ moveTimer.start()
}
}
}
diff --git a/src/private/dmessagemanager.cpp b/src/private/dmessagemanager.cpp
index 4d1bd33d..0941a416 100644
--- a/src/private/dmessagemanager.cpp
+++ b/src/private/dmessagemanager.cpp
@@ -188,11 +188,15 @@ void MessageManager::ensureLayout()
QQmlComponent columnCom(qmlEngine(parent()));
columnCom.setData("import QtQuick 2.11\n"
"Column {\n"
+ " spacing: 0\n"
" anchors {\n"
" bottom: parent.bottom\n"
- " bottomMargin: 10;\n"
+ " bottomMargin: 20;\n"
" horizontalCenter: parent.horizontalCenter\n"
" }\n"
+ " Component.onCompleted: {\n"
+ " console.log(\"parent onCompleted\", children.length);\n"
+ " }"
"}\n", QUrl());
auto layout = columnCom.beginCreate(qmlContext(parent()));
setLayout(qobject_cast(layout));