From 22f9043e50d7fedbb6172db7204b09a02dd0ac76 Mon Sep 17 00:00:00 2001 From: wagesj45 Date: Tue, 26 Aug 2025 01:33:50 -0500 Subject: [PATCH] =?UTF-8?q?docs:=20add=20migration=20plan=20for=20WPF?= =?UTF-8?q?=E2=86=92Avalonia=20port?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/migration-plan.md | 148 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 docs/migration-plan.md diff --git a/docs/migration-plan.md b/docs/migration-plan.md new file mode 100644 index 0000000..5521f3b --- /dev/null +++ b/docs/migration-plan.md @@ -0,0 +1,148 @@ +# Advanced Calculator Migration Plan + +Migration target: .NET 4.7 WPF (src.4.7) → Avalonia on .NET 8 (src) with Desktop, Android, and Browser heads. + +## Objectives + +- Preserve existing features and UX while adopting MVVM and cross‑platform patterns. +- Encapsulate the expression engine behind a service to isolate API differences. +- Maintain a single shared UI project for all heads; avoid platform‑specific code. + +## Repo Overview + +- New solution (src): + - `AdvancedCalculator` (shared UI, Avalonia 11, net8.0) + - Heads: `AdvancedCalculator.Desktop` (net8.0), `AdvancedCalculator.Android` (net8.0-android), `AdvancedCalculator.Browser` (net8.0-browser) + - Uses `CommunityToolkit.Mvvm` and already references `CSMic.StandardLibrary`. +- Old project (src.4.7): + - WPF `MainWindow` with variables, function definitions panel, history, and input with Enter submit. + - Icons via Material Design Icons TTF + `IconFont.cs` glyph map. + - Models: `HistoryItem`, `VariableItem`, `FunctionDefinitonItem`. + - Interpreter: `csmic.InputInterpreter` in code-behind. + +## High-Level Approach + +1) Port models and static data to the shared project. +2) Wrap the interpreter in a service (`ICalculatorService`) that maintains state and exposes async APIs. +3) Move UI logic from code-behind to `MainViewModel` using commands and observable collections. +4) Recreate the WPF layout in Avalonia XAML (`MainView.axaml`), preserving behavior and styling. +5) Migrate icons/assets and wire up font usage across platforms. +6) Polish interactions (auto-scroll, focus, virtualization) and verify cross‑platform. + +## Mapping WPF → Avalonia + +- Events → Commands: + - `txtInput_KeyDown` (Enter) → `SubmitCommand` with `KeyBinding` on the input `TextBox`. + - `btnFx_Click` → `ToggleFunctionsCommand`. +- Collections: + - `List` → `ObservableCollection` for `History` and `Variables`. +- Visibility: + - WPF `Visibility` → `bool` properties (`IsExpression`, `IsFunctionsPanelOpen`) bound to `IsVisible` or via a simple `BoolToGridLength`/`BoolToVisibility` converter. +- Icons: + - Keep `IconFont` glyphs and ship the TTF in `Assets/Fonts`, or reduce to the required subset. +- Scrolling: + - Use `ListBox`/`ListView` and set selected index to last; optionally call `ScrollIntoView` from code-behind or via behavior. + +## Phased Plan + +### Phase 1: Models and Service + +- Add `Models` in `src/AdvancedCalculator`: + - `HistoryItem.cs` (copy shape from WPF) + - `VariableItem.cs` (replace `Visibility` with `bool IsExpression` and `string? ExpressionComputation`) + - `FunctionDefinitionItem.cs` (rename to fix spelling; copy `DefinedFunctions` static enumeration) +- Add `Services`: + - `ICalculatorService` with methods like: + - `Task InterpretAsync(string input)` + - `CalculatorService` that holds a persistent interpreter instance from `CSMic.StandardLibrary` and returns: + - Computed `Output` + - Current variables (name, value, type) + - For equation variables: compute and store `ExpressionComputation` + +Notes: +- The service isolates any API delta between WPF’s `csmic.InputInterpreter` and the current `CSMic.StandardLibrary`. + +### Phase 2: ViewModel + +- Expand `MainViewModel`: + - Properties: `InputText`, `IsFunctionsPanelOpen`, `ObservableCollection History`, `ObservableCollection Variables`. + - Commands: `SubmitCommand`, `ToggleFunctionsCommand` using `RelayCommand`/`AsyncRelayCommand`. + - On submit: call `CalculatorService.InterpretAsync(InputText)`, append to `History`, rebuild `Variables`, clear `InputText`, and request UI scroll to last. + +### Phase 3: UI Layout + +- Update `Views/MainView.axaml` to mirror WPF layout: + - Grid with two columns; left hosts Variables (row 0) + Functions panel (row 1, height toggled), right hosts History (row 0) + input row (row 1). + - Add `GridSplitter` between columns. + - Bind `ItemsSource` for lists and set `DataTemplates` for item visuals (icon column + text stacks as in WPF XAML). + - Input row: toggle `Button` bound to `ToggleFunctionsCommand`; `TextBox` bound to `InputText` with `KeyBinding` Enter → `SubmitCommand`. + +### Phase 4: Icons and Assets + +- Copy `materialdesignicons-webfont.ttf` to `src/AdvancedCalculator/Assets/Fonts`. +- Update `AdvancedCalculator.csproj` to include the font as an `AvaloniaResource`. +- Reference the font in XAML via `FontFamily="avares://AdvancedCalculator/Assets/Fonts#Material Design Icons"`. +- Optionally copy a slimmed `IconFont.cs` (only used glyphs) and bind `TextBlock` to those glyph strings. + +### Phase 5: Interaction Polish + +- Auto-scroll History on submit (select last item or call `ScrollIntoView` in code-behind for `MainView`). +- Ensure lists use virtualization (default templates are virtualized; confirm template choice preserves it). +- Focus management: focus input `TextBox` after submit. + +### Phase 6: Cross-Platform Verification + +- Desktop: smoke test. +- Browser: ensure font loads correctly as an Avalonia resource; verify icons render and inputs submit with Enter. +- Android: verify IME enter (Done/Go) triggers submit; confirm font packaged and renders. + +### Phase 7: Cleanup and Docs + +- Remove placeholder greeting and unused templates. +- Update `README.md` with build/run instructions per target, plus basic usage. +- (Optional) Add a few unit tests for `CalculatorService` if practical without heavy harness. + +## File-Level Checklist + +- Add: + - `src/AdvancedCalculator/Models/HistoryItem.cs` + - `src/AdvancedCalculator/Models/VariableItem.cs` + - `src/AdvancedCalculator/Models/FunctionDefinitionItem.cs` + - `src/AdvancedCalculator/Services/ICalculatorService.cs` + - `src/AdvancedCalculator/Services/CalculatorService.cs` + - `src/AdvancedCalculator/Assets/Fonts/materialdesignicons-webfont.ttf` +- Update: + - `src/AdvancedCalculator/AdvancedCalculator.csproj` (Avalonia resources for Fonts) + - `src/AdvancedCalculator/ViewModels/MainViewModel.cs` (properties + commands) + - `src/AdvancedCalculator/Views/MainView.axaml` (+ optional code-behind for scroll/focus) + +## Risks & Mitigations + +- Interpreter API changes: contained by `CalculatorService`; adjust adapter logic without touching UI. +- Font payload size (Browser, Android): if large, switch to a reduced subset or alternate icon source. +- Visibility semantics: prefer `bool` bindings to `IsVisible` to avoid platform enums. +- WebAssembly resource loading: verify `avares://` URIs and that the font is included as a resource. + +## Acceptance Criteria + +- Entering an expression appends to History and updates Variables. +- Variables defined as equations show computed `ExpressionComputation` and a distinct icon. +- Function definitions panel toggles and displays static help list. +- Icons render on Desktop and Browser; Android renders acceptable icons. +- Solution builds and runs across Desktop, Browser, and Android heads. + +## Timeline Estimate + +- Phase 1–2 (Models, Service, VM): 0.5–1 day +- Phase 3 (UI layout and bindings): 1–1.5 days +- Phase 4–5 (Assets, polish): 0.5 day +- Phase 6 (Cross‑platform checks): 0.5–1 day +- Total: ~2.5–4 days including docs and smoke tests + +## Next Actions + +1) Create `Models` and `Services` scaffolding in `AdvancedCalculator` and wire `MainViewModel`. +2) Port the XAML layout and data templates into `MainView.axaml`. +3) Add icon font resources and verify rendering on Desktop. +4) Smoke test on Browser and Android heads; adjust assets if needed. +