diff --git a/app/gui2/src/components/ExtendedMenu.vue b/app/gui2/src/components/ExtendedMenu.vue
new file mode 100644
index 00000000000..eed5812f4a9
--- /dev/null
+++ b/app/gui2/src/components/ExtendedMenu.vue
@@ -0,0 +1,190 @@
+
+
+
+
+
+
+
diff --git a/app/gui2/src/components/GraphEditor.vue b/app/gui2/src/components/GraphEditor.vue
index 616973c37c6..6c39a92e6b1 100644
--- a/app/gui2/src/components/GraphEditor.vue
+++ b/app/gui2/src/components/GraphEditor.vue
@@ -170,6 +170,29 @@ useEvent(window, 'pointerdown', interactionBindingsHandler, { capture: true })
onMounted(() => viewportNode.value?.focus())
+function zoomToSelected() {
+ if (!viewportNode.value) return
+ let left = Infinity
+ let top = Infinity
+ let right = -Infinity
+ let bottom = -Infinity
+ const nodesToCenter =
+ nodeSelection.selected.size === 0 ? graphStore.db.nodeIdToNode.keys() : nodeSelection.selected
+ for (const id of nodesToCenter) {
+ const rect = graphStore.vizRects.get(id) ?? graphStore.nodeRects.get(id)
+ if (!rect) continue
+ left = Math.min(left, rect.left)
+ right = Math.max(right, rect.right)
+ top = Math.min(top, rect.top)
+ bottom = Math.max(bottom, rect.bottom)
+ }
+ graphNavigator.panAndZoomTo(
+ Rect.FromBounds(left, top, right, bottom),
+ 0.1,
+ Math.max(1, graphNavigator.scale),
+ )
+}
+
const graphBindingsHandler = graphBindings.handler({
undo() {
projectStore.module?.undoManager.undo()
@@ -202,26 +225,7 @@ const graphBindingsHandler = graphBindings.handler({
})
},
zoomToSelected() {
- if (!viewportNode.value) return
- let left = Infinity
- let top = Infinity
- let right = -Infinity
- let bottom = -Infinity
- const nodesToCenter =
- nodeSelection.selected.size === 0 ? graphStore.db.nodeIdToNode.keys() : nodeSelection.selected
- for (const id of nodesToCenter) {
- const rect = graphStore.vizRects.get(id) ?? graphStore.nodeRects.get(id)
- if (!rect) continue
- left = Math.min(left, rect.left)
- right = Math.max(right, rect.right)
- top = Math.min(top, rect.top)
- bottom = Math.max(bottom, rect.bottom)
- }
- graphNavigator.panAndZoomTo(
- Rect.FromBounds(left, top, right, bottom),
- 0.1,
- Math.max(1, graphNavigator.scale),
- )
+ zoomToSelected()
},
selectAll() {
if (keyboardBusy()) return
@@ -660,10 +664,14 @@ function handleEdgeDrop(source: AstId, position: Vec2) {
:breadcrumbs="stackNavigator.breadcrumbLabels.value"
:allowNavigationLeft="stackNavigator.allowNavigationLeft.value"
:allowNavigationRight="stackNavigator.allowNavigationRight.value"
+ :zoomLevel="100.0 * graphNavigator.scale"
@breadcrumbClick="stackNavigator.handleBreadcrumbClick"
@back="stackNavigator.exitNode"
@forward="stackNavigator.enterNextNodeFromHistory"
@execute="onPlayButtonPress()"
+ @fitToAllClicked="zoomToSelected"
+ @zoomIn="graphNavigator.scale *= 1.1"
+ @zoomOut="graphNavigator.scale *= 0.9"
/>
diff --git a/app/gui2/src/components/TopBar.vue b/app/gui2/src/components/TopBar.vue
index 853028964a2..64583e29872 100644
--- a/app/gui2/src/components/TopBar.vue
+++ b/app/gui2/src/components/TopBar.vue
@@ -1,4 +1,5 @@