@@ -1005,7 +1005,11 @@ Item {
10051005 padding: 2
10061006 anchors .bottom : parent .bottom
10071007 RowLayout {
1008+ id: navigation
10081009 spacing: 4
1010+
1011+ // Default index for search
1012+ property int currentIndex: - 1
10091013 // Fit
10101014 MaterialToolButton {
10111015 text: MaterialIcons .fullscreen
@@ -1044,7 +1048,7 @@ Item {
10441048 ComboBox {
10451049 flat: true
10461050 model: [' Minimum' , ' Maximum' ]
1047- implicitWidth: 80
1051+ implicitWidth: 85
10481052 currentIndex: uigraph ? uigraph .layout .depthMode : - 1
10491053 onActivated: {
10501054 uigraph .layout .depthMode = currentIndex
@@ -1071,50 +1075,44 @@ Item {
10711075 uigraph .setSelectedNodesColor (color)
10721076 }
10731077 }
1074- }
1075- }
10761078
1077- // Graph Nodes Search
1078- FloatingPane {
1079- id: navigation
1080- padding: 2
1081- anchors .top : parent .top
1082-
1083- property int currentIndex: - 1
1084-
1085- RowLayout {
1086- spacing: 0
1079+ // Separator
1080+ Rectangle {
1081+ Layout .fillHeight : true
1082+ Layout .margins : 2
1083+ implicitWidth: 1
1084+ color: activePalette .window
1085+ }
10871086
1087+ // Search nodes in the graph
10881088 SearchBar {
10891089 id: graphSearchBar
1090- Layout .minimumWidth : 150
1091- width: 150
1090+
1091+ toggle: true // enable toggling the actual text field by the search button
1092+ Layout .minimumWidth : graphSearchBar .width
1093+ maxWidth: 150
1094+
10921095 textField .background .opacity : 0.5
10931096 textField .onTextChanged : navigation .currentIndex = - 1
1097+
1098+ onAccepted: {
1099+ navigation .navigateForward ()
1100+ }
10941101 }
10951102
10961103 MaterialToolButton {
10971104 text: MaterialIcons .arrow_left
10981105 padding: 0
1099- enabled: graphSearchBar .text !== " "
1100- onClicked: {
1101- navigation .currentIndex --
1102- if (navigation .currentIndex === - 1 )
1103- navigation .currentIndex = filteredNodes .count - 1
1104- navigation .nextItem ()
1105- }
1106+ visible: graphSearchBar .text !== " "
1107+ onClicked: navigation .navigateBackward ()
11061108 }
11071109
11081110 MaterialToolButton {
1111+ id: nextArrow
11091112 text: MaterialIcons .arrow_right
11101113 padding: 0
1111- enabled: graphSearchBar .text !== " "
1112- onClicked: {
1113- navigation .currentIndex ++
1114- if (navigation .currentIndex === filteredNodes .count )
1115- navigation .currentIndex = 0
1116- navigation .nextItem ()
1117- }
1114+ visible: graphSearchBar .text !== " "
1115+ onClicked: navigation .navigateForward ()
11181116 }
11191117
11201118 Label {
@@ -1124,32 +1122,58 @@ Item {
11241122 visible: graphSearchBar .text !== " "
11251123 }
11261124
1127- }
1128-
1129- Repeater {
1130- id : filteredNodes
1131- model : SortFilterDelegateModel {
1132- model : root . graph ? root . graph . nodes : undefined
1133- sortRole : " label "
1134- filters : [{role : " label " , value : graphSearchBar . text }]
1135- delegate : Item {
1136- property var index_ : index
1137- }
1138- function modelData ( item , roleName_ ) {
1139- return item . model . object [roleName_]
1125+ Repeater {
1126+ id : filteredNodes
1127+ model : SortFilterDelegateModel {
1128+ model : root . graph ? root . graph . nodes : undefined
1129+ sortRole : " label "
1130+ filters : [{role : " label " , value : graphSearchBar . text }]
1131+ delegate : Item {
1132+ visible : false // Hide the items to not affect the layout as the nodes model gets changes
1133+ property var index_ : index
1134+ }
1135+ function modelData ( item , roleName_ ) {
1136+ return item . model . object [roleName_]
1137+ }
11401138 }
11411139 }
1142- }
11431140
1144- function nextItem () {
1145- // Compute bounding box
1146- var node = nodeRepeater .itemAt (filteredNodes .itemAt (navigation .currentIndex ).index_ )
1147- var bbox = Qt .rect (node .x , node .y , node .width , node .height )
1148- // Rescale to fit the bounding box in the view, zoom is limited to prevent huge text
1149- draggable .scale = Math .min (Math .min (root .width / bbox .width , root .height / bbox .height ),maxZoom)
1150- // Recenter
1151- draggable .x = bbox .x * draggable .scale * - 1 + (root .width - bbox .width * draggable .scale ) * 0.5
1152- draggable .y = bbox .y * draggable .scale * - 1 + (root .height - bbox .height * draggable .scale ) * 0.5
1141+ function navigateForward () {
1142+ /**
1143+ * Moves the navigation index forwards and focuses on the next node as per index.
1144+ */
1145+ if (! filteredNodes .count )
1146+ return
1147+
1148+ navigation .currentIndex ++
1149+ if (navigation .currentIndex === filteredNodes .count )
1150+ navigation .currentIndex = 0
1151+ navigation .nextItem ()
1152+ }
1153+
1154+ function navigateBackward () {
1155+ /**
1156+ * Moves the navigation index backwards and focuses on the previous node as per index.
1157+ */
1158+ if (! filteredNodes .count )
1159+ return
1160+
1161+ navigation .currentIndex --
1162+ if (navigation .currentIndex === - 1 )
1163+ navigation .currentIndex = filteredNodes .count - 1
1164+ navigation .nextItem ()
1165+ }
1166+
1167+ function nextItem () {
1168+ // Compute bounding box
1169+ var node = nodeRepeater .itemAt (filteredNodes .itemAt (navigation .currentIndex ).index_ )
1170+ var bbox = Qt .rect (node .x , node .y , node .width , node .height )
1171+ // Rescale to fit the bounding box in the view, zoom is limited to prevent huge text
1172+ draggable .scale = Math .min (Math .min (root .width / bbox .width , root .height / bbox .height ),maxZoom)
1173+ // Recenter
1174+ draggable .x = bbox .x * draggable .scale * - 1 + (root .width - bbox .width * draggable .scale ) * 0.5
1175+ draggable .y = bbox .y * draggable .scale * - 1 + (root .height - bbox .height * draggable .scale ) * 0.5
1176+ }
11531177 }
11541178 }
11551179
0 commit comments