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

davsclaus pushed a commit to branch camel-jbang-diagram-zoom
in repository https://gitbox.apache.org/repos/asf/camel.git

commit a26be4ac31eef095e710d17480a41c5dee9b8b46
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Oct 25 15:23:06 2026 +0100

    chore: camel-jbang - Diagram tab: the three levels lead the view bar
    
    Architecture › Topology › Route were dim words at the end of the title
    of the diagram, cut off when the title was long, and easy to miss. They
    now lead the view bar, after the v key that moves through them, the one
    shown highlighted and Route greyed out until a route is selected, as the
    help page and the manual describe; a click goes to a level. The title of
    a route separates its step count with a dot.
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../dsl/jbang/core/commands/tui/DiagramTab.java    | 55 +++++++---------------
 .../jbang/core/commands/tui/RouteDiagramZoom.java  |  2 +-
 .../dsl/jbang/core/commands/tui/SubViewBar.java    |  2 +-
 .../core/commands/tui/DiagramTabLevelBarTest.java  | 50 ++++++++++++++++++++
 .../core/commands/tui/RouteDiagramZoomTest.java    |  4 +-
 5 files changed, 71 insertions(+), 42 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java
index 697a1dea978e..fdd1e13fe753 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTab.java
@@ -393,38 +393,22 @@ class DiagramTab extends AbstractDiagramTab {
         if (ctx.findSelectedIntegration() == null || sourceViewer.isVisible() 
|| !diagram.isShowDiagram()) {
             return null;
         }
-        // the levels are in the title of the diagram, as the DSLs of the 
Source tab are (v moves through them); the
-        // bar has the view settings of the level shown
-        return new SubViewBar.Spec(null, List.of(), viewToggles(), true);
+        // the levels lead the bar, with v that moves through them, so it is 
plain there are three; the view settings of
+        // the level shown are at its right
+        return new SubViewBar.Spec("v", levelViews(), viewToggles(), true);
     }
 
