You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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>
Copy file name to clipboardExpand all lines: CLAUDE.md
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
4
4
5
5
## What this project is
6
6
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.)
8
8
9
9
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.
10
10
@@ -17,7 +17,7 @@ Past feature implementations are documented under [ai-docs/implementations/](ai-
17
17
-**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.
18
18
-**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.
19
19
-**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.)
21
21
-**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:
22
22
23
23
```markdown
@@ -47,7 +47,7 @@ Past feature implementations are documented under [ai-docs/implementations/](ai-
47
47
# Build everything
48
48
dotnet build Mouse2Joy.sln
49
49
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.
51
51
dotnet run --project src/Mouse2Joy.App
52
52
53
53
# Run all tests
@@ -76,10 +76,10 @@ Build settings (from [Directory.Build.props](Directory.Build.props)): nullable e
76
76
77
77
## UI conventions
78
78
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.
0 commit comments