Skip to content

Commit c9d2e27

Browse files
committed
Feat: 添加[DelCollapse]实现.
1 parent d099f8b commit c9d2e27

10 files changed

+780
-1
lines changed

CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ add_subdirectory(DelOTPInput)
4343
add_subdirectory(DelSlider)
4444
add_subdirectory(DelScrollBar)
4545
add_subdirectory(DelTimePicker)
46+
add_subdirectory(DelDrawer)
47+
add_subdirectory(DelCollapse)
4648

4749
# Deploy Script
4850
if(CMAKE_BUILD_TYPE MATCHES "Release")
@@ -84,6 +86,8 @@ if(CMAKE_BUILD_TYPE MATCHES "Release")
8486
COMMAND ${QT_DEPLOY_QT} ${CMAKE_SOURCE_DIR}/package/DelSlider.app -qmldir=DelSlider
8587
COMMAND ${QT_DEPLOY_QT} ${CMAKE_SOURCE_DIR}/package/DelScrollBar.app -qmldir=DelScrollBar
8688
COMMAND ${QT_DEPLOY_QT} ${CMAKE_SOURCE_DIR}/package/DelTimePicker.app -qmldir=DelTimePicker
89+
COMMAND ${QT_DEPLOY_QT} ${CMAKE_SOURCE_DIR}/package/DelDrawer.app -qmldir=DelDrawer
90+
COMMAND ${QT_DEPLOY_QT} ${CMAKE_SOURCE_DIR}/package/DelCollapse.app -qmldir=DelCollapse
8791
COMMENT "MacOs Deploying Qt Dependencies After Build........."
8892
SOURCES ${CMAKE_SOURCE_DIR}/CMakeLists.txt
8993
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
@@ -127,6 +131,8 @@ if(CMAKE_BUILD_TYPE MATCHES "Release")
127131
COMMAND ${QT_DEPLOY_QT} --qmldir=DelSlider --no-translations --compiler-runtime ${CMAKE_SOURCE_DIR}/package/DelSlider.exe
128132
COMMAND ${QT_DEPLOY_QT} --qmldir=DelScrollBar --no-translations --compiler-runtime ${CMAKE_SOURCE_DIR}/package/DelScrollBar.exe
129133
COMMAND ${QT_DEPLOY_QT} --qmldir=DelTimePicker --no-translations --compiler-runtime ${CMAKE_SOURCE_DIR}/package/DelTimePicker.exe
134+
COMMAND ${QT_DEPLOY_QT} --qmldir=DelDrawer --no-translations --compiler-runtime ${CMAKE_SOURCE_DIR}/package/DelDrawer.exe
135+
COMMAND ${QT_DEPLOY_QT} --qmldir=DelCollapse --no-translations --compiler-runtime ${CMAKE_SOURCE_DIR}/package/DelCollapse.exe
130136
COMMENT "Windows Deploying Qt Dependencies After Build........."
131137
SOURCES ${CMAKE_SOURCE_DIR}/CMakeLists.txt
132138
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}

DelCollapse/CMakeLists.txt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
project(DelCollapse VERSION 1.0 LANGUAGES CXX)
4+
5+
set(CMAKE_AUTOMOC ON)
6+
set(CMAKE_AUTORCC ON)
7+
8+
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Quick)
9+
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Quick)
10+
11+
set(SOURCES main.cpp delrectangle.h delrectangle.cpp)
12+
13+
qt5_add_resources(SOURCES qml.qrc)
14+
15+
add_executable(${PROJECT_NAME} ${SOURCES} "${CMAKE_SOURCE_DIR}/common/QmlControls_Resource.rc")
16+
17+
set_target_properties(${PROJECT_NAME} PROPERTIES
18+
WIN32_EXECUTABLE TRUE
19+
RUNTIME_OUTPUT_DIRECTORY $<IF:$<BOOL:${BUILD_OUTPUT_DIRECTORY}>,${BUILD_OUTPUT_DIRECTORY},${CMAKE_RUNTIME_OUTPUT_DIRECTORY}>
20+
)
21+
22+
target_link_libraries(${PROJECT_NAME} PRIVATE
23+
Qt::Quick
24+
Qt::QuickPrivate
25+
)

