docs: add migration plan for WPF→Avalonia port
This commit is contained in:
parent
e176488f5c
commit
22f9043e50
1 changed files with 148 additions and 0 deletions
148
docs/migration-plan.md
Normal file
148
docs/migration-plan.md
Normal file
|
@ -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<T>` → `ObservableCollection<T>` 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<InterpretResult> 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<HistoryItem> History`, `ObservableCollection<VariableItem> 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.
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue