Skip to content

CAMEL-23831: Add footer and Actions popup mouse support to camel-tui#24365

Merged
davsclaus merged 2 commits into
apache:mainfrom
ammachado:CAMEL-23831
Jul 2, 2026
Merged

CAMEL-23831: Add footer and Actions popup mouse support to camel-tui#24365
davsclaus merged 2 commits into
apache:mainfrom
ammachado:CAMEL-23831

Conversation

@ammachado

@ammachado ammachado commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Description

Follow-up to #24351 (merged), which added the bulk of mouse support to the
camel-tui monitor (camel-jbang-plugin-tui): mouse-wheel scrolling,
click-to-select on table tabs, tab-bar clicks, the More/Switch dropdown mouse
handling, scrollbar drag, panel-border resize and node selection in diagram views.

This PR adds the two pointer interactions #24351 did not cover, re-fitted onto its
architecture:

  • Footer key bindings — clicking a hint such as F1/help, F2/actions,
    Enter/open or a single-letter action (d, f, p, r, x, ...) fires that
    key. renderFooter captures the on-screen column range of every clickable hint
    (the Theme.hintKey()-styled key span plus its label span) after the
    overflow-drop logic runs, so clicking either the key or its label works.
    handleMouseEvent routes a left click on the footer row through
    handleFooterClick, which hit-tests the click and feeds the synthesized
    KeyEvent back through the normal key path, so it behaves exactly like the key
    press (including popups and tab switching). footerKeyEvent maps a hint token
    to a KeyEvent for unambiguous single keys only (F1-F12, Enter, Esc, Tab, single
    characters); ambiguous multi-key hints (Up/Down, PgUp/PgDn, arrow glyphs) stay
    non-clickable. Overlay states (screenshot flash, help, caption) leave the footer
    non-clickable.
  • Actions popup and doc pickerActionsPopup.handleMouseEvent handles the F2
    Actions menu and the doc picker with the same modal approach Improve mouse support in TUI: scroll, tab clicks, node selection, panel resize #24351 used for the
    More dropdown: a click on an entry selects and activates it via a synthetic
    Enter, a click outside goes back one level via a synthetic Esc, and the wheel
    moves the highlight. Divider rows are ignored. CamelMonitor now routes mouse
    events to ActionsPopup when it is visible instead of dropping them. The example
    and infra browsers stay keyboard-only for now (their wrapped, variable-height rows
    cannot be reliably hit-tested).
  • Overview divider fixImprove mouse support in TUI: scroll, tab clicks, node selection, panel resize #24351 added click-to-select on the Overview table, but
    a click on the "Dev/Infra Services" divider row moved the visual selection onto it
    while leaving the selected pid unchanged. The prior selection is now restored when
    the divider row is clicked, keeping it non-selectable and matching keyboard
    navigation which already skips it.

Static hit-testing helpers (footerKeyEvent, footerRegionAt, listItemAt) are
unit-tested directly; render tests cover the footer click-to-key path, the Actions
popup entry selection, and the Overview divider-vs-row click behavior.

Target

  • I checked that the commit is targeting the correct branch (Camel 4 uses the main branch)

Tracking

  • If this is a large change, bug fix, or code improvement, I checked there is a JIRA issue filed for the change (usually before you start working on it).

Apache Camel coding standards and style

  • I checked that each commit in the pull request has a meaningful subject line and body.
  • I have run mvn clean install -DskipTests locally from root folder and I have committed all auto-generated changes.

AI-assisted contributions

  • If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., Co-authored-by trailers) and the PR description identifies the AI tool used.

This PR was prepared by Claude Code (Anthropic) on behalf of Adriano Machado. Commits carry Co-Authored-By trailers.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@github-actions github-actions Bot added the dsl label Jul 1, 2026
@ammachado ammachado requested review from davsclaus and gnodet and removed request for gnodet July 1, 2026 20:02

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CAMEL-23831: Add mouse support to camel-tui

Well-structured PR that adds mouse support (click-to-select, scroll wheel, popup interaction) to the TUI monitor. The architecture is clean: widgets stay pure renderers capturing geometry at render time, and CamelMonitor hit-tests at dispatch time. Commits are logically split into focused changes.

