Skip to content

Add configurable radial menu for controls#1709

Open
Nightwalker743 wants to merge 7 commits into
utkarshdalal:masterfrom
Nightwalker743:feature/radial-menu-wheel-pr
Open

Add configurable radial menu for controls#1709
Nightwalker743 wants to merge 7 commits into
utkarshdalal:masterfrom
Nightwalker743:feature/radial-menu-wheel-pr

Conversation

@Nightwalker743

@Nightwalker743 Nightwalker743 commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a configurable radial menu for control profiles. The radial menu setting is in the in-game quick menu.

Users can bind on-screen controls, touchscreen gestures, or physical controller inputs to open a radial wheel with up to 12 actions. Radial slots can trigger existing bindings such as keyboard keys, mouse buttons, gamepad buttons, show keyboard, etc.

Recording

https://drive.google.com/file/d/1J8N80X6IBjkhhcNJCU-v48TmQf0LYGC7/view?usp=sharing

Type of Change

  • Bug fix
  • Performance / stability improvement
  • Compatibility improvements
  • Other (requires prior approval)

Checklist

  • If I have access to #code-changes, I have discussed this change there and it has been green-lighted. If I do not have access, I have still provided clear context in this PR. If I skip both, I accept that this change may face delays in review, may not be reviewed at all, or may be closed.
  • This change aligns with the current project scope (core functionality, stability, or performance). If not, it has been explicitly approved beforehand.
  • I have attached a recording of the change.
  • I have read and agree to the contribution guidelines in CONTRIBUTING.md.

Summary by CodeRabbit

  • New Features
    • Introduced a configurable radial menu overlay with up to 12 slots, slot labeling, and per-slot action bindings.
    • Open radial menus via gestures/touch actions, the touch pad gesture, physical controllers, and the Quick Menu.
    • Added a Radial Menu settings dialog (slot count, labels, bindings, and presets) with changes saved per control profile.
    • Radial menu configuration is copied when duplicating control profiles.
  • Localization
    • Added translated radial menu UI text and the “open radial menu” gesture/action label across supported languages.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2e24cb6e-fcea-46e2-b8d9-4003f4042b4d

📥 Commits

Reviewing files that changed from the base of the PR and between 3ad45eb and e964f10.

📒 Files selected for processing (20)
  • app/src/main/java/app/gamenative/PluviaApp.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
  • app/src/main/java/com/winlator/inputcontrols/Binding.java
  • app/src/main/java/com/winlator/widget/InputControlsView.java
  • app/src/main/res/values-da/strings.xml
  • app/src/main/res/values-de/strings.xml
  • app/src/main/res/values-es/strings.xml
  • app/src/main/res/values-fr/strings.xml
  • app/src/main/res/values-it/strings.xml
  • app/src/main/res/values-ja/strings.xml
  • app/src/main/res/values-ko/strings.xml
  • app/src/main/res/values-pl/strings.xml
  • app/src/main/res/values-pt-rBR/strings.xml
  • app/src/main/res/values-ro/strings.xml
  • app/src/main/res/values-ru/strings.xml
  • app/src/main/res/values-uk/strings.xml
  • app/src/main/res/values-zh-rCN/strings.xml
  • app/src/main/res/values-zh-rTW/strings.xml
  • app/src/main/res/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (19)
  • app/src/main/res/values-de/strings.xml
  • app/src/main/res/values-it/strings.xml
  • app/src/main/res/values-da/strings.xml
  • app/src/main/java/com/winlator/inputcontrols/Binding.java
  • app/src/main/res/values-zh-rCN/strings.xml
  • app/src/main/res/values-pt-rBR/strings.xml
  • app/src/main/res/values-es/strings.xml
  • app/src/main/res/values-ro/strings.xml
  • app/src/main/res/values-fr/strings.xml
  • app/src/main/res/values/strings.xml
  • app/src/main/res/values-ja/strings.xml
  • app/src/main/res/values-ko/strings.xml
  • app/src/main/java/app/gamenative/PluviaApp.kt
  • app/src/main/res/values-pl/strings.xml
  • app/src/main/res/values-zh-rTW/strings.xml
  • app/src/main/res/values-ru/strings.xml
  • app/src/main/java/com/winlator/widget/InputControlsView.java
  • app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt

📝 Walkthrough

Walkthrough

Adds a configurable radial menu with persisted slots and bindings, controller and touch gesture activation, an interactive overlay, settings UI, QuickMenu access, profile synchronization, gamepad dispatch, lifecycle cleanup, and localized strings.

Changes

Radial menu feature

