This commit is contained in:
zhuzichu 2023-09-21 18:29:09 +08:00
parent 28e1799ca4
commit a96191b2af
7 changed files with 173 additions and 114 deletions

View File

@ -10,9 +10,9 @@ FluScrollablePage {
title:"TreeView" title:"TreeView"
function treeData(){ function treeData(){
const dig = (path = '0', level = 3) => { const dig = (path = '0', level = 4) => {
const list = []; const list = [];
for (let i = 0; i < 8; i += 1) { for (let i = 0; i < 9; i += 1) {
const key = `${path}-${i}`; const key = `${path}-${i}`;
const treeNode = { const treeNode = {
title: key, title: key,
@ -130,4 +130,3 @@ FluScrollablePage {
' '
} }
} }

View File

@ -11,9 +11,9 @@ FluScrollablePage {
title:"TreeView" title:"TreeView"
function treeData(){ function treeData(){
const dig = (path = '0', level = 3) => { const dig = (path = '0', level = 4) => {
const list = []; const list = [];
for (let i = 0; i < 8; i += 1) { for (let i = 0; i < 9; i += 1) {
const key = `${path}-${i}`; const key = `${path}-${i}`;
const treeNode = { const treeNode = {
title: key, title: key,

View File

@ -13,6 +13,7 @@
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QTextDocument> #include <QTextDocument>
#include <QQuickWindow> #include <QQuickWindow>
#include <QDateTime>
FluTools::FluTools(QObject *parent):QObject{parent}{ FluTools::FluTools(QObject *parent):QObject{parent}{
@ -170,3 +171,7 @@ bool FluTools::isSoftware(){
QPoint FluTools::cursorPos(){ QPoint FluTools::cursorPos(){
return QCursor::pos(); return QCursor::pos();
} }
qint64 FluTools::currentTimestamp(){
return QDateTime::currentMSecsSinceEpoch();
}

View File

@ -47,6 +47,7 @@ public:
Q_INVOKABLE bool removeFile(QString filePath); Q_INVOKABLE bool removeFile(QString filePath);
Q_INVOKABLE void showFileInFolder(QString path); Q_INVOKABLE void showFileInFolder(QString path);
Q_INVOKABLE bool isSoftware(); Q_INVOKABLE bool isSoftware();
Q_INVOKABLE qint64 currentTimestamp();
Q_INVOKABLE QPoint cursorPos(); Q_INVOKABLE QPoint cursorPos();
}; };

View File

@ -56,9 +56,11 @@ void FluTreeModel::removeRows(int row,int count){
if (row < 0 || row + count > _rows.size() || count==0) if (row < 0 || row + count > _rows.size() || count==0)
return; return;
beginRemoveRows(QModelIndex(),row, row + count - 1); beginRemoveRows(QModelIndex(),row, row + count - 1);
for (int i = 0; i < count; ++i) { QList<Node*> firstPart = _rows.mid(0,row);
_rows.removeAt(row); QList<Node*> secondPart = _rows.mid(row + count);
} _rows.clear();
_rows.append(firstPart);
_rows.append(secondPart);
endRemoveRows(); endRemoveRows();
} }
@ -66,9 +68,12 @@ void FluTreeModel::insertRows(int row,QList<Node*> data){
if (row < 0 || row > _rows.size() || data.size() == 0) if (row < 0 || row > _rows.size() || data.size() == 0)
return;; return;;
beginInsertRows(QModelIndex(), row, row + data.size() - 1); beginInsertRows(QModelIndex(), row, row + data.size() - 1);
for (const auto& item : data) { QList<Node*> firstPart = _rows.mid(0, row);
_rows.insert(row++, item); QList<Node*> secondPart = _rows.mid(row);
} _rows.clear();
_rows.append(firstPart);
_rows.append(data);
_rows.append(secondPart);
endInsertRows(); endInsertRows();
} }
@ -84,6 +89,7 @@ void FluTreeModel::setDataSource(QList<QMap<QString,QVariant>> data){
} }
_root = new Node(this); _root = new Node(this);
std::reverse(data.begin(), data.end()); std::reverse(data.begin(), data.end());
auto startTime = QDateTime::currentMSecsSinceEpoch();
while (data.count() > 0) { while (data.count() > 0) {
auto item = data.at(data.count()-1); auto item = data.at(data.count()-1);
data.pop_back(); data.pop_back();
@ -104,8 +110,8 @@ void FluTreeModel::setDataSource(QList<QMap<QString,QVariant>> data){
QList<QVariant> children = item.value("children").toList(); QList<QVariant> children = item.value("children").toList();
if(!children.isEmpty()){ if(!children.isEmpty()){
std::reverse(children.begin(), children.end()); std::reverse(children.begin(), children.end());
foreach (auto c, children) { for (int i = 0; i < children.count(); ++i) {
auto child = c.toMap(); auto child = children.at(i).toMap();
child.insert("__depth",item.value("__depth").toInt(0)+1); child.insert("__depth",item.value("__depth").toInt(0)+1);
child.insert("__parent",QVariant::fromValue(node)); child.insert("__parent",QVariant::fromValue(node));
data.append(child); data.append(child);
@ -113,6 +119,7 @@ void FluTreeModel::setDataSource(QList<QMap<QString,QVariant>> data){
} }
} }
} }
auto endTime = QDateTime::currentMSecsSinceEpoch();
beginResetModel(); beginResetModel();
_rows = _dataSource; _rows = _dataSource;
endResetModel(); endResetModel();
@ -170,19 +177,58 @@ void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex,bool isDropTopArea){
} }
auto dragItem = _rows[dragIndex]; auto dragItem = _rows[dragIndex];
auto dropItem = _rows[dropIndex]; auto dropItem = _rows[dropIndex];
if (!beginMoveRows(QModelIndex(), dragIndex, dragIndex, QModelIndex(), dropIndex > dragIndex ? dropIndex+1 : dropIndex)) { int targetIndex;
if(dropIndex > dragIndex){
if(isDropTopArea){
targetIndex = dropIndex;
}else{
targetIndex = dropIndex+1;
}
}else{
if(isDropTopArea){
targetIndex = dropIndex;
}else{
targetIndex = dropIndex+1;
}
}
if (!beginMoveRows(QModelIndex(), dragIndex, dragIndex, QModelIndex(), targetIndex)) {
return; return;
} }
if(dropIndex > dragIndex){
if(isDropTopArea){
targetIndex = dropIndex-1;
}else{
targetIndex = dropIndex;
}
}else{
if(isDropTopArea){
targetIndex = dropIndex;
}else{
targetIndex = dropIndex+1;
}
}
_rows.move(dragIndex,targetIndex);
endMoveRows();
Q_EMIT layoutAboutToBeChanged();
if(dragItem->_parent == dropItem->_parent){ if(dragItem->_parent == dropItem->_parent){
QList<Node*>* children = &(dragItem->_parent->_children); QList<Node*>* children = &(dragItem->_parent->_children);
int srcIndex = children->indexOf(dragItem); int srcIndex = children->indexOf(dragItem);
int destIndex = children->indexOf(dropItem); int destIndex = children->indexOf(dropItem);
int offset = 1; if(dropIndex > dragIndex){
if(isDropTopArea){ if(isDropTopArea){
offset = offset - 1; targetIndex = destIndex-1;
}else{
targetIndex = destIndex;
}
}else{
if(isDropTopArea){
targetIndex = destIndex;
}else{
targetIndex = destIndex+1;
}
} }
children->move(srcIndex,destIndex>srcIndex? destIndex-1 + offset : destIndex + offset); children->move(srcIndex,targetIndex);
_rows.move(dragIndex,dropIndex>dragIndex? dropIndex-1 + offset : dropIndex + offset);
}else{ }else{
QList<Node*>* srcChildren = &(dragItem->_parent->_children); QList<Node*>* srcChildren = &(dragItem->_parent->_children);
QList<Node*>* destChildren = &(dropItem->_parent->_children); QList<Node*>* destChildren = &(dropItem->_parent->_children);
@ -210,25 +256,40 @@ void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex,bool isDropTopArea){
} }
} }
srcChildren->removeAt(srcIndex); srcChildren->removeAt(srcIndex);
int offset = 0;
if(!isDropTopArea){ if(dropIndex > dragIndex){
offset = offset + 1; if(isDropTopArea){
targetIndex = destIndex;
}else{
targetIndex = destIndex + 1;
}
}else{
if(isDropTopArea){
targetIndex = destIndex;
}else{
targetIndex = destIndex + 1;
}
} }
destChildren->insert(destIndex+offset,dragItem);
offset = 1; destChildren->insert(targetIndex,dragItem);
if(isDropTopArea){
offset = offset - 1; foreach (auto item,*destChildren) {
qDebug()<<item->title();
} }
_rows.move(dragIndex,dropIndex>dragIndex? dropIndex-1+offset : dropIndex+offset);
} }
endMoveRows();
changePersistentIndex(index(qMin(dragIndex,dropIndex),0),index(qMax(dragIndex,dropIndex),0));
Q_EMIT layoutChanged(QList<QPersistentModelIndex>(),QAbstractItemModel::VerticalSortHint);
} }
bool FluTreeModel::hitHasChildrenExpanded(int row){ bool FluTreeModel::hitHasChildrenExpanded(int row){
// auto itemData = _rows.at(row); // auto itemData = _rows.at(row);
// if(itemData->hasChildren() && itemData->_isExpanded){ // if(itemData->hasChildren() && itemData->_isExpanded){
// return true; // return true;
// } // }
return false; return false;
} }

View File

@ -54,6 +54,9 @@ Item {
} }
} }
} }
move: Transition {
NumberAnimation { property: "y"; duration: 200 }
}
add: Transition{ add: Transition{
ParallelAnimation{ ParallelAnimation{
NumberAnimation { NumberAnimation {
@ -164,7 +167,7 @@ Item {
loader_container.width = item_container.width loader_container.width = item_container.width
loader_container.height = item_container.height loader_container.height = item_container.height
loader_container.x = 0 loader_container.x = 0
loader_container.y = cellPosition.y + table_view.contentY loader_container.y = cellPosition.y
} }
onClicked: { onClicked: {
d.current = itemModel d.current = itemModel

View File

@ -27,11 +27,76 @@ Item {
FluTreeModel{ FluTreeModel{
id:tree_model id:tree_model
} }
Timer{ ListView{
id:timer_refresh id:table_view
interval: 10 ScrollBar.horizontal: FluScrollBar{}
onTriggered: { ScrollBar.vertical: FluScrollBar{}
table_view.forceLayout() boundsBehavior: Flickable.StopAtBounds
model: tree_model
anchors.fill: parent
clip: true
flickableDirection: Flickable.HorizontalAndVerticalFlick
contentWidth: contentItem.childrenRect.width
reuseItems: true
removeDisplaced : Transition{
ParallelAnimation{
NumberAnimation {
properties: "y"
duration: 167
from: d.dy + table_view.height
easing.type: Easing.OutCubic
}
NumberAnimation {
properties: "opacity"
duration: 300
from: 0
to: 1
}
}
}
move: Transition {
NumberAnimation { property: "y"; duration: 200 }
}
add: Transition{
ParallelAnimation{
NumberAnimation {
properties: "y"
duration: 167
from: d.dy
easing.type: Easing.OutCubic
}
NumberAnimation {
properties: "opacity"
duration: 300
from: 0
to: 1
}
}
}
delegate: Item {
id:item_control
implicitWidth: item_loader_container.width
implicitHeight: item_loader_container.height
ListView.onReused: {
item_loader_container.item.reused()
}
ListView.onPooled: {
item_loader_container.item.pooled()
}
Loader{
property var itemControl: item_control
property var itemModel: modelData
property int rowIndex: index
property bool isItemLoader: true
id:item_loader_container
sourceComponent: com_item_container
}
}
Loader{
id:loader_container
property var itemControl
property var itemModel
property bool isItemLoader: false
} }
} }
Component{ Component{
@ -102,7 +167,7 @@ Item {
loader_container.width = item_container.width loader_container.width = item_container.width
loader_container.height = item_container.height loader_container.height = item_container.height
loader_container.x = 0 loader_container.x = 0
loader_container.y = cellPosition.y + table_view.contentY loader_container.y = cellPosition.y
} }
onClicked: { onClicked: {
d.current = itemModel d.current = itemModel
@ -320,81 +385,6 @@ Item {
} }
} }
} }
ScrollView{
id:scroll_view
anchors.fill: parent
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
clip: true
ListView{
id:table_view
ScrollBar.horizontal: FluScrollBar{}
ScrollBar.vertical: FluScrollBar{}
boundsBehavior: Flickable.StopAtBounds
model: tree_model
clip: true
anchors.fill: parent
contentWidth: contentItem.childrenRect.width
reuseItems: true
removeDisplaced : Transition{
ParallelAnimation{
NumberAnimation {
properties: "y"
duration: 167
from: d.dy + table_view.height
easing.type: Easing.OutCubic
}
NumberAnimation {
properties: "opacity"
duration: 300
from: 0
to: 1
}
}
}
add: Transition{
ParallelAnimation{
NumberAnimation {
properties: "y"
duration: 167
from: d.dy
easing.type: Easing.OutCubic
}
NumberAnimation {
properties: "opacity"
duration: 300
from: 0
to: 1
}
}
}
delegate: Item {
id:item_control
implicitWidth: item_loader_container.width
implicitHeight: item_loader_container.height
ListView.onReused: {
item_loader_container.item.reused()
}
ListView.onPooled: {
item_loader_container.item.pooled()
}
Loader{
property var itemControl: item_control
property var itemModel: modelData
property int rowIndex: index
property bool isItemLoader: true
id:item_loader_container
sourceComponent: com_item_container
}
}
}
Loader{
id:loader_container
property var itemControl
property var itemModel
property bool isItemLoader: false
}
}
function count(){ function count(){
return tree_model.dataSourceSize return tree_model.dataSourceSize
} }