This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-23598-tui-screenshot in repository https://gitbox.apache.org/repos/asf/camel.git
commit 2a37c1374a69ca0753079be8733291b7a18cced7 Author: Claus Ibsen <[email protected]> AuthorDate: Thu May 21 11:02:55 2026 +0200 CAMEL-23598: TUI screenshot action (Shift+F5) to capture screen as ASCII art Co-Authored-By: Claude <[email protected]> --- .../dsl/jbang/core/commands/tui/CamelMonitor.java | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) 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 a6197c03a367..46c647eb53cd 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 @@ -23,7 +23,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.Duration; import java.time.Instant; +import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -39,6 +41,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import dev.tamboui.buffer.Buffer; +import dev.tamboui.export.ExportRequest; import dev.tamboui.layout.Constraint; import dev.tamboui.layout.Layout; import dev.tamboui.layout.Rect; @@ -192,6 +196,9 @@ public class CamelMonitor extends CamelCommand { private volatile long lastRefresh; private boolean showKillConfirm; + private volatile Buffer lastBuffer; + private volatile String screenshotMessage; + private volatile long screenshotMessageTime; private final AtomicBoolean refreshInProgress = new AtomicBoolean(false); private TuiRunner runner; @@ -368,6 +375,12 @@ public class CamelMonitor extends CamelCommand { return true; } + // Screenshot: Shift+F5 + if (ke.isKey(KeyCode.F5) && ke.hasShift()) { + takeScreenshot(); + return true; + } + // Tab-specific keys — delegate to active tab first int tab = tabsState.selected(); MonitorTab activeTab = activeTab(); @@ -635,6 +648,8 @@ public class CamelMonitor extends CamelCommand { renderKillConfirm(frame, mainChunks.get(4)); } renderFooter(frame, mainChunks.get(5)); + + lastBuffer = frame.buffer(); } private void renderHeader(Frame frame, Rect area) { @@ -1434,6 +1449,16 @@ public class CamelMonitor extends CamelCommand { } private void renderFooter(Frame frame, Rect area) { + // Show screenshot flash message briefly + String msg = screenshotMessage; + if (msg != null && System.currentTimeMillis() - screenshotMessageTime < 3000) { + frame.renderWidget( + Paragraph.from(Line.from(Span.styled(" " + msg, Style.EMPTY.fg(Color.GREEN)))), + area); + return; + } + screenshotMessage = null; + List<Span> spans = new ArrayList<>(); MonitorTab tab = activeTab(); @@ -2706,6 +2731,23 @@ public class CamelMonitor extends CamelCommand { return ph.info().startInstant().map(Instant::toEpochMilli).orElse(0L); } + private void takeScreenshot() { + Buffer buf = lastBuffer; + if (buf == null) { + return; + } + try { + String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss")); + Path path = Path.of("camel-tui-screenshot-" + timestamp + ".txt"); + ExportRequest.export(buf).text().toFile(path); + screenshotMessage = "Screenshot saved to " + path.toAbsolutePath(); + screenshotMessageTime = System.currentTimeMillis(); + } catch (IOException e) { + screenshotMessage = "Screenshot failed: " + e.getMessage(); + screenshotMessageTime = System.currentTimeMillis(); + } + } + private static String objToString(Object o) { return o != null ? o.toString() : ""; }