Layer / File(s) Summary
Radial menu contracts and persistence
app/src/main/java/com/winlator/inputcontrols/*, app/src/main/java/app/gamenative/ui/screen/xserver/InputControlsProfileCopy.kt
Defines radial menu bindings and slot models, persists menus in control profiles, and deep-copies default menus between profiles.
Touch and controller input plumbing
app/src/main/java/com/winlator/widget/*, app/src/main/java/com/winlator/inputcontrols/ControlElement.java, app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt
Routes touch, gesture, keyboard, joystick, and motion input into radial menu state and selection callbacks.
Overlay and coordinator
app/src/main/java/app/gamenative/ui/screen/xserver/RadialMenuOverlayView.kt, app/src/main/java/app/gamenative/ui/screen/xserver/RadialMenuCoordinator.kt
Renders the radial menu, manages pointer selection and profiles, hosts settings, and dispatches selected bindings.
Settings and screen integration
app/src/main/java/app/gamenative/ui/component/dialog/*, app/src/main/java/app/gamenative/ui/component/QuickMenu.kt, app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt, app/src/main/java/app/gamenative/PluviaApp.kt
Adds slot and binding configuration, QuickMenu access, gesture selection, coordinator installation, profile synchronization, and teardown.
Localization
app/src/main/res/values*/strings.xml
Adds radial menu settings, preset, slot, binding, and gesture-action strings across supported locales.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant XServerScreen
  participant RadialMenuCoordinator
  participant RadialMenuOverlayView
  participant XServer
  User->>XServerScreen: touch, gesture, or controller input
  XServerScreen->>RadialMenuCoordinator: route radial menu event
  RadialMenuCoordinator->>RadialMenuOverlayView: open and update selection
  RadialMenuOverlayView-->>RadialMenuCoordinator: selected binding on release
  RadialMenuCoordinator->>XServer: dispatch binding and gamepad state
Loading

Possibly related PRs