Observations (non-blocking)

  1. Unrelated PluginAdd.java change — The printer().printf("Plugin %s added%n", name) confirmation message is unrelated to mouse support. The PR description acknowledges it. Minor scope mixing but trivial.

  2. MORE_ITEM_COUNT = 17 hardcoded constant — Correct today (matches the 17 ListItem.from() entries). Will silently go stale when someone adds a new dropdown entry. Already an improvement over the prior bare 17 in selectNext(17), since the constant is named and scoped.

  3. Minor blank line removals — A few files have cosmetic blank line removals between fields (BrowseTab, HttpTab, ThreadsTab, HistoryTab, SpansTab). Harmless but unnecessary churn.

Checklist

  • JIRA ticket linked (CAMEL-23831)
  • Commit format follows conventions
  • Tests for new functionality (2 new test classes + additions to 5 existing ones)
  • AI attribution declared
  • No new dependencies
  • JUnit 5, no Thread.sleep(), no Lombok, no FQCNs
  • Targeting correct branch (main)

CI builds are still pending.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

@davsclaus

Copy link
Copy Markdown
Contributor

Ups have you seen @gnodet is also doing this with #24351

@ammachado

Copy link
Copy Markdown
Contributor Author

No, I haven't seen it. I'm working on this since the weekend. Let's keep this one on hold, and I rebase it once @gnodet's PR merge.

@ammachado

ammachado commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Comparison with #24351

Both PRs implement CAMEL-23831: mouse support for the camel-tui monitor, developed independently and in parallel.

At a glance

This PR #24351 (@gnodet)
Files changed 28 44
Additions / deletions +1,483 / −7 +1,859 / −976
New files 2 (both tests) 4 (AbstractTab, AbstractTableTab, DragSplit, PanelAnimation)
Net footprint Purely additive Add + heavy refactor
Commits 10, CAMEL-23831: prefixed, granular per-feature 6, chore: prefixed, refactor-oriented

Different core architecture

  • Improve mouse support in TUI: scroll, tab clicks, node selection, panel resize #24351 — inheritance refactor. Introduces AbstractTab (+107) and AbstractTableTab (+142) base classes, then pulls shared table logic up into them. This is why the table tabs show large deletions (BeansTab −61, ConsumersTab −58, DataSourceTab −58, InflightTab −68, HeapHistogramTab −77): duplicated code is centralized. Mouse behavior lives in the base classes via renderTableScrollbar() and nearestPresetIndex().
  • This PR — central dispatch, widgets stay pure renderers. Everything routes through a single MouseEvent branch in CamelMonitor. Widgets capture their geometry at render time and expose static hit-testing helpers (tableRowAt, tabIndexAt, morePopupItemAt, listItemAt, footerKeyEvent, footerRegionAt) that the app calls at dispatch time. The −7 deletions confirm it only adds.

Different feature scope

Testing

Overlap / conflict

The two PRs collide on ~19 files, including the hardest to reconcile (CamelMonitor, MonitorTab), every table tab, PopupManager, HistoryTab, OverviewTab, and OverviewTabRenderTest. Because #24351 restructures the class hierarchy that this PR builds on top of, they cannot merge cleanly together.

Recommendation

Let #24351 merge first (it does the deeper refactor and wider tab coverage; rebasing additive work onto it is far easier than the reverse). This PR then becomes a follow-up for the features #24351 lacks:

  • Clickable footer key bindings
  • Clickable Actions popup / doc picker
  • Overview integration-list click-to-select

On rebase, those would re-target the new AbstractTab / AbstractTableTab hit-testing surface instead of the current standalone static helpers.


Comparison prepared by Claude Code (Anthropic) on behalf of Adriano Machado.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • dsl/camel-jbang/camel-jbang-plugin-tui

🔬 Scalpel shadow comparison — Scalpel: 2 tested, 1 compile-only — current: 3 all tested

Maveniverse Scalpel detected 3 affected modules (current approach: 3).

Skip-tests mode would test 2 modules (1 direct + 1 downstream), skip tests for 1 (generated code, meta-modules)

Modules Scalpel would test (2)
  • camel-jbang-plugin-tui
  • camel-launcher-container
Modules with tests skipped (1)
  • camel-launcher

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

All tested modules (3 modules)
  • Camel :: JBang :: Plugin :: TUI
  • Camel :: Launcher
  • Camel :: Launcher :: Container

⚙️ View full build and test results

@ammachado

