This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch worktree-more-tui-4
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 3cf3b500f9bdcdb7172b1b29a20d847e8331f90c
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed May 20 09:42:39 2026 +0200

    camel-jbang - TUI diagram all/single route toggle
    
    Add 'a' key on route tab to toggle between showing all routes or just the
    selected route in the diagram view. Route titles are rendered in bold in
    text diagram mode, and routes are separated by double empty lines.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../dsl/jbang/core/commands/tui/CamelMonitor.java  | 109 ++++++++++++++-------
 1 file changed, 71 insertions(+), 38 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
index 9090fbc6be38..9842413db7cd 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
@@ -26,6 +26,7 @@ import java.time.Instant;
 import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -312,8 +313,10 @@ public class CamelMonitor extends CamelCommand {
     private int chartMode = CHART_ALL;
     private boolean showDiagram;
     private boolean diagramTextMode;
+    private boolean diagramAllRoutes;
     private boolean diagramMetrics = true;
     private List<RouteDiagramAsciiRenderer.CounterPos> diagramCounterPositions 
= Collections.emptyList();
+    private Set<Integer> diagramRouteTitleRows = Collections.emptySet();
     private List<String> diagramLines = Collections.emptyList();
     private int diagramScroll;
     private int diagramScrollX;
@@ -701,6 +704,10 @@ public class CamelMonitor extends CamelCommand {
                 routeSortReversed = !routeSortReversed;
                 return true;
             }
+            if (tab == TAB_ROUTES && !showSource && !showDiagram && 
ke.isCharIgnoreCase('a')) {
+                diagramAllRoutes = !diagramAllRoutes;
+                return true;
+            }
             if (tab == TAB_ROUTES && ke.isChar('d')) {
                 if (showDiagram) {
                     showDiagram = false;
@@ -1683,12 +1690,16 @@ public class CamelMonitor extends CamelCommand {
 
         // Fullscreen diagram mode
         if (showDiagram && (diagramTextMode ? !diagramLines.isEmpty() : 
diagramFullImageData != null)) {
-            // Split: route info header (4 rows) + diagram (fill)
-            List<Rect> fullChunks = Layout.vertical()
-                    .constraints(Constraint.length(4), Constraint.fill())
-                    .split(area);
-            renderRouteHeader(frame, fullChunks.get(0), info);
-            renderDiagram(frame, fullChunks.get(1));
+            if (diagramAllRoutes) {
+                renderDiagram(frame, area);
+            } else {
+                // Split: route info header (4 rows) + diagram (fill)
+                List<Rect> fullChunks = Layout.vertical()
+                        .constraints(Constraint.length(4), Constraint.fill())
+                        .split(area);
+                renderRouteHeader(frame, fullChunks.get(0), info);
+                renderDiagram(frame, fullChunks.get(1));
+            }
             return;
         }
 
@@ -2356,6 +2367,10 @@ public class CamelMonitor extends CamelCommand {
     }
 
     private Line styleDiagramLine(String text, int row, int scrollX) {
+        if (diagramRouteTitleRows.contains(row)) {
+            return Line.from(Span.styled(text, 
Style.EMPTY.fg(Color.WHITE).bold()));
+        }
+
         // Build counter color ranges for this row
         List<int[]> counterRanges = new ArrayList<>();
         for (RouteDiagramAsciiRenderer.CounterPos cp : 
diagramCounterPositions) {
@@ -2486,11 +2501,11 @@ public class CamelMonitor extends CamelCommand {
         String pid = selectedPid;
         boolean textMode = diagramTextMode;
         boolean showMetrics = diagramMetrics;
-        String routeId = selectedRoute.routeId;
+        String routeId = diagramAllRoutes ? null : selectedRoute.routeId;
 
         boolean initialLoad = !showDiagram;
         if (initialLoad) {
-            diagramRouteId = routeId;
+            diagramRouteId = routeId != null ? routeId : "all";
             diagramLines = List.of("(Loading diagram...)");
             diagramImageData = null;
             diagramFullImageData = null;
@@ -2759,39 +2774,49 @@ public class CamelMonitor extends CamelCommand {
             RouteDiagramLayoutEngine engine = new RouteDiagramLayoutEngine(
                     RouteDiagramLayoutEngine.DEFAULT_BOX_WIDTH, 
RouteDiagramLayoutEngine.DEFAULT_FONT_SIZE,
                     RouteDiagramLayoutEngine.NodeLabelMode.CODE);
-            List<RouteDiagramLayoutEngine.LayoutRoute> layoutRoutes = new 
ArrayList<>();
-            int currentY = RouteDiagramLayoutEngine.PADDING;
-            for (RouteDiagramLayoutEngine.RouteInfo r : diagramRoutes) {
-                RouteDiagramLayoutEngine.LayoutRoute lr = 
engine.layoutRoute(r, currentY);
-                layoutRoutes.add(lr);
-                currentY = lr.maxY + RouteDiagramLayoutEngine.V_GAP;
-            }
-            RouteDiagramAsciiRenderer asciiRenderer = new 
RouteDiagramAsciiRenderer(
-                    RouteDiagramLayoutEngine.DEFAULT_BOX_WIDTH * 
RouteDiagramLayoutEngine.SCALE, true, metrics);
-            String ascii = asciiRenderer.renderDiagram(layoutRoutes, currentY);
-            List<RouteDiagramAsciiRenderer.CounterPos> origPositions = 
asciiRenderer.getCounterPositions();
 
-            // Build result lines, remapping counter positions to account for 
removed empty lines
-            String[] rawLines = ascii.split("\n", -1);
             List<String> result = new ArrayList<>();
-            int[] rowMapping = new int[rawLines.length];
-            int newRow = 0;
-            for (int i = 0; i < rawLines.length; i++) {
-                if (!rawLines[i].isEmpty()) {
-                    rowMapping[i] = newRow++;
-                    result.add(rawLines[i]);
-                } else {
-                    rowMapping[i] = -1;
-                }
-            }
             List<RouteDiagramAsciiRenderer.CounterPos> positions = new 
ArrayList<>();
-            for (RouteDiagramAsciiRenderer.CounterPos cp : origPositions) {
-                if (cp.row() >= 0 && cp.row() < rowMapping.length && 
rowMapping[cp.row()] >= 0) {
-                    positions.add(new RouteDiagramAsciiRenderer.CounterPos(
-                            rowMapping[cp.row()], cp.col(), cp.length(), 
cp.type()));
+            Set<Integer> titleRows = new HashSet<>();
+
+            for (RouteDiagramLayoutEngine.RouteInfo r : diagramRoutes) {
+                // Add separator between routes
+                if (!result.isEmpty()) {
+                    result.add("");
+                    result.add("");
+                }
+
+                int titleRow = result.size();
+
+                RouteDiagramLayoutEngine.LayoutRoute lr = 
engine.layoutRoute(r, RouteDiagramLayoutEngine.PADDING);
+                RouteDiagramAsciiRenderer asciiRenderer = new 
RouteDiagramAsciiRenderer(
+                        RouteDiagramLayoutEngine.DEFAULT_BOX_WIDTH * 
RouteDiagramLayoutEngine.SCALE, true, metrics);
+                String ascii = asciiRenderer.renderDiagram(List.of(lr), 
lr.maxY + RouteDiagramLayoutEngine.V_GAP);
+                List<RouteDiagramAsciiRenderer.CounterPos> origPositions = 
asciiRenderer.getCounterPositions();
+
+                // Strip empty lines and remap counter positions
+                String[] rawLines = ascii.split("\n", -1);
+                int[] rowMapping = new int[rawLines.length];
+                int baseRow = result.size();
+                int newRow = baseRow;
+                for (int i = 0; i < rawLines.length; i++) {
+                    if (!rawLines[i].isEmpty()) {
+                        rowMapping[i] = newRow++;
+                        result.add(rawLines[i]);
+                    } else {
+                        rowMapping[i] = -1;
+                    }
                 }
+                for (RouteDiagramAsciiRenderer.CounterPos cp : origPositions) {
+                    if (cp.row() >= 0 && cp.row() < rowMapping.length && 
rowMapping[cp.row()] >= 0) {
+                        positions.add(new RouteDiagramAsciiRenderer.CounterPos(
+                                rowMapping[cp.row()], cp.col(), cp.length(), 
cp.type()));
+                    }
+                }
+                titleRows.add(titleRow);
             }
-            applyDiagramResult(routeId, result, null, null, null, positions);
+
+            applyDiagramResult(routeId, result, null, null, null, positions, 
titleRows);
         } else {
             TerminalImageCapabilities caps = 
TerminalImageCapabilities.detect();
             if (caps.supportsNativeImages()) {
@@ -2822,20 +2847,27 @@ public class CamelMonitor extends CamelCommand {
 
     private void applyDiagramResult(
             String routeId, List<String> lines, ImageData imageData, ImageData 
fullImageData, ImageProtocol protocol) {
-        applyDiagramResult(routeId, lines, imageData, fullImageData, protocol, 
Collections.emptyList());
+        applyDiagramResult(routeId, lines, imageData, fullImageData, protocol, 
Collections.emptyList(), Collections.emptySet());
     }
 
     private void applyDiagramResult(
             String routeId, List<String> lines, ImageData imageData, ImageData 
fullImageData, ImageProtocol protocol,
             List<RouteDiagramAsciiRenderer.CounterPos> positions) {
+        applyDiagramResult(routeId, lines, imageData, fullImageData, protocol, 
positions, Collections.emptySet());
+    }
+
+    private void applyDiagramResult(
+            String routeId, List<String> lines, ImageData imageData, ImageData 
fullImageData, ImageProtocol protocol,
+            List<RouteDiagramAsciiRenderer.CounterPos> positions, Set<Integer> 
titleRows) {
         if (runner == null) {
             return;
         }
         runner.runOnRenderThread(() -> {
             boolean wasShowing = showDiagram;
-            diagramRouteId = routeId;
+            diagramRouteId = routeId != null ? routeId : "all";
             diagramLines = lines;
             diagramCounterPositions = positions;
+            diagramRouteTitleRows = titleRows;
             diagramImageData = imageData;
             diagramFullImageData = fullImageData;
             diagramProtocol = protocol;
@@ -4851,6 +4883,7 @@ public class CamelMonitor extends CamelCommand {
             hint(spans, "c", "source");
             hint(spans, "d", "diagram");
             hint(spans, "D", "text diagram");
+            hint(spans, "a", diagramAllRoutes ? "all [on]" : "all [off]");
             String routeState = selectedRouteState();
             boolean supSus = selectedRouteSupportsSuspension();
             if ("Started".equals(routeState)) {

Reply via email to