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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,11 +27,76 @@ Item {
FluTreeModel{
id:tree_model
}
Timer{
id:timer_refresh
interval: 10
onTriggered: {
table_view.forceLayout()
ListView{
id:table_view
ScrollBar.horizontal: FluScrollBar{}
ScrollBar.vertical: FluScrollBar{}
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{
@ -102,7 +167,7 @@ Item {
loader_container.width = item_container.width
loader_container.height = item_container.height
loader_container.x = 0
loader_container.y = cellPosition.y + table_view.contentY
loader_container.y = cellPosition.y
}
onClicked: {
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(){
return tree_model.dataSourceSize
}