ammachado commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @davsclaus. Follow-up in 1c5c030 addresses the two non-blocking observations:

  • MORE_ITEM_COUNT staleness — the dropdown entries are now built by a shared moreItems() helper, and both the constant (MORE_ITEM_COUNT = moreItems().length) and the popup height (MORE_ITEM_COUNT + 2) derive from it, so they can no longer drift when an entry is added or removed.
  • Blank-line churn — restored the incidental blank-line removals in BrowseTab, HttpTab, ThreadsTab, SpansTab, and HistoryTab.

About the first observation (the PluginAdd.java message): it is no longer part of this branch's diff against main, so there is nothing left to split out.

Full camel-jbang-plugin-tui suite still green (516 tests).

Claude Code (Anthropic) on behalf of Adriano Machado

ammachado and others added 2 commits July 2, 2026 10:54
… clickable

Follow-up to apache#24351 (merged), which already added mouse wheel scrolling,
table click-to-select, tab-bar clicks and the More/Switch dropdown mouse
handling. This adds the two interactions apache#24351 did not cover, re-fitted onto
its architecture.

- Footer key bindings: renderFooter captures the on-screen column range of
  every clickable hint (a Theme.hintKey()-styled key span plus its label span)
  after the overflow-drop logic runs. handleMouseEvent routes a left click on
  the footer row through handleFooterClick, which hit-tests the click and feeds
  the synthesized KeyEvent back through the normal key path so it behaves
  exactly like the key press. footerKeyEvent maps a hint token to a KeyEvent for
  unambiguous single keys only (F1-F12, Enter, Esc, Tab, single characters);
  ambiguous multi-key hints (Up/Down, PgUp/PgDn, arrow glyphs) stay
  non-clickable. Overlay states (screenshot flash, help, caption) leave the
  footer non-clickable.
- Actions popup and doc picker: ActionsPopup.handleMouseEvent handles the F2
  Actions menu and the doc picker with the same modal approach as the More
  dropdown. A click on an entry selects and activates it via a synthetic Enter,
  a click outside goes back one level via a synthetic Esc, and the wheel moves
  the highlight. Divider rows are ignored. Other sub-popups stay modal.
  CamelMonitor now routes mouse events to ActionsPopup when it is visible
  instead of dropping them.

Tests: CamelMonitorTest covers footerKeyEvent parsing and footerRegionAt
geometry; ActionsPopupTest covers listItemAt geometry including scroll offset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
apache#24351 added click-to-select on the Overview table, but a click on the
"Dev/Infra Services" divider row moved the visual selection onto it (the
selected pid was left unchanged). Restore the prior selection when the divider
row is clicked so it stays non-selectable, matching keyboard navigation which
already skips it.

Tests: OverviewTabRenderTest covers clicking an integration row (selection
change plus pid-changed callback) and clicking the divider row (no change).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ammachado ammachado changed the title CAMEL-23831: Add mouse support to camel-tui CAMEL-23831: Add footer and Actions popup mouse support to camel-tui Jul 2, 2026
@ammachado ammachado marked this pull request as ready for review July 2, 2026 15:36

@davsclaus davsclaus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: CAMEL-23831 — Footer and Actions popup mouse support

CI Status: All checks pass.

Clean, well-scoped follow-up to #24351. Three features (footer clicks, Actions popup mouse, Overview divider fix) are logically coherent and consistent with the established mouse handling architecture.

Highlights

  • Re-entrancy is safehandleFooterClick calls handleEvent(KeyEvent) from inside handleEvent(MouseEvent). The synthesized event goes through a separate dispatch branch; no recursion risk.
  • Footer invalidation is correctrenderFooter resets footerRowY = -1 before any early-return path (screenshot flash, help overlay, caption), so overlay states leave the footer non-clickable.
  • Divider fix mirrors keyboard behavior — The Overview tab already skips the divider in navigateUp/navigateDown; the mouse click now does the same by restoring the prior selection.
  • Good separation — ActionsPopup gets mouse routing while FilesBrowser stays keyboard-only (variable-height rows prevent reliable hit-testing), matching the PR description.
  • Test coverage — All new static helpers (footerKeyEvent, footerRegionAt, listItemAt) are unit-tested. OverviewTab render tests cover both happy path and divider edge case.
  • Conventions — Commits follow CAMEL-XXXX: format with detailed bodies and Co-Authored-By trailers.

No issues found. LGTM.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

@davsclaus davsclaus merged commit 52c7642 into apache:main Jul 2, 2026
5 checks passed
@ammachado ammachado deleted the CAMEL-23831 branch July 2, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants