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

davsclaus pushed a commit to branch feature/CAMEL-23857-tui-runtime-chooser
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 83e7708c43d2162f4406e680b47ee1e891ce49bb
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Jun 29 20:45:36 2026 +0200

    CAMEL-23857: TUI allow to choose runtime when running from folder or 
examples
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../jbang/core/commands/tui/RunOptionsForm.java    | 68 +++++++++++++++++-----
 1 file changed, 55 insertions(+), 13 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java
index 64c776b53636..669b65abe008 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/RunOptionsForm.java
@@ -44,15 +44,16 @@ class RunOptionsForm {
 
     // Row indices for page 0
     private static final int ROW_NAME = 0;
-    private static final int ROW_PORT = 1;
-    private static final int ROW_MAX = 2;
-    private static final int ROW_CONSOLE = 3;
-    private static final int ROW_DEV = 4;
-    private static final int ROW_OBSERVE = 5;
-    private static final int ROW_TRACE = 6;
-    private static final int ROW_STUB = 7;
-    private static final int ROW_OTEL_AGENT = 8;
-    private static final int ROW_COUNT = 9;
+    private static final int ROW_RUNTIME = 1;
+    private static final int ROW_PORT = 2;
+    private static final int ROW_MAX = 3;
+    private static final int ROW_CONSOLE = 4;
+    private static final int ROW_DEV = 5;
+    private static final int ROW_OBSERVE = 6;
+    private static final int ROW_TRACE = 7;
+    private static final int ROW_STUB = 8;
+    private static final int ROW_OTEL_AGENT = 9;
+    private static final int ROW_COUNT = 10;
 
     private boolean visible;
     private int page;
@@ -60,12 +61,15 @@ class RunOptionsForm {
 
     private static final String[] MAX_MODES = { "Max seconds:", "Max 
messages:", "Max idle secs:" };
     private static final String[] MAX_FLAGS = { "--max-seconds=", 
"--max-messages=", "--max-idle-seconds=" };
+    private static final String[] RUNTIME_LABELS = { "Camel Main", "Spring 
Boot", "Quarkus" };
+    private static final String[] RUNTIME_VALUES = { "camel-main", 
"spring-boot", "quarkus" };
 
     // Text fields
     private TextInputState nameInput;
     private TextInputState portInput;
     private TextInputState maxInput;
     private int maxMode;
+    private int runtimeMode;
 
     // Checkboxes
     private boolean devMode;
@@ -96,6 +100,7 @@ class RunOptionsForm {
         portInput = new TextInputState("");
         maxInput = new TextInputState("");
         maxMode = 0;
+        runtimeMode = 0;
         devMode = dev;
         observe = false;
         backlogTrace = false;
@@ -161,7 +166,9 @@ class RunOptionsForm {
             } else {
                 hint(spans, "Tab", "next");
             }
-            if (selectedRow >= ROW_CONSOLE) {
+            if (selectedRow == ROW_RUNTIME || selectedRow == ROW_MAX) {
+                hint(spans, "Space", "cycle");
+            } else if (selectedRow >= ROW_CONSOLE) {
                 hint(spans, "Space", "toggle");
             }
             if (hasProperties()) {
@@ -184,6 +191,9 @@ class RunOptionsForm {
         if (!name.isEmpty()) {
             args.add("--name=" + name);
         }
+        if (runtimeMode > 0) {
+            args.add("--runtime=" + RUNTIME_VALUES[runtimeMode]);
+        }
         String port = portInput.text().trim();
         if (!port.isEmpty()) {
             args.add("--port=" + port);
@@ -277,6 +287,18 @@ class RunOptionsForm {
             return true;
         }
 
+        // Runtime row: Space or Left/Right cycles
+        if (selectedRow == ROW_RUNTIME) {
+            if (ke.isChar(' ') || ke.isRight()) {
+                runtimeMode = (runtimeMode + 1) % RUNTIME_LABELS.length;
+                return true;
+            }
+            if (ke.isLeft()) {
+                runtimeMode = (runtimeMode - 1 + RUNTIME_LABELS.length) % 
RUNTIME_LABELS.length;
+                return true;
+            }
+        }
+
         // Max row: Space cycles mode
         if (ke.isChar(' ') && selectedRow == ROW_MAX) {
             maxMode = (maxMode + 1) % MAX_MODES.length;
@@ -296,8 +318,8 @@ class RunOptionsForm {
             return true;
         }
 
-        // Text field rows: delegate to active input
-        if (selectedRow <= ROW_MAX) {
+        // Text field rows: delegate to active input (skip runtime row — it 
uses cycling)
+        if (selectedRow <= ROW_MAX && selectedRow != ROW_RUNTIME) {
             TextInputState active = activeInput();
             if (active != null) {
                 handleTextInput(ke, active, selectedRow == ROW_PORT || 
selectedRow == ROW_MAX);
@@ -408,7 +430,7 @@ class RunOptionsForm {
 
     private void renderOptionsPage(Frame frame, Rect area) {
         int popupW = Math.min(56, area.width() - 4);
-        int popupH = 13;
+        int popupH = 14;
         int x = area.left() + Math.max(0, (area.width() - popupW) / 2);
         int y = area.top() + Math.max(0, (area.height() - popupH) / 4);
         Rect popup = new Rect(x, y, Math.min(popupW, area.width()), 
Math.min(popupH, area.height()));
@@ -438,6 +460,10 @@ class RunOptionsForm {
         renderTextInput(frame, innerX + labelW, rowY, fieldW, nameInput, 
selectedRow == ROW_NAME);
         rowY++;
 
+        renderLabel(frame, innerX, rowY, labelW, "Runtime:", selectedRow == 
ROW_RUNTIME);
+        renderCycler(frame, innerX + labelW, rowY, fieldW, RUNTIME_LABELS, 
runtimeMode, selectedRow == ROW_RUNTIME);
+        rowY++;
+
         renderLabel(frame, innerX, rowY, labelW, "Port:", selectedRow == 
ROW_PORT);
         renderTextInput(frame, innerX + labelW, rowY, fieldW, portInput, 
selectedRow == ROW_PORT);
         rowY++;
@@ -644,6 +670,22 @@ class RunOptionsForm {
         }
     }
 
+    private void renderCycler(Frame frame, int x, int y, int w, String[] 
labels, int active, boolean selected) {
+        List<Span> spans = new ArrayList<>();
+        for (int i = 0; i < labels.length; i++) {
+            if (i > 0) {
+                spans.add(Span.styled(" ", Style.EMPTY));
+            }
+            if (i == active) {
+                spans.add(Span.styled("[" + labels[i] + "]", selected ? 
Style.EMPTY.bold() : Style.EMPTY));
+            } else {
+                spans.add(Span.styled(" " + labels[i] + " ", 
Style.EMPTY.dim()));
+            }
+        }
+        Rect area = new Rect(x, y, w, 1);
+        frame.renderWidget(Paragraph.from(Line.from(spans)), area);
+    }
+
     private void renderCheckbox(Frame frame, int x, int y, int w, String 
label, boolean checked, boolean selected) {
         String box = checked ? "[x]" : "[ ]";
         Style style = selected ? Style.EMPTY.bold().reversed() : Style.EMPTY;

Reply via email to