This commit is contained in:
zhuzichu 2023-09-18 18:10:27 +08:00
parent 257f3a7b3d
commit b27a88d261
8 changed files with 150 additions and 105 deletions

View File

@ -87,22 +87,20 @@ FluScrollablePage {
} }
FluSlider{ FluSlider{
id:slider_width id:slider_width
value: 200 value: 280
from: 160 from: 160
to:400 to:400
} }
} }
FluToggleSwitch{ FluToggleSwitch{
id:switch_showline id:switch_showline
text:"showLine" text:"showLine"
checked: true checked: true
} }
FluToggleSwitch{ FluToggleSwitch{
id:switch_draggable id:switch_draggable
text:"draggable" text:"draggable"
checked: false checked: true
} }
} }
} }

View File

@ -155,7 +155,7 @@ void FluTreeModel::expand(int row){
} }
void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex){ void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex){
if(dragIndex == dropIndex+1){ if(dragIndex == dropIndex+1 || dropIndex>_rows.count() || dropIndex<0){
return; return;
} }
auto dragItem = _rows[dragIndex]; auto dragItem = _rows[dragIndex];
@ -164,18 +164,11 @@ void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex){
return; return;
} }
if(dragItem->_parent == dropItem->_parent){ if(dragItem->_parent == dropItem->_parent){
if(dragItem->hasChildren()){
}else{
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);
children->move(srcIndex,destIndex>srcIndex? destIndex : destIndex +1); children->move(srcIndex,destIndex>srcIndex? destIndex : destIndex +1);
_rows.move(dragIndex,dropIndex>dragIndex? dropIndex : dropIndex+1); _rows.move(dragIndex,dropIndex>dragIndex? dropIndex : dropIndex+1);
}
}else{
if(dragItem->hasChildren()){
}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);
@ -183,10 +176,36 @@ void FluTreeModel::dragAnddrop(int dragIndex,int dropIndex){
int destIndex = destChildren->indexOf(dropItem); int destIndex = destChildren->indexOf(dropItem);
dragItem->_depth = dropItem->_depth; dragItem->_depth = dropItem->_depth;
dragItem->_parent = dropItem->_parent; dragItem->_parent = dropItem->_parent;
if(dragItem->hasChildren()){
QList<Node*> stack = dragItem->_children;
foreach (auto node, stack) {
node->_depth = dragItem->_depth+1;
}
std::reverse(stack.begin(), stack.end());
while (stack.count() > 0) {
auto item = stack.at(stack.count()-1);
stack.pop_back();
QList<Node*> children = item->_children;
if(!children.isEmpty()){
std::reverse(children.begin(), children.end());
foreach (auto c, children) {
c->_depth = item->_depth+1;
stack.append(c);
}
}
}
}
srcChildren->removeAt(srcIndex); srcChildren->removeAt(srcIndex);
destChildren->insert(destIndex+1,dragItem); destChildren->insert(destIndex+1,dragItem);
_rows.move(dragIndex,dropIndex>dragIndex? dropIndex : dropIndex+1); _rows.move(dragIndex,dropIndex>dragIndex? dropIndex : dropIndex+1);
} }
}
endMoveRows(); endMoveRows();
} }
void FluTreeModel::refreshNode(int row){
Q_EMIT dataChanged(index(row,0),index(row,0));
};
Node* FluTreeModel::getNode(int row){
return _rows.at(row);
}

View File