Suggested reviewers: utkarshdalal

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.25% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly describes the main change: adding a configurable radial menu for controls.
Description check ✅ Passed The description includes all required sections, explains the change, provides a recording link, and completes the checklist.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Nightwalker743
Nightwalker743 marked this pull request as ready for review July 12, 2026 22:08

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 12

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt`:
- Line 27: Update closeRadialMenuIfOpen() and its teardown callers, including
profile changes and cleanup(), to accept or propagate a commit/cancel choice and
invoke the radial-menu close path with commit = false during lifecycle closure.
Preserve normal release behavior with commit = true for user-triggered button
release, so RadialMenuCoordinator does not execute the highlighted slot during
teardown.
- Around line 173-179: Update the radial-menu opening transition in
PhysicalControllerHandler, around the radialMenuPressed handling and its
motion-opener path, to neutralize any previously active gamepad axes, triggers,
and mouse movement before returning to radial selection. Exclude the control
that opened the menu, send neutral release states once on the opening
transition, and preserve normal radial-menu vector updates and opener-release
behavior.
- Around line 46-48: Update PhysicalControllerHandler’s radial-menu state to
track the opener controller device ID alongside radialMenuOpenerKeyCode. Record
the device ID when opening the menu, and in the radial input, selection,
release, and close paths ignore events from other devices so only the opener can
drive or close the menu; preserve existing keycode checks and
motion-versus-digital behavior.

In `@app/src/main/java/app/gamenative/ui/screen/xserver/RadialMenuCoordinator.kt`:
- Around line 263-266: The radial-stick handling in the visible magnitude check
must clear the current selection when the controller returns to the dead zone.
Update the relevant selection state in the coordinator before returning from the
magnitude < 0.25f branch, so releasing the opener selects the displayed cancel
area rather than committing the previous slot.
- Around line 326-336: Update the profile creation flow in RadialMenuCoordinator
around duplicateProfile so any duplication or subsequent linkage/save failure
aborts settings instead of returning sourceProfile. Keep the duplicate
operation, name assignment, container profileId update, and persistence within
one failure boundary, and propagate or handle the failure so the settings dialog
is not opened with an inconsistent profile.

In `@app/src/main/java/app/gamenative/ui/screen/xserver/RadialMenuOverlayView.kt`:
- Around line 192-199: Update label sizing in the radial menu drawing logic
around fitLabel and textRadiusPx so the maximum label width is derived from the
available slice width represented by sweep and textRadiusPx, rather than using
the fixed radiusPx * 0.62f constraint. Preserve support for all configured
action counts, including 12 slots, and continue passing the resulting
constrained label to canvas.drawText.

In `@app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt`:
- Line 1124: Update the profile-swap flow near radialMenuCoordinator.setProfile
to also call physicalControllerHandler?.setProfile with the same activeProfile,
or use a shared helper that updates both components. Ensure OPEN_RADIAL_MENU
uses the new profile’s bindings after every profile change.

In `@app/src/main/java/com/winlator/inputcontrols/ControlElement.java`:
- Around line 1261-1266: Update the Type.BUTTON release handling in
ControlElement so radial-menu buttons handled by isRadialMenuButton() do not
proceed into the common toggleSwitch logic. Ensure the OPEN_RADIAL_MENU action
remains momentary by bypassing or clearing toggle behavior for that branch,
while preserving the existing radial-menu touch-up and invalidation calls.
- Around line 1078-1084: Before the radial-menu early return in the directional
handling logic of ControlElement, release every previously active directional
binding recorded in states, including keyboard, mouse, and gamepad inputs, then
clear their active state before calling handleRadialMenuTouchDown. Preserve
normal radial-menu activation and ensure the existing cleanup path cannot leave
prior directional inputs held.

In `@app/src/main/java/com/winlator/widget/InputControlsView.java`:
- Around line 1283-1285: The ACTION_CANCEL handling must release the saved
radial pointer without committing any radial button. Update the cancellation
flow around handleRadialMenuTouchUp and the element-loop handleTouchUp path to
use a dedicated cancel-release operation for radial controls, keyed by
radialMenuTouchPointerId rather than the event action-index pointer, while
preserving normal touch-up behavior.

In `@app/src/main/res/values-ru/strings.xml`:
- Line 1985: Update the radial_menu_slot_count_subtitle string to use the
natural Russian wording “Активных слотов: %1$d” while preserving the existing
numeric placeholder.
- Around line 1991-1992: Update the Russian translations
radial_menu_slot_binding and radial_menu_slot_binding_summary to use the
established “Привязка” terminology instead of “Назначение,” preserving their
existing format placeholders.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a9b6cc6-d51d-4a4f-a552-4eb4437de9f8

📥 Commits

Reviewing files that changed from the base of the PR and between aaeafe7 and a238077.

📒 Files selected for processing (31)
  • app/src/main/java/app/gamenative/PluviaApp.kt
  • app/src/main/java/app/gamenative/data/TouchGestureConfig.kt
  • app/src/main/java/app/gamenative/ui/component/QuickMenu.kt
  • app/src/main/java/app/gamenative/ui/component/dialog/RadialMenuSettingsDialog.kt
  • app/src/main/java/app/gamenative/ui/component/dialog/TouchGestureSettingsDialog.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/InputControlsProfileCopy.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/RadialMenuCoordinator.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/RadialMenuOverlayView.kt
  • app/src/main/java/app/gamenative/ui/screen/xserver/XServerScreen.kt
  • app/src/main/java/com/winlator/inputcontrols/Binding.java
  • app/src/main/java/com/winlator/inputcontrols/ControlElement.java
  • app/src/main/java/com/winlator/inputcontrols/ControlsProfile.java
  • app/src/main/java/com/winlator/inputcontrols/RadialMenu.java
  • app/src/main/java/com/winlator/widget/InputControlsView.java
  • app/src/main/java/com/winlator/widget/TouchpadView.java
  • app/src/main/res/values-da/strings.xml
  • app/src/main/res/values-de/strings.xml
  • app/src/main/res/values-es/strings.xml
  • app/src/main/res/values-fr/strings.xml
  • app/src/main/res/values-it/strings.xml
  • app/src/main/res/values-ja/strings.xml
  • app/src/main/res/values-ko/strings.xml
  • app/src/main/res/values-pl/strings.xml
  • app/src/main/res/values-pt-rBR/strings.xml
  • app/src/main/res/values-ro/strings.xml
  • app/src/main/res/values-ru/strings.xml
  • app/src/main/res/values-uk/strings.xml
  • app/src/main/res/values-zh-rCN/strings.xml
  • app/src/main/res/values-zh-rTW/strings.xml
  • app/src/main/res/values/strings.xml

Comment thread app/src/main/java/app/gamenative/ui/screen/xserver/PhysicalControllerHandler.kt Outdated
Comment thread app/src/main/java/com/winlator/inputcontrols/ControlElement.java
Comment thread app/src/main/java/com/winlator/inputcontrols/ControlElement.java
Comment thread app/src/main/java/com/winlator/widget/InputControlsView.java
Comment thread app/src/main/res/values-ru/strings.xml Outdated
Comment thread app/src/main/res/values-ru/strings.xml Outdated

@cubic-dev-ai cubic-dev-ai Bot 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.

All reported issues were addressed across 31 files

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Comment thread app/src/main/java/com/winlator/inputcontrols/ControlElement.java Outdated
Comment thread app/src/main/java/app/gamenative/ui/screen/xserver/RadialMenuCoordinator.kt Outdated
Comment thread app/src/main/java/com/winlator/inputcontrols/ControlElement.java
Comment thread app/src/main/java/com/winlator/inputcontrols/ControlElement.java
Comment thread app/src/main/res/values-fr/strings.xml Outdated
Comment thread app/src/main/res/values-ko/strings.xml Outdated
Comment thread app/src/main/res/values-ko/strings.xml Outdated
Comment thread app/src/main/java/com/winlator/inputcontrols/RadialMenu.java
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant