Compare commits

..

No commits in common. "4c1a96c03ec40415147632f39b932e16e1c52f68" and "a96191b2af42ac01b5d6617f2b474c84448f9375" have entirely different histories.

10 changed files with 263 additions and 268 deletions

View File

@ -18,10 +18,9 @@ on:
jobs:
build:
name: Build
runs-on: ${{ matrix.os }}
runs-on: windows-2022
strategy:
matrix:
os: [windows-2019]
include:
- qt_arch: win64_mingw
qt_ver: 6.5.0
@ -61,10 +60,8 @@ jobs:
id: build
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
mkdir build
cd build
ninja --version
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.5.0\mingw_64 -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release -GNinja ..
cmake --build . --target all --config Release --parallel

View File

@ -49,7 +49,6 @@ jobs:
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.msvc_arch }}
ninja --version
mkdir build
cd build
cmake -DCMAKE_MESSAGE_LOG_LEVEL=STATUS -DCMAKE_PREFIX_PATH=D:\a\FluentUI\Qt\6.5.0\msvc2019_64 -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl -DCMAKE_BUILD_TYPE=Release -GNinja ..

View File

@ -5,7 +5,7 @@ import QtQuick.Controls
import FluentUI
import "qrc:///example/qml/component"
FluContentPage {
FluScrollablePage {
title:"TreeView"
@ -28,47 +28,67 @@ FluContentPage {
return dig();
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 10
paddings: 10
height: 80
Column{
id:layout_column
spacing: 12
width: 300
anchors.verticalCenter: parent.verticalCenter
spacing: 10
FluText{
text:"高性能树控件新的TreeView用TableView实现"
}
FluText{
text:"共计:%1条数据当前显示的%2条数据".arg(tree_view.count()).arg(tree_view.visibleCount())
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 10
paddings: 10
height: 420
Item{
anchors.fill: tree_view
FluShadow{}
}
FluTreeView{
id:tree_view
width:slider_width.value
anchors{
topMargin: 20
top:parent.top
left:parent.left
leftMargin: 10
bottom:parent.bottom
bottomMargin: 20
}
FluText{
text:"共计%1条数据当前显示的%2条数据".arg(tree_view.count()).arg(tree_view.visibleCount())
draggable:switch_draggable.checked
showLine: switch_showline.checked
Component.onCompleted: {
var data = treeData()
dataSource = data
}
RowLayout{
spacing: 10
FluText{
text:"cellHeight:"
Layout.alignment: Qt.AlignVCenter
}
FluSlider{
id:slider_cell_height
value: 30
from: 30
to:100
}
Column{
spacing: 15
anchors{
top:parent.top
topMargin: 10
bottomMargin: 10
rightMargin: 10
bottom:parent.bottom
right: parent.right
}
RowLayout{
spacing: 10
FluText{
text:"depthPadding:"
text:"width:"
Layout.alignment: Qt.AlignVCenter
}
FluSlider{
id:slider_depth_padding
value: 30
from: 30
to:100
id:slider_width
value: 280
from: 160
to:400
}
}
FluToggleSwitch{
@ -94,28 +114,19 @@ FluContentPage {
}
}
}
FluArea{
anchors{
left: layout_column.right
top: parent.top
bottom: parent.bottom
right: parent.right
rightMargin: 5
topMargin: 5
bottomMargin: 5
}
FluShadow{}
FluTreeView{
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTreeView{
id:tree_view
anchors.fill: parent
cellHeight: slider_cell_height.value
draggable:switch_draggable.checked
showLine: switch_showline.checked
depthPadding: slider_depth_padding.value
width:240
height:600
Component.onCompleted: {
var data = treeData()
dataSource = data
}
}
'
}
}

View File

@ -183,7 +183,7 @@ CustomWindow {
z:999
//StackpopFluPagelaunchMode
// pageMode: FluNavigationViewType.Stack
//NoStackFluViewModel
//NoStack
pageMode: FluNavigationViewType.NoStack
items: ItemsOriginal
footerItems:ItemsFooter

View File

@ -6,7 +6,7 @@ import FluentUI 1.0
import "qrc:///example/qml/component"
import "../component"
FluContentPage {
FluScrollablePage {
title:"TreeView"
@ -29,47 +29,67 @@ FluContentPage {
return dig();
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 10
paddings: 10
height: 80
Column{
id:layout_column
spacing: 12
width: 300
anchors.verticalCenter: parent.verticalCenter
spacing: 10
FluText{
text:"高性能树控件新的TreeView用TableView实现"
}
FluText{
text:"共计:%1条数据当前显示的%2条数据".arg(tree_view.count()).arg(tree_view.visibleCount())
}
}
}
FluArea{
Layout.fillWidth: true
Layout.topMargin: 10
paddings: 10
height: 420
Item{
anchors.fill: tree_view
FluShadow{}
}
FluTreeView{
id:tree_view
width:slider_width.value
anchors{
topMargin: 20
top:parent.top
left:parent.left
leftMargin: 10
bottom:parent.bottom
bottomMargin: 20
}
FluText{
text:"共计%1条数据当前显示的%2条数据".arg(tree_view.count()).arg(tree_view.visibleCount())
draggable:switch_draggable.checked
showLine: switch_showline.checked
Component.onCompleted: {
var data = treeData()
dataSource = data
}
RowLayout{
spacing: 10
FluText{
text:"cellHeight:"
Layout.alignment: Qt.AlignVCenter
}
FluSlider{
id:slider_cell_height
value: 30
from: 30
to:100
}
Column{
spacing: 15
anchors{
top:parent.top
topMargin: 10
bottomMargin: 10
rightMargin: 10
bottom:parent.bottom
right: parent.right
}
RowLayout{
spacing: 10
FluText{
text:"depthPadding:"
text:"width:"
Layout.alignment: Qt.AlignVCenter
}
FluSlider{
id:slider_depth_padding
value: 30
from: 30
to:100
id:slider_width
value: 280
from: 160
to:400
}
}
FluToggleSwitch{
@ -95,28 +115,19 @@ FluContentPage {
}
}
}
FluArea{
anchors{
left: layout_column.right
top: parent.top
bottom: parent.bottom
right: parent.right
rightMargin: 5
topMargin: 5
bottomMargin: 5
}
FluShadow{}
FluTreeView{
CodeExpander{
Layout.fillWidth: true
Layout.topMargin: -1
code:'FluTreeView{
id:tree_view
anchors.fill: parent
cellHeight: slider_cell_height.value
draggable:switch_draggable.checked
showLine: switch_showline.checked
depthPadding: slider_depth_padding.value
width:240
height:600
Component.onCompleted: {
var data = treeData()
dataSource = data
}
}
'
}
}

View File

@ -186,7 +186,7 @@ CustomWindow {
z:999
//StackpopFluPagelaunchMode
// pageMode: FluNavigationViewType.Stack
//NoStackFluViewModel
//NoStack
pageMode: FluNavigationViewType.NoStack
items: ItemsOriginal
footerItems:ItemsFooter

View File

@ -119,8 +119,7 @@ void FluHttp::post(HttpRequest* r,HttpCallable* c){
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
QNetworkReply::NetworkError error = reply->error();
bool isSuccess = error == QNetworkReply::NoError;
bool isSuccess = reply->error() == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
@ -135,9 +134,6 @@ void FluHttp::post(HttpRequest* r,HttpCallable* c){
onError(callable,status,errorString,result);
}
}
if(error == QNetworkReply::OperationCanceledError){
break;
}
}
onFinish(callable,request);
});
@ -178,8 +174,7 @@ void FluHttp::postString(HttpRequest* r,HttpCallable* c){
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
QNetworkReply::NetworkError error = reply->error();
bool isSuccess = error == QNetworkReply::NoError;
bool isSuccess = reply->error() == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
@ -194,9 +189,6 @@ void FluHttp::postString(HttpRequest* r,HttpCallable* c){
onError(callable,status,errorString,result);
}
}
if(error == QNetworkReply::OperationCanceledError){
break;
}
}
onFinish(callable,request);
});
@ -236,8 +228,7 @@ void FluHttp::postJson(HttpRequest* r,HttpCallable* c){
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
QNetworkReply::NetworkError error = reply->error();
bool isSuccess = error == QNetworkReply::NoError;
bool isSuccess = reply->error() == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
@ -252,9 +243,6 @@ void FluHttp::postJson(HttpRequest* r,HttpCallable* c){
onError(callable,status,errorString,result);
}
}
if(error == QNetworkReply::OperationCanceledError){
break;
}
}
onFinish(callable,request);
});
@ -285,15 +273,14 @@ void FluHttp::get(HttpRequest* r,HttpCallable* c){
QNetworkRequest req(url);
addHeaders(&req,data["headers"].toMap());
QEventLoop loop;
auto reply = QPointer(manager.get(req));
QNetworkReply* reply = manager.get(req);
_cacheReply.append(reply);
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();});
loop.exec();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
QNetworkReply::NetworkError error = reply->error();
bool isSuccess = error == QNetworkReply::NoError;
bool isSuccess = reply->error() == QNetworkReply::NoError;
QString result = QString::fromUtf8(reply->readAll());
if (isSuccess) {
handleCache(httpId,result);
@ -309,9 +296,6 @@ void FluHttp::get(HttpRequest* r,HttpCallable* c){
}
reply->deleteLater();
reply = nullptr;
if(error == QNetworkReply::OperationCanceledError){
break;
}
}
onFinish(callable,request);
});

View File

@ -2,10 +2,15 @@
#include <QMetaEnum>
Node::Node(QObject *parent): QObject{parent}{
Node::Node(QObject *parent)
: QObject{parent}
{
}
FluTreeModel::FluTreeModel(QObject *parent): QAbstractItemModel{parent}{
FluTreeModel::FluTreeModel(QObject *parent)
: QAbstractItemModel{parent}
{
dataSourceSize(0);
}
@ -204,6 +209,7 @@ void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex,bool isDropTopArea){
}
_rows.move(dragIndex,targetIndex);
endMoveRows();
Q_EMIT layoutAboutToBeChanged();
if(dragItem->_parent == dropItem->_parent){
QList<Node*>* children = &(dragItem->_parent->_children);
@ -250,6 +256,7 @@ void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex,bool isDropTopArea){
}
}
srcChildren->removeAt(srcIndex);
if(dropIndex > dragIndex){
if(isDropTopArea){
targetIndex = destIndex;
@ -263,18 +270,26 @@ void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex,bool isDropTopArea){
targetIndex = destIndex + 1;
}
}
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){
auto itemData = _rows.at(row);
if(itemData->hasChildren() && itemData->_isExpanded){
return true;
}
// auto itemData = _rows.at(row);
// if(itemData->hasChildren() && itemData->_isExpanded){
// return true;
// }
return false;
}

View File

@ -10,8 +10,6 @@ Item {
property var dataSource
property bool showLine: true
property bool draggable: false
property int cellHeight: 30
property int depthPadding: 30
property color lineColor: FluTheme.dark ? Qt.rgba(111/255,111/255,111/255,1) : Qt.rgba(217/255,217/255,217/255,1)
id:control
QtObject {
@ -114,13 +112,13 @@ Item {
property bool isCurrent: d.current === itemModel
id:item_container
width: {
var w = 46 + item_loader_cell.width + control.depthPadding*itemModel.depth
var w = 46 + item_layout_text.width + 30*itemModel.depth
if(control.width>w){
return control.width
}
return w
}
height: control.cellHeight
height: 30
implicitWidth: width
implicitHeight: height
function toggle(){
@ -196,13 +194,13 @@ Item {
var pos = FluTools.cursorPos()
var viewPos = table_view.mapToGlobal(0,0)
var y = table_view.contentY + pos.y-viewPos.y
var index = Math.floor(y/control.cellHeight)
if(tree_model.hitHasChildrenExpanded(index) && y>index*control.cellHeight+control.cellHeight/2){
var index = Math.floor(y/30)
if(tree_model.hitHasChildrenExpanded(index) && y>index*30+15){
d.dropIndex = index + 1
d.isDropTopArea = true
}else{
d.dropIndex = index
if(y>index*control.cellHeight+control.cellHeight/2){
if(y>index*30+15){
d.isDropTopArea = false
}else{
d.isDropTopArea = true
@ -231,8 +229,14 @@ Item {
Rectangle{
id:item_line_drop_tip
anchors{
left: layout_row.left
leftMargin: 26
left: parent.left
leftMargin: {
var count = itemModel.depth+1
if(itemModel.hasChildren()){
return 30*count - 8
}
return 30*count + 18
}
right: parent.right
rightMargin: 10
bottom: parent.bottom
@ -279,18 +283,18 @@ Item {
height: itemModel.hideLineFooter() ? parent.height/2 : parent.height
anchors{
top: parent.top
left: item_line_h.left
right: layout_row.left
rightMargin: -9
}
}
FluRectangle{
id:item_line_h
height: 1
color: control.lineColor
visible: control.showLine && isItemLoader && itemModel.depth !== 0 && !itemModel.hasChildren()
width: depthPadding - 10
width: 18
anchors{
right: layout_row.left
rightMargin: -24
rightMargin: -27
verticalCenter: parent.verticalCenter
}
}
@ -305,7 +309,7 @@ Item {
top:parent.top
bottom: parent.bottom
left: parent.left
leftMargin: control.depthPadding*(index+1) + 24
leftMargin: 30*(index+2) - 8
}
}
}
@ -338,10 +342,9 @@ Item {
}
RowLayout{
id:layout_row
height: parent.height
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 14 + control.depthPadding*itemModel.depth
anchors.leftMargin: 14 + 30*itemModel.depth
Component{
id:com_icon_btn
FluIconButton{
@ -361,35 +364,18 @@ Item {
Layout.preferredWidth: 20
Layout.preferredHeight: 20
sourceComponent: itemModel.hasChildren() ? com_icon_btn : undefined
Layout.alignment: Qt.AlignVCenter
}
Loader{
property var modelData: itemModel
property var itemMouse: item_mouse
id:item_loader_cell
Layout.preferredWidth: {
if(item){
return item.width
}
return 0
}
Layout.fillHeight: true
sourceComponent:com_item_text
}
}
}
}
Component{
id:com_item_text
Item{
width: item_text.width
id:item_layout_text
Layout.preferredWidth: item_text.implicitWidth+14
Layout.preferredHeight:item_text.implicitHeight+14
Layout.alignment: Qt.AlignVCenter
FluText {
id:item_text
text: modelData.title
rightPadding: 14
text: itemModel.title
anchors.centerIn: parent
color:{
if(itemMouse.pressed){
if(item_mouse.pressed){
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
}
return FluTheme.dark ? FluColors.White : FluColors.Grey220
@ -397,6 +383,8 @@ Item {
}
}
}
}
}
function count(){
return tree_model.dataSourceSize
}
@ -415,4 +403,5 @@ Item {
function allCollapse(){
tree_model.allCollapse()
}
}

View File

@ -10,8 +10,6 @@ Item {
property var dataSource
property bool showLine: true
property bool draggable: false
property int cellHeight: 30
property int depthPadding: 30
property color lineColor: FluTheme.dark ? Qt.rgba(111/255,111/255,111/255,1) : Qt.rgba(217/255,217/255,217/255,1)
id:control
QtObject {
@ -114,13 +112,13 @@ Item {
property bool isCurrent: d.current === itemModel
id:item_container
width: {
var w = 46 + item_loader_cell.width + control.depthPadding*itemModel.depth
var w = 46 + item_layout_text.width + 30*itemModel.depth
if(control.width>w){
return control.width
}
return w
}
height: control.cellHeight
height: 30
implicitWidth: width
implicitHeight: height
function toggle(){
@ -196,13 +194,13 @@ Item {
var pos = FluTools.cursorPos()
var viewPos = table_view.mapToGlobal(0,0)
var y = table_view.contentY + pos.y-viewPos.y
var index = Math.floor(y/control.cellHeight)
if(tree_model.hitHasChildrenExpanded(index) && y>index*control.cellHeight+control.cellHeight/2){
var index = Math.floor(y/30)
if(tree_model.hitHasChildrenExpanded(index) && y>index*30+15){
d.dropIndex = index + 1
d.isDropTopArea = true
}else{
d.dropIndex = index
if(y>index*control.cellHeight+control.cellHeight/2){
if(y>index*30+15){
d.isDropTopArea = false
}else{
d.isDropTopArea = true
@ -231,8 +229,14 @@ Item {
Rectangle{
id:item_line_drop_tip
anchors{
left: layout_row.left
leftMargin: 26
left: parent.left
leftMargin: {
var count = itemModel.depth+1
if(itemModel.hasChildren()){
return 30*count - 8
}
return 30*count + 18
}
right: parent.right
rightMargin: 10
bottom: parent.bottom
@ -279,18 +283,18 @@ Item {
height: itemModel.hideLineFooter() ? parent.height/2 : parent.height
anchors{
top: parent.top
left: item_line_h.left
right: layout_row.left
rightMargin: -9
}
}
FluRectangle{
id:item_line_h
height: 1
color: control.lineColor
visible: control.showLine && isItemLoader && itemModel.depth !== 0 && !itemModel.hasChildren()
width: depthPadding - 10
width: 18
anchors{
right: layout_row.left
rightMargin: -24
rightMargin: -27
verticalCenter: parent.verticalCenter
}
}
@ -305,7 +309,7 @@ Item {
top:parent.top
bottom: parent.bottom
left: parent.left
leftMargin: control.depthPadding*(index+1) + 24
leftMargin: 30*(index+2) - 8
}
}
}
@ -338,10 +342,9 @@ Item {
}
RowLayout{
id:layout_row
height: parent.height
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 14 + control.depthPadding*itemModel.depth
anchors.leftMargin: 14 + 30*itemModel.depth
Component{
id:com_icon_btn
FluIconButton{
@ -361,35 +364,18 @@ Item {
Layout.preferredWidth: 20
Layout.preferredHeight: 20
sourceComponent: itemModel.hasChildren() ? com_icon_btn : undefined
Layout.alignment: Qt.AlignVCenter
}
Loader{
property var modelData: itemModel
property var itemMouse: item_mouse
id:item_loader_cell
Layout.preferredWidth: {
if(item){
return item.width
}
return 0
}
Layout.fillHeight: true
sourceComponent:com_item_text
}
}
}
}
Component{
id:com_item_text
Item{
width: item_text.width
id:item_layout_text
Layout.preferredWidth: item_text.implicitWidth+14
Layout.preferredHeight:item_text.implicitHeight+14
Layout.alignment: Qt.AlignVCenter
FluText {
id:item_text
text: modelData.title
rightPadding: 14
text: itemModel.title
anchors.centerIn: parent
color:{
if(itemMouse.pressed){
if(item_mouse.pressed){
return FluTheme.dark ? FluColors.Grey80 : FluColors.Grey120
}
return FluTheme.dark ? FluColors.White : FluColors.Grey220
@ -397,6 +383,8 @@ Item {
}
}
}
}
}
function count(){
return tree_model.dataSourceSize
}
@ -415,4 +403,5 @@ Item {
function allCollapse(){
tree_model.allCollapse()
}
}