@ -20,6 +20,26 @@ public:
Q_INVOKABLE int depth(){return _depth;}; Q_INVOKABLE int depth(){return _depth;};
Q_INVOKABLE bool isExpanded(){return _isExpanded;}; Q_INVOKABLE bool isExpanded(){return _isExpanded;};
Q_INVOKABLE bool hasChildren(){ return !_children.isEmpty();}; Q_INVOKABLE bool hasChildren(){ return !_children.isEmpty();};
Q_INVOKABLE bool isHeaderNode(){
if(hasChildren() && _isExpanded){
return true;
}
return false;
}
Q_INVOKABLE bool isFooterNode(){
return this->_parent->_children.indexOf(this) == this->_parent->_children.count()-1;
}
Q_INVOKABLE bool hasNextNodeByIndex(int index){
Node* p = this;
for(int i=0;i<(_depth - index -1);i++){
p = p->_parent;
}
if(p->_parent->_children.indexOf(p) == p->_parent->_children.count()-1){
return false;
}
return true;
}
Q_INVOKABLE bool hideLineFooter(){ Q_INVOKABLE bool hideLineFooter(){
if(_parent){ if(_parent){
auto childIndex = _parent->_children.indexOf(this); auto childIndex = _parent->_children.indexOf(this);
@ -72,6 +92,8 @@ public:
Q_INVOKABLE void collapse(int row); Q_INVOKABLE void collapse(int row);
Q_INVOKABLE void expand(int row); Q_INVOKABLE void expand(int row);
Q_INVOKABLE void dragAnddrop(int dragIndex,int dropIndex); Q_INVOKABLE void dragAnddrop(int dragIndex,int dropIndex);
Q_INVOKABLE Node* getNode(int row);
Q_INVOKABLE void refreshNode(int row);
private: private:
QList<Node*> _rows; QList<Node*> _rows;
QList<Node*> _dataSource; QList<Node*> _dataSource;

View File

@ -13,11 +13,14 @@ Rectangle{
property string closeText : "关闭" property string closeText : "关闭"
property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000" property color textColor: FluTheme.dark ? "#FFFFFF" : "#000000"
property color minimizeNormalColor: Qt.rgba(0,0,0,0) property color minimizeNormalColor: Qt.rgba(0,0,0,0)
property color minimizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06) property color minimizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03)
property color minimizePressColor: FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)
property color maximizeNormalColor: Qt.rgba(0,0,0,0) property color maximizeNormalColor: Qt.rgba(0,0,0,0)
property color maximizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.1) : Qt.rgba(0,0,0,0.06) property color maximizeHoverColor: FluTheme.dark ? Qt.rgba(1,1,1,0.03) : Qt.rgba(0,0,0,0.03)
property color maximizePressColor: FluTheme.dark ? Qt.rgba(1,1,1,0.06) : Qt.rgba(0,0,0,0.06)
property color closeNormalColor: Qt.rgba(0,0,0,0) property color closeNormalColor: Qt.rgba(0,0,0,0)
property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1) property color closeHoverColor: Qt.rgba(251/255,115/255,115/255,1)
property color closePressColor: Qt.rgba(251/255,115/255,115/255,0.8)
property bool showDark: false property bool showDark: false
property bool showClose: true property bool showClose: true
property bool showMinimize: true property bool showMinimize: true
@ -114,7 +117,12 @@ Rectangle{
radius: 0 radius: 0
visible: !isMac && showMinimize visible: !isMac && showMinimize
iconColor: control.textColor iconColor: control.textColor
color: hovered ? minimizeHoverColor : minimizeNormalColor color: {
if(pressed){
return minimizePressColor
}
return hovered ? minimizeHoverColor : minimizeNormalColor
}
onClicked: minClickListener() onClicked: minClickListener()
} }
FluIconButton{ FluIconButton{
@ -122,7 +130,12 @@ Rectangle{
Layout.preferredWidth: 40 Layout.preferredWidth: 40
Layout.preferredHeight: 30 Layout.preferredHeight: 30
iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize iconSource : d.isRestore ? FluentIcons.ChromeRestore : FluentIcons.ChromeMaximize
color: hovered ? maximizeHoverColor : maximizeNormalColor color: {
if(pressed){
return maximizePressColor
}
return hovered ? maximizeHoverColor : maximizeNormalColor
}
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
visible: d.resizable && !isMac && showMaximize visible: d.resizable && !isMac && showMaximize
radius: 0 radius: 0
@ -142,7 +155,12 @@ Rectangle{
radius: 0 radius: 0
iconSize: 10 iconSize: 10
iconColor: hovered ? Qt.rgba(1,1,1,1) : control.textColor iconColor: hovered ? Qt.rgba(1,1,1,1) : control.textColor
color:hovered ? closeHoverColor : closeNormalColor color:{
if(pressed){
return closePressColor
}
return hovered ? closeHoverColor : closeNormalColor
}
onClicked: closeClickListener() onClicked: closeClickListener()
} }
} }

View File

@ -8,9 +8,8 @@ Rectangle {
id:control id:control
color:Qt.rgba(0,0,0,0) color:Qt.rgba(0,0,0,0)
height: spacing*2+separator.height height: spacing*2+separator.height
Rectangle{ FluRectangle{
id:separator id:separator
clip: true
color: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1) color: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
width:parent.width width:parent.width
anchors.centerIn: parent anchors.centerIn: parent

View File

@ -56,6 +56,8 @@ Item {
return w return w
} }
height: 30 height: 30
implicitWidth: width
implicitHeight: height
function toggle(){ function toggle(){
if(itemModel.isExpanded){ if(itemModel.isExpanded){
tree_model.collapse(rowIndex) tree_model.collapse(rowIndex)
@ -63,33 +65,6 @@ Item {
tree_model.expand(rowIndex) tree_model.expand(rowIndex)
} }
} }
Rectangle{
anchors.fill: parent
radius: 4
anchors.leftMargin: 6
anchors.rightMargin: 6
border.color: d.hitColor
border.width: d.dragIndex === rowIndex ? 1 : 0
color: {
if(FluTheme.dark){
if(isCurrent){
return Qt.rgba(1,1,1,0.03)
}
if(item_mouse.containsMouse){
return Qt.rgba(1,1,1,0.03)
}
return Qt.rgba(0,0,0,0)
}else{
if(isCurrent){
return Qt.rgba(0,0,0,0.06)
}
if(item_mouse.containsMouse){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
}
}
}
Rectangle{ Rectangle{
width: 3 width: 3
height: 18 height: 18
@ -104,6 +79,7 @@ Item {
} }
MouseArea{ MouseArea{
id:item_mouse id:item_mouse
property point clickPos: Qt.point(0,0)
anchors.fill: parent anchors.fill: parent
drag.target:control.draggable ? loader_container : undefined drag.target:control.draggable ? loader_container : undefined
hoverEnabled: true hoverEnabled: true
@ -116,7 +92,9 @@ Item {
loader_container.sourceComponent = com_item_container loader_container.sourceComponent = com_item_container
} }
} }
onPressed: { onPressed: (mouse)=>{
clickPos = Qt.point(mouse.x,mouse.y)
console.debug(clickPos)
loader_container.itemControl = itemControl loader_container.itemControl = itemControl
loader_container.itemModel = itemModel loader_container.itemModel = itemModel
var cellPosition = item_container.mapToItem(table_view, 0, 0) var cellPosition = item_container.mapToItem(table_view, 0, 0)
@ -124,6 +102,7 @@ Item {
loader_container.height = item_container.height loader_container.height = item_container.height
loader_container.x = table_view.contentX + cellPosition.x loader_container.x = table_view.contentX + cellPosition.x
loader_container.y = table_view.contentY + cellPosition.y loader_container.y = table_view.contentY + cellPosition.y
} }
onClicked: { onClicked: {
d.current = itemModel d.current = itemModel
@ -151,6 +130,7 @@ Item {
var index = Math.round(y/30) var index = Math.round(y/30)
if(index !== d.dragIndex){ if(index !== d.dragIndex){
d.dropIndex = index d.dropIndex = index
tree_model.refreshNode(rowIndex)
}else{ }else{
d.dropIndex = -1 d.dropIndex = -1
} }
@ -174,10 +154,11 @@ Item {
anchors{ anchors{
left: parent.left left: parent.left
leftMargin: { leftMargin: {
var count = itemModel.depth+1
if(itemModel.hasChildren()){ if(itemModel.hasChildren()){
return 30*(itemModel.depth+1) - 8 return 30*count - 8
} }
return 30*(itemModel.depth+1) + 18 return 30*count + 18
} }
right: parent.right right: parent.right
rightMargin: 10 rightMargin: 10
@ -202,10 +183,10 @@ Item {
} }
} }
} }
Rectangle{ FluRectangle{
width: 1 width: 1
color: control.lineColor color: control.lineColor
visible: itemModel.depth !== 0 && control.showLine && !itemModel.hasChildren() visible: control.showLine && isItemLoader && itemModel.depth !== 0 && !itemModel.hasChildren()
height: itemModel.hideLineFooter() ? parent.height/2 : parent.height height: itemModel.hideLineFooter() ? parent.height/2 : parent.height
anchors{ anchors{
top: parent.top top: parent.top
@ -213,10 +194,10 @@ Item {
rightMargin: -9 rightMargin: -9
} }
} }
Rectangle{ FluRectangle{
height: 1 height: 1
color: control.lineColor color: control.lineColor
visible: itemModel.depth !== 0 && control.showLine && !itemModel.hasChildren() visible: control.showLine && isItemLoader && itemModel.depth !== 0 && !itemModel.hasChildren()
width: 18 width: 18
anchors{ anchors{
right: layout_row.left right: layout_row.left
@ -226,11 +207,11 @@ Item {
} }
Repeater{ Repeater{
model: Math.max(itemModel.depth-1,0) model: Math.max(itemModel.depth-1,0)
delegate: Rectangle{ delegate: FluRectangle{
required property int index required property int index
width: 1 width: 1
color: control.lineColor color: control.lineColor
visible: itemModel.depth !== 0 && control.showLine visible: control.showLine && isItemLoader && itemModel.depth !== 0 && itemModel.hasNextNodeByIndex(index)
anchors{ anchors{
top:parent.top top:parent.top
bottom: parent.bottom bottom: parent.bottom
@ -239,6 +220,33 @@ Item {
} }
} }
} }
Rectangle{
anchors.fill: parent
radius: 4
anchors.leftMargin: 6
anchors.rightMargin: 6
border.color: d.hitColor
border.width: d.dragIndex === rowIndex ? 1 : 0
color: {
if(FluTheme.dark){
if(isCurrent){
return Qt.rgba(1,1,1,0.03)
}
if(item_mouse.containsMouse){
return Qt.rgba(1,1,1,0.03)
}
return Qt.rgba(0,0,0,0)
}else{
if(isCurrent){
return Qt.rgba(0,0,0,0.06)
}
if(item_mouse.containsMouse){
return Qt.rgba(0,0,0,0.03)
}
return Qt.rgba(0,0,0,0)
}
}
}
RowLayout{ RowLayout{
id:layout_row id:layout_row
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -310,14 +318,9 @@ Item {
property var itemControl: item_control property var itemControl: item_control
property var itemModel: modelData property var itemModel: modelData
property int rowIndex: row property int rowIndex: row
property bool isItemLoader: true
id:item_loader_container id:item_loader_container
width: item.width sourceComponent: com_item_container
height: item.height
sourceComponent: {
if(modelData)
return com_item_container
return undefined
}
} }
} }
} }
@ -326,6 +329,7 @@ Item {
id:loader_container id:loader_container
property var itemControl property var itemControl
property var itemModel property var itemModel
property bool isItemLoader: false
} }
} }
function count(){ function count(){

View File

@ -8,9 +8,8 @@ Rectangle {
id:control id:control
color:Qt.rgba(0,0,0,0) color:Qt.rgba(0,0,0,0)
height: spacing*2+separator.height height: spacing*2+separator.height
Rectangle{ FluRectangle{
id:separator id:separator
clip: true
color: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1) color: FluTheme.dark ? Qt.rgba(80/255,80/255,80/255,1) : Qt.rgba(210/255,210/255,210/255,1)
width:parent.width width:parent.width
anchors.centerIn: parent anchors.centerIn: parent

View File

@ -56,6 +56,8 @@ Item {
return w return w
} }
height: 30 height: 30
implicitWidth: width
implicitHeight: height
function toggle(){ function toggle(){
if(itemModel.isExpanded){ if(itemModel.isExpanded){
tree_model.collapse(rowIndex) tree_model.collapse(rowIndex)
@ -203,7 +205,7 @@ Item {
} }
} }
} }
Rectangle{ FluRectangle{
width: 1 width: 1
color: control.lineColor color: control.lineColor
visible: itemModel.depth !== 0 && control.showLine && !itemModel.hasChildren() visible: itemModel.depth !== 0 && control.showLine && !itemModel.hasChildren()
@ -214,7 +216,7 @@ Item {
rightMargin: -9 rightMargin: -9
} }
} }
Rectangle{ FluRectangle{
height: 1 height: 1
color: control.lineColor color: control.lineColor
visible: itemModel.depth !== 0 && control.showLine && !itemModel.hasChildren() visible: itemModel.depth !== 0 && control.showLine && !itemModel.hasChildren()
@ -227,7 +229,7 @@ Item {
} }
Repeater{ Repeater{
model: Math.max(itemModel.depth-1,0) model: Math.max(itemModel.depth-1,0)
delegate: Rectangle{ delegate: FluRectangle{
required property int index required property int index
width: 1 width: 1
color: control.lineColor color: control.lineColor
@ -312,23 +314,7 @@ Item {
property var itemModel: modelData property var itemModel: modelData
property int rowIndex: row property int rowIndex: row
id:item_loader_container id:item_loader_container
width:{ sourceComponent: com_item_container
if(item){
return item.width
}
return 1
}
height: {
if(item){
return item.height
}
return 1
}
sourceComponent: {
if(modelData)
return com_item_container
return undefined
}
} }
} }
} }