DelCollapse/DelCollapse.pro

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
QT += quick
2+
3+
# You can make your code fail to compile if it uses deprecated APIs.
4+
# In order to do so, uncomment the following line.
5+
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
6+
7+
HEADERS += delrectangle.h
8+
9+
SOURCES += \
10+
main.cpp
11+
delrectangle.cpp
12+
13+
RESOURCES += qml.qrc
14+
15+
# Additional import path used to resolve QML modules in Qt Creator's code model
16+
QML_IMPORT_PATH =
17+
18+
# Additional import path used to resolve QML modules just for Qt Quick Designer
19+
QML_DESIGNER_IMPORT_PATH =
20+
21+
# Default rules for deployment.
22+
qnx: target.path = /tmp/$${TARGET}/bin
23+
else: unix:!android: target.path = /opt/$${TARGET}/bin
24+
!isEmpty(target.path): INSTALLS += target

DelCollapse/DelCollapse.qml

+259
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
import QtQuick 2.15
2+
import QtQuick.Templates 2.15 as T
3+
import DelegateUI.Controls 1.0
4+
5+
import "qrc:/../common"
6+
7+
Item {
8+
id: control
9+
10+
height: __listView.contentHeight
11+
12+
titleFont {
13+
family: "微软雅黑"
14+
pixelSize: 14
15+
}
16+
contentFont {
17+
family: "微软雅黑"
18+
pixelSize: 14
19+
}
20+
21+
signal actived(key: string);
22+
23+
property bool animationEnabled: true
24+
property var initModel: []
25+
property alias count: __listModel.count
26+
property alias spacing: __listView.spacing
27+
property bool accordion: false
28+
property var activeKey: accordion ? "" : []
29+
property var defaultActiveKey: []
30+
property int expandIcon: DelIcon.RightOutlined
31+
property font titleFont
32+
property color colorBg: "#fff"
33+
property color colorIcon: Qt.rgba(0,0,0,0.88)
34+
property color colorTitle: Qt.rgba(0,0,0,0.88)
35+
property color colorTitleBg: Qt.rgba(0,0,0,0.04)
36+
property font contentFont
37+
property color colorContent: Qt.rgba(0,0,0,0.88)
38+
property color colorContentBg: "#fff"
39+
property color colorBorder: Qt.darker("#fff", 1.18)
40+
property int radiusBg: 6
41+
property Component titleDelegate: Row {
42+
leftPadding: 16
43+
rightPadding: 16
44+
height: Math.max(40, __icon.height, __title.height)
45+
spacing: 8
46+
47+
DelIconText {
48+
id: __icon
49+
anchors.verticalCenter: parent.verticalCenter
50+
iconSource: control.expandIcon
51+
colorIcon: control.colorIcon
52+
rotation: isActive ? 90 : 0
53+
54+
Behavior on rotation { enabled: control.animationEnabled; RotationAnimation { duration: 100 } }
55+
}
56+
57+
Text {
58+
id: __title
59+
anchors.verticalCenter: parent.verticalCenter
60+
text: model.title
61+
elide: Text.ElideRight
62+
font: control.titleFont
63+
color: control.colorTitle
64+
}
65+
}
66+
property Component contentDelegate: DelCopyableText {
67+
padding: 16
68+
topPadding: 8
69+
bottomPadding: 8
70+
text: model.content
71+
font: control.contentFont
72+
wrapMode: Text.WordWrap
73+
color: control.colorContent
74+
}
75+
76+
onInitModelChanged: {
77+
clear();
78+
for (const object of initModel) {
79+
append(object);
80+
}
81+
}
82+
83+
function get(index) {
84+
return __listModel.get(index);
85+
}
86+
87+
function set(index, object) {
88+
__listModel.set(index, object);
89+
}
90+
91+
function setProperty(index, propertyName, value) {
92+
__listModel.setProperty(index, propertyName, value);
93+
}
94+
95+
function move(from, to, count = 1) {
96+
__listModel.move(from, to, count);
97+
}
98+
99+
function insert(index, object) {
100+
__listModel.insert(index, object);
101+
}
102+
103+
function append(object) {
104+
__listModel.append(object);
105+
}
106+
107+
function removeAt(index, count = 1) {
108+
__listModel.remove(index, count);
109+
}
110+
111+
function clear() {
112+
__listModel.clear();
113+
}
114+
115+
Behavior on colorBg { enabled: control.animationEnabled; ColorAnimation { duration: 100 } }
116+
Behavior on colorTitle { enabled: control.animationEnabled; ColorAnimation { duration: 100 } }
117+
Behavior on colorTitleBg { enabled: control.animationEnabled; ColorAnimation { duration: 100 } }
118+
Behavior on colorContent { enabled: control.animationEnabled; ColorAnimation { duration: 100 } }
119+
Behavior on colorContentBg { enabled: control.animationEnabled; ColorAnimation { duration: 100 } }
120+
121+
QtObject {
122+
id: __private
123+
function calcActiveKey() {
124+
if (control.accordion) {
125+
for (let i = 0; i < __listView.count; i++) {
126+
const item = __listView.itemAtIndex(i);
127+
if (item && item.active) {
128+
control.activeKey = item.model.key;
129+
break;
130+
}
131+
}
132+
} else {
133+
let keys = [];
134+
for (let i = 0; i < __listView.count; i++) {
135+
const item = __listView.itemAtIndex(i);
136+
if (item && item.active) {
137+
keys.push(item.model.key);
138+
}
139+
}
140+
control.activeKey = keys;
141+
}
142+
}
143+
}
144+
145+
ListView {
146+
id: __listView
147+
anchors.fill: parent
148+
interactive: false
149+
spacing: -1
150+
model: ListModel { id: __listModel }
151+
onContentHeightChanged: if (contentHeight > 0) cacheBuffer = contentHeight;
152+
delegate: DelRectangle {
153+
id: __rootItem
154+
width: __listView.width
155+
height: __column.height + ((detached && active) ? 1 : 0)
156+
topLeftRadius: (isStart || detached) ? control.radiusBg : 0
157+
topRightRadius: (isStart || detached) ? control.radiusBg : 0
158+
bottomLeftRadius: (isEnd || detached) ? control.radiusBg : 0
159+
bottomRightRadius: (isEnd || detached) ? control.radiusBg : 0
160+
color: control.colorBg
161+
border.color: control.colorBorder
162+
border.width: detached
163+
clip: true
164+
165+
required property var model
166+
required property int index
167+
property bool isStart: index == 0
168+
property bool isEnd: (index + 1) === control.count
169+
property bool active: false
170+
property bool detached: __listView.spacing !== -1
171+
172+
Component.onCompleted: {
173+
if (control.defaultActiveKey.indexOf(model.key) != -1)
174+
active = true;
175+
}
176+
177+
Column {
178+
id: __column
179+
width: parent.width
180+
anchors.horizontalCenter: parent.horizontalCenter
181+
182+
DelRectangle {
183+
width: parent.width
184+
height: __titleLoader.height
185+
topLeftRadius: (isStart || detached) ? control.radiusBg : 0
186+
topRightRadius: (isStart || detached) ? control.radiusBg : 0
187+
bottomLeftRadius: (isEnd && !active) || (detached && !active) ? control.radiusBg : 0
188+
bottomRightRadius: (isEnd && !active) || (detached && !active) ? control.radiusBg : 0
189+
color: control.colorTitleBg
190+
border.color: control.colorBorder
191+
192+
Loader {
193+
id: __titleLoader
194+
width: parent.width
195+
sourceComponent: titleDelegate
196+
property alias model: __rootItem.model
197+
property alias index: __rootItem.index
198+
property alias isActive: __rootItem.active
199+
200+
HoverHandler {
201+
cursorShape: Qt.PointingHandCursor
202+
}
203+
204+
TapHandler {
205+
onTapped: {
206+
if (control.accordion) {
207+
for (let i = 0; i < __listView.count; i++) {
208+
const item = __listView.itemAtIndex(i);
209+
if (item && item !== __rootItem) {
210+
item.active = false;
211+
}
212+
}
213+
__rootItem.active = !__rootItem.active;
214+
} else {
215+
__rootItem.active = !__rootItem.active;
216+
}
217+
if (__rootItem.active)
218+
control.actived(__rootItem.model.key);
219+
__private.calcActiveKey();
220+
}
221+
}
222+
}
223+
}
224+
225+
DelRectangle {
226+
width: parent.width
227+
height: active ? __contentLoader.height : 0
228+
anchors.horizontalCenter: parent.horizontalCenter
229+
bottomLeftRadius: control.radiusBg
230+
bottomRightRadius: control.radiusBg
231+
color: control.colorContentBg
232+
clip: true
233+
234+
Behavior on height { enabled: control.animationEnabled; NumberAnimation { duration: 100 } }
235+
236+
Loader {
237+
id: __contentLoader
238+
width: parent.width
239+
anchors.centerIn: parent
240+
sourceComponent: contentDelegate
241+
property alias model: __rootItem.model
242+
property alias index: __rootItem.index
243+
property alias isActive: __rootItem.active
244+
}
245+
}
246+
}
247+
}
248+
}
249+
250+
Loader {
251+
anchors.fill: __listView
252+
active: spacing === -1
253+
sourceComponent: Rectangle {
254+
color: "transparent"
255+
border.color: control.colorBorder
256+
radius: control.radiusBg
257+
}
258+
}
259+
}

0 commit comments

Comments
 (0)