-    /**
-     * The levels for the title of the diagram: Architecture │ Topology │ 
Route, the one shown bold and the others dim,
-     * as the Source tab shows YAML │ Java │ XML. The Route level is dimmer 
when no route is selected to go to.
-     */
-    List<Span> levelSpans() {
+    /** The levels for the bar: the one shown highlighted, Route greyed out 
while no route is selected to go to. */
+    List<SubViewBar.View> levelViews() {
         Level current = level();
-        List<Span> spans = new ArrayList<>();
-        spans.add(Span.raw(" "));
-        String[] labels = { "Architecture", "Topology", "Route" };
-        Level[] levels = { Level.ARCHITECTURE, Level.TOPOLOGY, Level.ROUTE };
-        for (int i = 0; i < levels.length; i++) {
-            if (i > 0) {
-                spans.add(Span.styled(" \u2502 ", Style.EMPTY.dim()));
-            }
-            Style style = levels[i] == current ? Style.EMPTY.bold()
-                    : levels[i] == Level.ROUTE && routeCandidate() == null ? 
Theme.muted().dim() : Style.EMPTY.dim();
-            spans.add(Span.styled(labels[i], style));
-        }
-        spans.add(Span.raw(" "));
-        return spans;
-    }
-
-    /** The title with the levels after it. */
-    private Line withLevels(Line title) {
-        List<Span> spans = new ArrayList<>(title.spans());
-        spans.addAll(levelSpans());
-        return Line.from(spans);
+        return List.of(
+                new SubViewBar.View(
+                        "Architecture", current == Level.ARCHITECTURE, true,
+                        () -> goToLevel(Level.ARCHITECTURE)),
+                new SubViewBar.View("Topology", current == Level.TOPOLOGY, 
true, () -> goToLevel(Level.TOPOLOGY)),
+                new SubViewBar.View(
+                        "Route", current == Level.ROUTE, routeCandidate() != 
null,
+                        () -> goToLevel(Level.ROUTE)));
     }
 
     /**
@@ -547,7 +531,7 @@ class DiagramTab extends AbstractDiagramTab {
         }
 
         if (architecture.isActive()) {
-            architecture.render(frame, area, info.name, levelSpans());
+            architecture.render(frame, area, info.name, List.of());
             return;
         }
 
@@ -557,7 +541,7 @@ class DiagramTab extends AbstractDiagramTab {
             if (topologyMode && diagram.hasNativeLayout()) {
                 Line title;
                 if (info.name != null) {
-                    // the level is named by the levels after it, as on the 
Source tab
+                    // the level is named by the bar above
                     title = Line.from(
                             Span.raw(" Diagram ["),
                             Span.styled(info.name, Theme.label().bold()),
@@ -565,7 +549,6 @@ class DiagramTab extends AbstractDiagramTab {
                 } else {
                     title = Line.from(Span.raw(" Diagram "));
                 }
-                title = withLevels(title);
                 if (selectedRouteId != null && area.width() > 60) {
                     infoPanelWidth = Math.max(10, Math.min(infoPanelWidth, 
area.width() - 20));
                     List<Rect> hChunks = Layout.horizontal()
@@ -583,10 +566,10 @@ class DiagramTab extends AbstractDiagramTab {
             } else if (!topologyMode && drillDownRouteId != null
                     && diagram.getRouteLayout(drillDownRouteId) != null) {
                 var routeLayout = diagram.getRouteLayout(drillDownRouteId);
-                Line title = 
withLevels(diagram.zoom.withStepCount(DiagramDetailSupport.withRouteContext(
+                Line title = 
diagram.zoom.withStepCount(DiagramDetailSupport.withRouteContext(
                         
DiagramDetailSupport.buildBreadcrumbTitle(routeNavigationStack, 
drillDownRouteId), info,
                         drillDownRouteId, selectedSourceDirectory(), 
isShowGroups(), diagram.isShowErrorPaths()),
-                        drillDownRouteId, routeLayout));
+                        drillDownRouteId, routeLayout);
                 if (area.width() > 60) {
                     infoPanelWidth = Math.max(10, Math.min(infoPanelWidth, 
area.width() - 20));
                     List<Rect> hChunks = Layout.horizontal()
@@ -649,10 +632,6 @@ class DiagramTab extends AbstractDiagramTab {
             sourceViewer.renderFooter(spans);
             return;
         }
-        if (diagram.isShowDiagram() && ctx.findSelectedIntegration() != null) {
-            // the levels are in the title of the diagram
-            hint(spans, "v", "level");
-        }
         if (architecture.isActive()) {
             architecture.renderFooter(spans);
             return;
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RouteDiagramZoom.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RouteDiagramZoom.java
index d6d28e1d63f4..df3c69d5c000 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RouteDiagramZoom.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RouteDiagramZoom.java
@@ -245,7 +245,7 @@ final class RouteDiagramZoom {
         for (int n : foldedStepsOf(shown).values()) {
             hidden += n;
         }
-        String text = steps + (steps == 1 ? " step" : " steps") + (hidden > 0 
? " · " + hidden + " folded" : "") + " ";
+        String text = "· " + steps + (steps == 1 ? " step" : " steps") + 
(hidden > 0 ? " · " + hidden + " folded" : "") + " ";
         List<Span> spans = new ArrayList<>(title.spans());
         spans.add(Span.styled(text, Theme.muted()));
         return Line.from(spans);
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SubViewBar.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SubViewBar.java
index c559fabd1e7b..faaf09b2599e 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SubViewBar.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/SubViewBar.java
@@ -85,7 +85,7 @@ final class SubViewBar {
             spans.add(Span.raw(" "));
             x += CharWidth.of(key) + 1;
         }
-        String separator = spec.levels() ? "  ›  " : "  │  ";
+        String separator = spec.levels() ? " › " : "  │  ";
         List<View> views = spec.views();
         for (int i = 0; i < views.size(); i++) {
             View v = views.get(i);
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTabLevelBarTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTabLevelBarTest.java
new file mode 100644
index 000000000000..6be2cd331147
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramTabLevelBarTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.tui;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The three levels of the Diagram tab lead its view bar, so it is plain there 
are three and v moves through them.
+ */
+class DiagramTabLevelBarTest {
+
+    private final MonitorContext ctx = new MonitorContext(
+            new AtomicReference<>(List.of()), new 
AtomicReference<>(List.of()));
+
+    @Test
+    void theLevelsAreViewsOfTheBar() {
+        DiagramTab tab = new DiagramTab(ctx);
+
+        List<SubViewBar.View> views = tab.levelViews();
+        
assertThat(views).extracting(SubViewBar.View::label).containsExactly("Architecture",
 "Topology", "Route");
+        // the topology first; no route selected to go to yet
+        
assertThat(views).extracting(SubViewBar.View::active).containsExactly(false, 
true, false);
+        
assertThat(views).extracting(SubViewBar.View::enabled).containsExactly(true, 
true, false);
+
+        tab.topologyMode = false;
+        tab.drillDownRouteId = "orders";
+        views = tab.levelViews();
+        
assertThat(views).extracting(SubViewBar.View::active).containsExactly(false, 
false, true);
+        assertThat(views.get(2).enabled()).isTrue();
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/RouteDiagramZoomTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/RouteDiagramZoomTest.java
index 0e53e3881168..4133c870210f 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/RouteDiagramZoomTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/RouteDiagramZoomTest.java
@@ -126,12 +126,12 @@ class RouteDiagramZoomTest {
         LayoutRoute lr = layout(zoom, 0);
         assertThat(zoom.stepCount("orders")).isEqualTo(9);
         assertThat(text(zoom.withStepCount(Line.from(" Route [orders] "), 
"orders", lr)))
-                .isEqualTo(" Route [orders] 9 steps ");
+                .isEqualTo(" Route [orders] · 9 steps ");
 
         zoom.toggleFold("orders", find(lr, "choice1"));
         lr = layout(zoom, 0);
         assertThat(text(zoom.withStepCount(Line.from(" Route [orders] "), 
"orders", lr)))
-                .isEqualTo(" Route [orders] 9 steps · 5 folded ");
+                .isEqualTo(" Route [orders] · 9 steps · 5 folded ");
         // a route not laid out yet: the title as it is
         assertThat(text(zoom.withStepCount(Line.from(" Route [other] "), 
"other", lr))).isEqualTo(" Route [other] ");
     }

Reply via email to