DPS_Manage/DelegateUI/Controls/DelCollapse.qml

263 lines
9.4 KiB
QML

import QtQuick 2.15
import QtQuick.Templates 2.15 as T
import DelegateUI 1.0
Item {
id: control
height: __listView.contentHeight
titleFont {
family: DelTheme.DelCollapse.fontFamily
pixelSize: DelTheme.DelCollapse.fontSizeTitle
}
contentFont {
family: DelTheme.DelCollapse.fontFamily
pixelSize: DelTheme.DelCollapse.fontSizeContent
}
signal actived(key: string)
property bool animationEnabled: DelTheme.animationEnabled
property int hoverCursorShape: Qt.PointingHandCursor
property var initModel: []
property alias count: __listModel.count
property alias spacing: __listView.spacing
property bool accordion: false
property var activeKey: accordion ? "" : []
property var defaultActiveKey: []
property int expandIcon: DelIcon.RightOutlined
property font titleFont
property color colorBg: DelTheme.DelCollapse.colorBg
property color colorIcon: DelTheme.DelCollapse.colorIcon
property color colorTitle: DelTheme.DelCollapse.colorTitle
property color colorTitleBg: DelTheme.DelCollapse.colorTitleBg
property font contentFont
property color colorContent: DelTheme.DelCollapse.colorContent
property color colorContentBg: DelTheme.DelCollapse.colorContentBg
property color colorBorder: DelTheme.isDark ? DelTheme.DelCollapse.colorBorderDark : DelTheme.DelCollapse.colorBorder
property int radiusBg: 6
property Component titleDelegate: Row {
leftPadding: 16
rightPadding: 16
height: Math.max(40, __icon.height, __title.height)
spacing: 8
DelIconText {
id: __icon
anchors.verticalCenter: parent.verticalCenter
iconSource: control.expandIcon
colorIcon: control.colorIcon
rotation: isActive ? 90 : 0
Behavior on rotation { enabled: control.animationEnabled; RotationAnimation { duration: DelTheme.Primary.durationFast } }
}
Text {
id: __title
anchors.verticalCenter: parent.verticalCenter
text: model.title
elide: Text.ElideRight
font: control.titleFont
color: control.colorTitle
}
HoverHandler {
cursorShape: control.hoverCursorShape
}
}
property Component contentDelegate: DelCopyableText {
padding: 16
topPadding: 8
bottomPadding: 8
text: model.content
font: control.contentFont
wrapMode: Text.WordWrap
color: control.colorContent
}
onInitModelChanged: {
clear();
for (const object of initModel) {
append(object);
}
}
function get(index) {
return __listModel.get(index);
}
function set(index, object) {
__listModel.set(index, object);
}
function setProperty(index, propertyName, value) {
__listModel.setProperty(index, propertyName, value);
}
function move(from, to, count = 1) {
__listModel.move(from, to, count);
}
function insert(index, object) {
__listModel.insert(index, object);
}
function append(object) {
__listModel.append(object);
}
function remove(index, count = 1) {
__listModel.remove(index, count);
}
function clear() {
__listModel.clear();
}
Behavior on colorBg { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
Behavior on colorTitle { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
Behavior on colorTitleBg { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
Behavior on colorContent { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
Behavior on colorContentBg { enabled: control.animationEnabled; ColorAnimation { duration: DelTheme.Primary.durationFast } }
QtObject {
id: __private
function calcActiveKey() {
if (control.accordion) {
for (let i = 0; i < __listView.count; i++) {
const item = __listView.itemAtIndex(i);
if (item && item.active) {
control.activeKey = item.model.key;
break;
}
}
} else {
let keys = [];
for (let i = 0; i < __listView.count; i++) {
const item = __listView.itemAtIndex(i);
if (item && item.active) {
keys.push(item.model.key);
}
}
control.activeKey = keys;
}
}
}
ListView {
id: __listView
anchors.fill: parent
interactive: false
spacing: -1
model: ListModel { id: __listModel }
onContentHeightChanged: cacheBuffer = contentHeight;
delegate: DelRectangle {
id: __rootItem
width: __listView.width
height: __column.height + ((detached && active) ? 1 : 0)
topLeftRadius: (isStart || detached) ? control.radiusBg : 0
topRightRadius: (isStart || detached) ? control.radiusBg : 0
bottomLeftRadius: (isEnd || detached) ? control.radiusBg : 0
bottomRightRadius: (isEnd || detached) ? control.radiusBg : 0
color: control.colorBg
border.color: control.colorBorder
border.width: detached ? 1 : 0
clip: true
required property var model
required property int index
property bool isStart: index == 0
property bool isEnd: (index + 1) === control.count
property bool active: false
property bool detached: __listView.spacing !== -1
Component.onCompleted: {
if (control.defaultActiveKey.indexOf(model.key) != -1)
active = true;
}
Column {
id: __column
width: parent.width
anchors.horizontalCenter: parent.horizontalCenter
DelRectangle {
width: parent.width
height: __titleLoader.height
topLeftRadius: (isStart || detached) ? control.radiusBg : 0
topRightRadius: (isStart || detached) ? control.radiusBg : 0
bottomLeftRadius: (isEnd && !active) || (detached && !active) ? control.radiusBg : 0
bottomRightRadius: (isEnd && !active) || (detached && !active) ? control.radiusBg : 0
color: control.colorTitleBg
border.color: control.colorBorder
Loader {
id: __titleLoader
width: parent.width
sourceComponent: titleDelegate
property alias model: __rootItem.model
property alias index: __rootItem.index
property alias isActive: __rootItem.active
HoverHandler {
cursorShape: Qt.PointingHandCursor
}
TapHandler {
onTapped: {
if (control.accordion) {
for (let i = 0; i < __listView.count; i++) {
const item = __listView.itemAtIndex(i);
if (item && item !== __rootItem) {
item.active = false;
}
}
__rootItem.active = !__rootItem.active;
} else {
__rootItem.active = !__rootItem.active;
}
if (__rootItem.active)
control.actived(__rootItem.model.key);
__private.calcActiveKey();
}
}
}
}
DelRectangle {
width: parent.width - __rootItem.border.width * 2
height: active ? __contentLoader.height : 0
anchors.horizontalCenter: parent.horizontalCenter
bottomLeftRadius: control.radiusBg
bottomRightRadius: control.radiusBg
color: control.colorContentBg
clip: true
Behavior on height { enabled: control.animationEnabled; NumberAnimation { duration: DelTheme.Primary.durationFast } }
Loader {
id: __contentLoader
width: parent.width
anchors.centerIn: parent
sourceComponent: contentDelegate
property alias model: __rootItem.model
property alias index: __rootItem.index
property alias isActive: __rootItem.active
}
}
}
}
}
Loader {
anchors.fill: __listView
active: spacing === -1
sourceComponent: Rectangle {
color: "transparent"
border.color: control.colorBorder
radius: control.radiusBg
}
}
}