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));