Skip to content

Commit c006336

Browse files
Zangesclaude
andauthored
Add node-based profiles plan; refresh stale WPF references (#25)
* Add node-based profiles plan; refresh stale WPF references Adds ai-docs/plans/node-based-profiles.md capturing the full design for replacing the current Binding+Modifier list with a per-profile node graph: typed ports (Digital/Delta/Scalar/Integer/Vector2), named profile-scoped variables for cross-tick state, DAG-only wire graph, shared single-instance source/target nodes, inline groups, and a shader-style canvas built on NodeEditorAvalonia plus a Skia CustomDrawOperation edge layer. Hard cutover with no v8 migration; old profiles get moved to profiles.v8.bak\ on first run. While drafting the plan it surfaced that CLAUDE.md and INITIALWORK.md still described the UI as WPF, even though the Avalonia cutover landed in PLAN_A_WINDOWS_AVALONIA.md. Updated both: - CLAUDE.md: project description, test-exception wording, run command, tooltip section now match the Avalonia API; added a pointer to the PLAN_A write-down for context. - INITIALWORK.md: added a top-of-doc stale-on-purpose notice pointing readers to PLAN_A for current UI shape; left the body as a v1 checkpoint per the doc's own framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Fix tooltip C# example: ToolTip.SetTip, not .ToolTip property Avalonia exposes tooltips via the ToolTip attached property setter (ToolTip.SetTip(control, value)); the .ToolTip = "..." form shown in CLAUDE.md is the WPF API and would not compile against Avalonia. The codebase uses ToolTip.SetTip exclusively (e.g. WidgetEditorWindow). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a2be5c2 commit c006336

3 files changed

Lines changed: 579 additions & 7 deletions

File tree

CLAUDE.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44

55
## What this project is
66

7-
Mouse2Joy is a Windows desktop app (.NET 8 / WPF, `net8.0-windows`, x64) that emulates an Xbox 360 / XInput gamepad and maps mouse motion, mouse buttons, scroll, and keyboard keys to virtual gamepad outputs. It's a solo project; v1 is functional end-to-end.
7+
Mouse2Joy is a Windows desktop app (.NET 8 / Avalonia 11, `net8.0-windows`, x64) that emulates an Xbox 360 / XInput gamepad and maps mouse motion, mouse buttons, scroll, and keyboard keys to virtual gamepad outputs. It's a solo project; v1 is functional end-to-end. (The UI was ported from WPF to Avalonia 11 — see [PLAN_A_WINDOWS_AVALONIA.md](ai-docs/implementations/PLAN_A_WINDOWS_AVALONIA.md) for the rationale.)
88

99
For the full architecture write-up — solution layout, tech stack, lifecycle, "where things live" table, and the rationale behind key design choices — read [INITIALWORK.md](ai-docs/implementations/INITIALWORK.md). That document is the source of truth for "big picture" architecture; do not duplicate its contents here.
1010

@@ -17,7 +17,7 @@ Past feature implementations are documented under [ai-docs/implementations/](ai-
1717
- **No Shortcuts**: Always implement the full feature or fix, even if it seems "obvious". Don't take shortcuts or make assumptions about what's "obviously right". The user prefers explicit, complete implementations.
1818
- **No Hacks**: Don't write "temporary hacks" or "just this once" code. If it needs to be done, do it properly. The user prefers clean, maintainable code over quick fixes.
1919
- **Keep everything user configurable**: Don't hardcode values or behaviors that the user might want to change. If it's a tweakable setting, make it a user option with a reasonable default.
20-
- **Always add tests when applicable**: For any new pure-logic surface — evaluators, parsers, math, state machines, persistence shapes, view-model logic that doesn't touch the WPF visual tree — add unit tests in the matching `tests/Mouse2Joy.*.Tests` project as part of the change. Mirror the file/class structure of an existing peer test (e.g., a new modifier evaluator goes next to its sibling in [tests/Mouse2Joy.Engine.Tests/Modifiers/ModifierEvaluatorTests.cs](tests/Mouse2Joy.Engine.Tests/Modifiers/ModifierEvaluatorTests.cs) and uses the same xUnit + FluentAssertions style). Cover the happy path, edge cases the implementation actually guards (e.g., NaN, clamps, identity defaults), and sign/symmetry where the math implies it. Run `dotnet test Mouse2Joy.sln` before reporting done. Exceptions where tests are optional — call them out explicitly in the response: code that's purely visual (XAML), tightly coupled to Win32 / kernel drivers (Interception, ViGEmBus, low-level hooks, the panic hotkey window), or where a real integration test would need admin + hardware. In those cases, prefer extracting the testable logic into a pure helper that *can* be tested. Never ship a new evaluator, parser, or non-trivial pure function without tests just because the user didn't explicitly ask.
20+
- **Always add tests when applicable**: For any new pure-logic surface — evaluators, parsers, math, state machines, persistence shapes, view-model logic that doesn't touch the Avalonia visual tree — add unit tests in the matching `tests/Mouse2Joy.*.Tests` project as part of the change. Mirror the file/class structure of an existing peer test (e.g., a new modifier evaluator goes next to its sibling in [tests/Mouse2Joy.Engine.Tests/Modifiers/ModifierEvaluatorTests.cs](tests/Mouse2Joy.Engine.Tests/Modifiers/ModifierEvaluatorTests.cs) and uses the same xUnit + FluentAssertions style). Cover the happy path, edge cases the implementation actually guards (e.g., NaN, clamps, identity defaults), and sign/symmetry where the math implies it. Run `dotnet test Mouse2Joy.sln` before reporting done. Exceptions where tests are optional — call them out explicitly in the response: code that's purely visual (XAML), tightly coupled to Win32 / kernel drivers (Interception, ViGEmBus, low-level hooks, the panic hotkey window), or where a real integration test would need admin + hardware. In those cases, prefer extracting the testable logic into a pure helper that *can* be tested. Never ship a new evaluator, parser, or non-trivial pure function without tests just because the user didn't explicitly ask. (Purely-visual code includes AXAML and the Avalonia control rendering layer.)
2121
- **Document every feature in `ai-docs/implementations/`**: After finishing any non-trivial feature or behavior change, write a concise Markdown write-down to `ai-docs/implementations/<FEATURE_NAME>.md` (UPPER_SNAKE_CASE filename). This is the persistent record future work depends on. Use this template:
2222

2323
```markdown
@@ -47,7 +47,7 @@ Past feature implementations are documented under [ai-docs/implementations/](ai-
4747
# Build everything
4848
dotnet build Mouse2Joy.sln
4949
50-
# Run the host (WPF exe). MUST be in an elevated shell — Interception needs admin to attach.
50+
# Run the host (Avalonia desktop exe). MUST be in an elevated shell — Interception needs admin to attach.
5151
dotnet run --project src/Mouse2Joy.App
5252
5353
# Run all tests
@@ -76,10 +76,10 @@ Build settings (from [Directory.Build.props](Directory.Build.props)): nullable e
7676

7777
## UI conventions
7878

79-
- **Tooltips wrap automatically and can be sectioned.** All `ToolTip` content goes through the implicit style + template selector defined in [App.xaml](src/Mouse2Joy.App/App.xaml). Two paths:
80-
- **Plain string** (`ToolTip="..."` / `.ToolTip = "..."`) — auto-wraps at 320px. Right for short, single-thought tooltips.
81-
- **`TooltipContent`** (in [src/Mouse2Joy.UI/Tooltips/](src/Mouse2Joy.UI/Tooltips/)) — three optional sections rendered as `Typical` (italic, dim, at the top, closest to the input), then `Description`, then `Advice`. Use this when a tooltip combines "what it does" + "when to change it" + a typical-range hint, so users see the at-a-glance answer first instead of buried at the end of a paragraph.
82-
- Don't reach for plain `\n\n` paragraph breaks inside a string when the content has a clear Typical / Advice split — use `TooltipContent`. See [TOOLTIP_AUTO_WRAP.md](ai-docs/implementations/TOOLTIP_AUTO_WRAP.md) for the full design.
79+
- **Tooltips wrap automatically and can be sectioned.** All tooltip content goes through the implicit `<Style Selector="ToolTip">` + `TooltipContent` DataTemplate defined in [App.axaml](src/Mouse2Joy.App/App.axaml). Authoring is via the `Tooltip.Build()` fluent builder (C#) or the `{tt:Tooltip ...}` markup extension (AXAML). Two paths:
80+
- **Plain string** (`ToolTip.Tip="..."` in AXAML / `ToolTip.SetTip(control, "...")` in C#) — auto-wraps at 320px. Right for short, single-thought tooltips.
81+
- **`Tooltip.Build().Typical(...).Description(...).Advice(...)`** (in [src/Mouse2Joy.UI/Tooltips/](src/Mouse2Joy.UI/Tooltips/)) — three optional sections rendered as `Typical` (italic, dim, at the top, closest to the input), then `Description`, then `Advice`. Use this when a tooltip combines "what it does" + "when to change it" + a typical-range hint, so users see the at-a-glance answer first instead of buried at the end of a paragraph.
82+
- Don't reach for plain `\n\n` paragraph breaks inside a string when the content has a clear Typical / Advice split — use the builder. See [TOOLTIP_AUTO_WRAP.md](ai-docs/implementations/TOOLTIP_AUTO_WRAP.md) and [PLAN_A_WINDOWS_AVALONIA.md](ai-docs/implementations/PLAN_A_WINDOWS_AVALONIA.md) for the design.
8383

8484
## Storage
8585

ai-docs/implementations/INITIALWORK.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ A short, pragmatic onboarding doc capturing the state of the project after the
44
v1 implementation session (2026-05-09). Treat this as a checkpoint, not a
55
finished spec.
66

7+
> **Stale-on-purpose notice.** This document captures the v1 WPF state. The
8+
> UI has since been ported to Avalonia 11 (big-bang cutover, 2026-05-21).
9+
> Read [PLAN_A_WINDOWS_AVALONIA.md](PLAN_A_WINDOWS_AVALONIA.md) for the
10+
> current UI shape; the references to WPF below are historical. The
11+
> Engine / Persistence / Input / VirtualPad architecture described here is
12+
> still accurate.
13+
714
## What it is
815

916
A Windows desktop app that emulates an Xbox 360 / XInput gamepad and lets the

0 commit comments

Comments
 (0)