@@ -115,6 +115,54 @@ Item {
115
115
return str
116
116
}
117
117
118
+ function updateChildPin (attribute , parentPins , pin ) {
119
+ /*
120
+ * Update the pin of a child attribute: if the attribute is enabled and its parent is a GroupAttribute,
121
+ * the visibility is determined based on the parent pin's "expanded" state, using the "parentPins" map to
122
+ * access the status.
123
+ * If the current pin is also a GroupAttribute and is expanded while its newly "visible" state is false,
124
+ * it is reset.
125
+ */
126
+ if (Boolean (attribute .enabled )) {
127
+ // If the parent's a GroupAttribute, use status of the parent's pin to determine visibility
128
+ if (attribute .root && attribute .root .type === " GroupAttribute" ) {
129
+ var visible = Boolean (parentPins .get (attribute .root .name ))
130
+ if (! visible && parentPins .has (attribute .name ) && parentPins .get (attribute .name ) === true ) {
131
+ parentPins .set (attribute .name , false )
132
+ pin .expanded = false
133
+ }
134
+ return visible
135
+ }
136
+ return true
137
+ }
138
+ return false
139
+ }
140
+
141
+ function generateAttributesModel (isOutput , parentPins ) {
142
+ if (! node)
143
+ return undefined
144
+
145
+ const attributes = []
146
+ for (let i = 0 ; i < node .attributes .count ; ++ i) {
147
+ let attr = node .attributes .at (i)
148
+ if (attr .isOutput == isOutput) {
149
+ attributes .push (attr)
150
+ if (attr .type === " GroupAttribute" ) {
151
+ parentPins .set (attr .name , false )
152
+ }
153
+
154
+ for (let j = 0 ; j < attr .flattenedChildren .count ; ++ j) {
155
+ attributes .push (attr .flattenedChildren .at (j))
156
+ if (attr .flattenedChildren .at (j).type === " GroupAttribute" ) {
157
+ parentPins .set (attr .flattenedChildren .at (j).name , false )
158
+ }
159
+ }
160
+ }
161
+ }
162
+
163
+ return attributes
164
+ }
165
+
118
166
// Main Layout
119
167
MouseArea {
120
168
id: mouseArea
@@ -394,25 +442,52 @@ Item {
394
442
width: parent .width
395
443
spacing: 3
396
444
445
+ property var parentPins: new Map ()
446
+ signal parentPinsUpdated ()
447
+
397
448
Repeater {
398
- model: node ? node . attributes : undefined
449
+ model: generateAttributesModel ( true , outputs . parentPins ) // isOutput = true
399
450
400
451
delegate: Loader {
401
452
id: outputLoader
402
- active: Boolean (object .isOutput && object .desc .visible )
403
- visible: Boolean (object .enabled || object .hasOutputConnections )
453
+ active: Boolean (modelData .isOutput && modelData .desc .visible )
454
+
455
+ visible: {
456
+ if (Boolean (modelData .enabled || modelData .hasOutputConnections )) {
457
+ if (modelData .root && modelData .root .type === " GroupAttribute" ) {
458
+ return Boolean (outputs .parentPins .get (modelData .root .name ))
459
+ }
460
+ return true
461
+ }
462
+ return false
463
+ }
404
464
anchors .right : parent .right
405
465
width: outputs .width
406
466
467
+ Connections {
468
+ target: outputs
469
+
470
+ function onParentPinsUpdated () {
471
+ visible = updateChildPin (modelData, outputs .parentPins , outputLoader .item )
472
+ }
473
+ }
474
+
407
475
sourceComponent: AttributePin {
408
476
id: outPin
409
477
nodeItem: root
410
- attribute: object
478
+ attribute: modelData
411
479
412
480
property real globalX: root .x + nodeAttributes .x + outputs .x + outputLoader .x + outPin .x
413
481
property real globalY: root .y + nodeAttributes .y + outputs .y + outputLoader .y + outPin .y
414
482
415
483
onPressed: root .pressed (mouse)
484
+ onClicked: {
485
+ expanded = ! expanded
486
+ if (outputs .parentPins .has (modelData .name )) {
487
+ outputs .parentPins .set (modelData .name , expanded)
488
+ outputs .parentPinsUpdated ()
489
+ }
490
+ }
416
491
onEdgeAboutToBeRemoved: root .edgeAboutToBeRemoved (input)
417
492
418
493
Component .onCompleted : attributePinCreated (attribute, outPin)
@@ -429,27 +504,55 @@ Item {
429
504
width: parent .width
430
505
spacing: 3
431
506
507
+ property var parentPins: new Map ()
508
+ signal parentPinsUpdated ()
509
+
432
510
Repeater {
433
- model: node ? node . attributes : undefined
511
+ model: generateAttributesModel ( false , inputs . parentPins ) // isOutput = false
434
512
435
513
delegate: Loader {
436
514
id: inputLoader
437
- active: ! object .isOutput && object .exposed && object .desc .visible
438
- visible: Boolean (object .enabled )
515
+ active: ! modelData .isOutput && modelData .exposed && modelData .desc .visible
516
+ visible: {
517
+ if (Boolean (modelData .enabled )) {
518
+ if (modelData .root && modelData .root .type === " GroupAttribute" ) {
519
+ return Boolean (inputs .parentPins .get (modelData .root .name ))
520
+ }
521
+ return true
522
+ }
523
+ return false
524
+ }
439
525
width: inputs .width
440
526
527
+ Connections {
528
+ target: inputs
529
+
530
+ function onParentPinsUpdated () {
531
+ visible = updateChildPin (modelData, inputs .parentPins , inputLoader .item )
532
+ }
533
+ }
534
+
441
535
sourceComponent: AttributePin {
442
536
id: inPin
443
537
nodeItem: root
444
- attribute: object
538
+ attribute: modelData
445
539
446
540
property real globalX: root .x + nodeAttributes .x + inputs .x + inputLoader .x + inPin .x
447
541
property real globalY: root .y + nodeAttributes .y + inputs .y + inputLoader .y + inPin .y
448
542
449
- readOnly: root .readOnly || object .isReadOnly
543
+ readOnly: Boolean ( root .readOnly || modelData .isReadOnly )
450
544
Component .onCompleted : attributePinCreated (attribute, inPin)
451
545
Component .onDestruction : attributePinDeleted (attribute, inPin)
546
+
452
547
onPressed: root .pressed (mouse)
548
+ onClicked: {
549
+ expanded = ! expanded
550
+ if (inputs .parentPins .has (modelData .name )) {
551
+ inputs .parentPins .set (modelData .name , expanded)
552
+ inputs .parentPinsUpdated ()
553
+ }
554
+ }
555
+
453
556
onEdgeAboutToBeRemoved: root .edgeAboutToBeRemoved (input)
454
557
onChildPinCreated: attributePinCreated (childAttribute, inPin)
455
558
onChildPinDeleted: attributePinDeleted (childAttribute, inPin)
@@ -489,30 +592,62 @@ Item {
489
592
id: inputParams
490
593
width: parent .width
491
594
spacing: 3
595
+
596
+ property var parentPins: new Map ()
597
+ signal parentPinsUpdated ()
598
+
492
599
Repeater {
493
- id : inputParamsRepeater
494
- model : node ? node . attributes : undefined
600
+ model : generateAttributesModel ( false , inputParams . parentPins ) // isOutput = false
601
+
495
602
delegate: Loader {
496
603
id: paramLoader
497
- active: ! object .isOutput && ! object .exposed && object .desc .visible
498
- visible: Boolean (object .enabled || object .isLink || object .hasOutputConnections )
499
- property bool isFullyActive: Boolean (m .displayParams || object .isLink || object .hasOutputConnections )
604
+ active: ! modelData .isOutput && ! modelData .exposed && modelData .desc .visible
605
+ visible: {
606
+ if (Boolean (modelData .enabled || modelData .isLink || modelData .hasOutputConnections )) {
607
+ if (modelData .root && modelData .root .type === " GroupAttribute" ) {
608
+ return Boolean (inputParams .parentPins .get (modelData .root .name ))
609
+ active: ! modelData .isOutput && modelData .desc .exposed && modelData .desc .visible }
610
+ return true
611
+ }
612
+ return false
613
+ }
614
+ property bool isFullyActive: Boolean (m .displayParams || modelData .isLink || modelData .hasOutputConnections )
500
615
width: parent .width
501
616
617
+ Connections {
618
+ target: inputParams
619
+
620
+ function onParentPinsUpdated () {
621
+ visible = updateChildPin (modelData, inputParams .parentPins , paramLoader .item )
622
+ }
623
+ }
624
+
502
625
sourceComponent: AttributePin {
503
626
id: inParamsPin
504
627
nodeItem: root
628
+ attribute: modelData
629
+
505
630
property real globalX: root .x + nodeAttributes .x + inputParamsRect .x + paramLoader .x + inParamsPin .x
506
631
property real globalY: root .y + nodeAttributes .y + inputParamsRect .y + paramLoader .y + inParamsPin .y
507
632
508
633
height: isFullyActive ? childrenRect .height : 0
509
634
Behavior on height { PropertyAnimation {easing .type : Easing .Linear } }
510
635
visible: (height == childrenRect .height )
511
- attribute : object
512
- readOnly: Boolean (root .readOnly || object .isReadOnly )
636
+
637
+ readOnly: Boolean (root .readOnly || modelData .isReadOnly )
513
638
Component .onCompleted : attributePinCreated (attribute, inParamsPin)
514
639
Component .onDestruction : attributePinDeleted (attribute, inParamsPin)
640
+
515
641
onPressed: root .pressed (mouse)
642
+
643
+ onClicked: {
644
+ expanded = ! expanded
645
+ if (inputParams .parentPins .has (modelData .name )) {
646
+ inputParams .parentPins .set (modelData .name , expanded)
647
+ inputParams .parentPinsUpdated ()
648
+ }
649
+ }
650
+
516
651
onEdgeAboutToBeRemoved: root .edgeAboutToBeRemoved (input)
517
652
onChildPinCreated: attributePinCreated (childAttribute, inParamsPin)
518
653
onChildPinDeleted: attributePinDeleted (childAttribute, inParamsPin)
0 commit comments