Skip to content

GUI 2.4.3

Choose a tag to compare

@mpenafiel mpenafiel released this 14 May 22:51
· 25 commits to main since this release

Changed

  • DelayTimerToggle scaled up ~25% for touchscreen legibility: button
    hit area 32×32 → 40×40, icon canvas 24×24 → 30×30. Geometries stay
    authored against the 24-viewport — the Path now uses
    Stretch="Uniform" with explicit Width="30" Height="30" so the
    existing clock-face / arc constants render at the new size and the
    stroke renders proportionally bolder. iconText font size 10 → 13.
    The "Timer" caption in UIPrelimSettings (Step 1 + Step 4) now
    carries FontSize="14" FontWeight="SemiBold" with a 4 px top margin
    so it reads at glance distance.
  • UIReport ScrollViewer gains PanningMode="VerticalOnly" so the
    report body pans by finger drag, not just mouse wheel.
  • StepCardNavigator no longer enables IsManipulationEnabled on its
    root grid or wires the Manipulation* event pipeline. Touch swipes
    still work via Windows' touch→mouse promotion against the existing
    Swipe_Mouse* handlers; removing the manipulation container unblocks
    taps on descendant controls inside a StepCard that don't have their
    own touch handlers (the SegmentedToggle RadioButtons and the inner
    Button in DelayTimerToggle), which previously had their touches
    captured by the manipulation pipeline.
  • UpdateWindow release notes now show the markdown changelog body
    instead of "Release notes: <url>". Added
    GHReleaseTracker.GetReleaseByTagAsync(tag) and a regex-parser in
    MainApp that extracts owner/repo/tag from the manifest entry's
    notesUrl (HTML release-page URL), then fetches the release body
    anonymously through the GitHub Releases API. Falls back to the
    previous "Release notes: " line on parse/fetch failure (rate
    limit, offline, schema drift). One launch-time fetch fits well
    inside the 60 req/hr anonymous rate limit.
  • Removed the redundant sp.WriteCmd("BK") in UIEvaluation.btnMeasure_Click
    for AROM mode. Check_CurrentUI already sets the motor to RL when
    AROM is selected, and after 0a7a5cf the in-line BK was actively
    wrong for the page's current convention.

Fixed

  • Wrapper buttons (ImageButton, ActionButton, IconButton,
    IconToggleButton) no longer double-fire on touch. Touch hardware
    that emits parallel WM_LBUTTON alongside WM_TOUCH (common on
    Windows touchscreens) caused both the manual click raised from
    TouchUp AND the inner Button.Click from the mouse-promoted
    message to fire, raising the outer Click event twice. On the eval
    Start/Stop ImageButton this flipped IsPressed back to its
    starting value, so the icon/text never swapped on touch even though
    the underlying handler ran. Each wrapper now guards its inner click
    handler so the mouse-promoted call following a touch is suppressed
    (cleared on the next Input-priority dispatch). IconToggleButton
    additionally hooks PreviewMouseLeftButtonUp so ButtonBase.OnClick
    doesn't toggle IsChecked a second time after the touch path has
    manually swapped it; the touch handler now sets IsChecked before
    raising Toggle so subscribers reading EmgPlotBtn.IsChecked /
    ModePlotBtn.IsChecked see the new state.
  • UICoverFlow.Load_GameList crashed with NullReferenceException on
    the foreach (var game in gameLibrary) when the user added or
    deleted a game from UIGameLib on a fresh launch — UICoverFlow's
    gameLibrary field is only wired in Load_GameProtocol, which
    doesn't run until the user first enters the Game task. Null-guard
    Refresh_GameList and Load_GameList; keep IsChanged = true when
    bailing so the pending refresh resolves once Load_GameLibrary
    eventually runs.
  • UIGameLib.btnAddGame_Click / btnDeleteGame_Click could fire
    before Initialize_Variables wired mainApp, NRE-ing on
    mainApp.uiGames.IsChanged = true. Adds EnsureReady() (refreshes
    the local MainApp.GameLibrary reference and null-checks mainApp)
    at the top of every mutation handler; toggleDisplay_Changed
    null-guards mainApp directly since it fires from the per-item
    IsChecked binding during initial materialization, before
    Initialize_Gamelist runs. btnDeleteGame_Click also captures the
    target GameInfo from the row's Tag up front instead of
    round-tripping through lstGames.SelectedItem — the
    dispatcher-pumping MessageBox.Show could otherwise null out the
    selection mid-handler.
  • UIGameLib could operate on a stale MainApp.GameLibrary
    reference: Initialize_Settings reassigns the static field to a new
    ObservableCollection AFTER uiGameLib_Loaded has captured the
    original empty one. Subsequent adds/removes mutated the orphan
    collection while Save_GameLibrary persisted the live one,
    silently losing entries on disk. SyncGameLibraryRef() re-fetches
    the current static reference and rebinds lstGames.ItemsSource
    whenever the instance changes.
  • AR01BleClient.WriteToCsv crashed with ArgumentNullException when
    the data-saving state was toggled quickly enough that evalTrialsFile
    / prelimSummaryFile was still null (or had been cleared by a
    Stop/disconnect) at the moment a record was queued. The existing
    catch (IOException) didn't cover argument exceptions, so the
    throw escaped and killed the app. Early-out with a BleLogger line
    when fileName is null/empty or the records collection is null;
    also catches UnauthorizedAccessException so a read-only attribute
    or AV lock on the data file is never session-fatal.