7.3 KiB
7.3 KiB
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 referencesCSMic.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.
- WPF
High-Level Approach
- Port models and static data to the shared project.
- Wrap the interpreter in a service (
ICalculatorService
) that maintains state and exposes async APIs. - Move UI logic from code-behind to
MainViewModel
using commands and observable collections. - Recreate the WPF layout in Avalonia XAML (
MainView.axaml
), preserving behavior and styling. - Migrate icons/assets and wire up font usage across platforms.
- Polish interactions (auto-scroll, focus, virtualization) and verify cross‑platform.
Mapping WPF → Avalonia
- Events → Commands:
txtInput_KeyDown
(Enter) →SubmitCommand
withKeyBinding
on the inputTextBox
.btnFx_Click
→ToggleFunctionsCommand
.
- Collections:
List<T>
→ObservableCollection<T>
forHistory
andVariables
.
- Visibility:
- WPF
Visibility
→bool
properties (IsExpression
,IsFunctionsPanelOpen
) bound toIsVisible
or via a simpleBoolToGridLength
/BoolToVisibility
converter.
- WPF
- Icons:
- Keep
IconFont
glyphs and ship the TTF inAssets/Fonts
, or reduce to the required subset.
- Keep
- Scrolling:
- Use
ListBox
/ListView
and set selected index to last; optionally callScrollIntoView
from code-behind or via behavior.
- Use
Phased Plan
Phase 1: Models and Service
- Add
Models
insrc/AdvancedCalculator
:HistoryItem.cs
(copy shape from WPF)VariableItem.cs
(replaceVisibility
withbool IsExpression
andstring? ExpressionComputation
)FunctionDefinitionItem.cs
(rename to fix spelling; copyDefinedFunctions
static enumeration)
- Add
Services
:ICalculatorService
with methods like:Task<InterpretResult> InterpretAsync(string input)
CalculatorService
that holds a persistent interpreter instance fromCSMic.StandardLibrary
and returns:- Computed
Output
- Current variables (name, value, type)
- For equation variables: compute and store
ExpressionComputation
- Computed
Notes:
- The service isolates any API delta between WPF’s
csmic.InputInterpreter
and the currentCSMic.StandardLibrary
.
Phase 2: ViewModel
- Expand
MainViewModel
:- Properties:
InputText
,IsFunctionsPanelOpen
,ObservableCollection<HistoryItem> History
,ObservableCollection<VariableItem> Variables
. - Commands:
SubmitCommand
,ToggleFunctionsCommand
usingRelayCommand
/AsyncRelayCommand
. - On submit: call
CalculatorService.InterpretAsync(InputText)
, append toHistory
, rebuildVariables
, clearInputText
, and request UI scroll to last.
- Properties:
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 setDataTemplates
for item visuals (icon column + text stacks as in WPF XAML). - Input row: toggle
Button
bound toToggleFunctionsCommand
;TextBox
bound toInputText
withKeyBinding
Enter →SubmitCommand
.
Phase 4: Icons and Assets
- Copy
materialdesignicons-webfont.ttf
tosrc/AdvancedCalculator/Assets/Fonts
. - Update
AdvancedCalculator.csproj
to include the font as anAvaloniaResource
. - Reference the font in XAML via
FontFamily="avares://AdvancedCalculator/Assets/Fonts#Material Design Icons"
. - Optionally copy a slimmed
IconFont.cs
(only used glyphs) and bindTextBlock
to those glyph strings.
Phase 5: Interaction Polish
- Auto-scroll History on submit (select last item or call
ScrollIntoView
in code-behind forMainView
). - 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 toIsVisible
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
- Create
Models
andServices
scaffolding inAdvancedCalculator
and wireMainViewModel
. - Port the XAML layout and data templates into
MainView.axaml
. - Add icon font resources and verify rendering on Desktop.
- Smoke test on Browser and Android heads; adjust assets if needed.