[Therion] Mapiah version 0.3.5 released: The Dental Nerve release

Rodrigo Severo rsev at pm.me
Thu Apr 9 15:02:23 CEST 2026


Hi,

I have just released Mapiah version 0.3.5 - The [Dental Nerve](https://xkcd.com/846/) release.

I believe the repositioning (and scaling and rotationg) background issue discussed recently in this list is properly dealt with on this release.

# Changelog

## 0.3.5 - 2026-04-09 - The [Dental Nerve](https://xkcd.com/846/) release
* Highlights:
* Background image editing was rebuilt into an Inkscape-style transform workflow with move, scale, rotate, flip, reset, keyboard nudging, and much better on-canvas handles, cursors, and undo/redo behavior.
* Drawing and editing got several new productivity tools: merge areas (`Ctrl+M`), join lines at coinciding extremities (`Ctrl+J`), convert line segments between straight and Bézier (`J` / `Shift+J`), and keyboard nudging for images, selected elements, and single-line points.
* Therion and editor settings were cleaned up with a dedicated Therion section, backward-compatible setting renames, configurable snap angle and nudge factor, optional extra debug logging, and better startup/run diagnostics.
* Many workflow polish fixes landed across startup, overlays, scrap/image panels, and image editing, making mode switches, dragging, handle feedback, and file-opening behavior more reliable.
* New features:
* Background image transform mode now supports direct flipping with `H` / `V`, negating `xScale` or `yScale` respectively for the active image, with matching state-context FAB buttons and undo support.
* Join lines at coinciding extremities (Ctrl+J).
* Change 'Split line' shortcut from Ctrl+Shift+P to Ctrl+P.
* Merge areas (Ctrl+M): when multiple selected areas or border lines belong to the same area set, Mapiah now merges their LTSA borders into the minimum number of closed output lines and replaces them with a single area referencing those merged borders.
* Convert line segments between straight and Bézier types with `J` / `Shift+J`, available both for selected whole lines in selection mode and for selected non-start line segments in single-line-edit mode, with matching state-context FAB actions and undo support. [request by Axel Hack]
* Renamed Therion settings from `Main_TherionExecutablePath` / `Main_TherionRunParameters` to `Therion_ExecutablePath` / `Therion_RunParameters`, added legacy settings-file read compatibility for the old names, moved them into a dedicated Therion settings section, and updated EN/PT help pages plus regression tests.
* Renamed the image-rotation snap setting to `TH2Edit_SnapAngle`, updated the default constant name to `mpDefaultSnapAngle`, changed the UI label to "Snap angle" / "Ângulo preferencial", and documented the setting in the EN/PT settings help pages.
* Added the `TH2Edit_NudgeFactor` setting as a persisted double with default `2.0`, including settings-page labels, keyboard nudge support for selected images and selected elements, and regression coverage for the default-value path.
* Added the `Therion_DebugLog1` boolean setting with default `false`, wired it to gate the extra Therion startup/run diagnostics introduced for troubleshooting, updated the settings/help text in EN/PT, and added regression coverage for the new setting and log-toggle behavior.
* Image move mode now supports keyboard nudging: `Arrow` moves the selected image by `TH2Edit_NudgeFactor`, `Shift+Arrow` by 10x that value, `Alt+Arrow` by 1 screen pixel, and `Alt+Shift+Arrow` by 10 screen pixels. Updated the EN/PT file-edit help pages and keyboard-shortcuts pages, with regression tests for all four shortcut variants.
* Selected elements in selection mode now support the same keyboard nudging shortcuts as image move mode: `Arrow` moves by `TH2Edit_NudgeFactor`, `Shift+Arrow` by 10x that value, `Alt+Arrow` by 1 screen pixel, and `Alt+Shift+Arrow` by 10 screen pixels. Updated the EN/PT file-edit help pages and keyboard-shortcuts pages, with regression tests for all four shortcut variants.
* Selected end/control points in single-line edit mode now support the same keyboard nudging shortcuts as image move mode: `Arrow` moves by `TH2Edit_NudgeFactor`, `Shift+Arrow` by 10x that value, `Alt+Arrow` by 1 screen pixel, and `Alt+Shift+Arrow` by 10 screen pixels. Updated the EN/PT file-edit help pages and keyboard-shortcuts pages, with regression tests for the end-point and control-point paths.
* Fixed bugs:
* Refactored Therion debug-log setting access so startup and run diagnostics now read the shared `isTherionDebugLog1Enabled` helper from `MPSettingsController`, removing duplicated per-class lookups and keeping the implicit `false` bool default path.
* Updated the EN/PT Run Therion help pages to refer to the renamed `Therion_RunParameters` setting instead of the legacy `Main_TherionRunParameters` name.
* Startup file handling is now serialized ahead of telemetry consent and update checking: when Mapiah is launched with TH2/THConfig command-line arguments or via file association, the initial open/run action now completes before any startup dialogs can appear, reducing dialog-order races during Windows Therion troubleshooting.
* Arrow-key image nudging now repeats correctly in all directions, including `ArrowUp`: the canvas key listener now forwards `KeyRepeatEvent`s and marks arrow keys as handled so Flutter focus/navigation does not steal them after the first move.
* Switching image transform mode by clicking the active image now updates the visible handles immediately instead of waiting for mouse movement. State changes into `movingElements` and single-line move states now also trigger immediate redraws so selection handles and end/control-point edit visuals refresh as soon as the mode changes.
* Settings page: boolean setting labels now use the same text style as the other setting labels, so "Show direction ticks on non-selected lines" no longer appears larger than the rest.
* The available-scraps and available-images overlays are now mutually exclusive: opening one closes the other first, so the two panels can no longer stay open at the same time.
* During background image edit mode, clicking elsewhere on the canvas now closes the available-images overlay and exits the image-edit state only for that outside-canvas dismissal path, while clicks on the image, its scale handles, or overlay buttons keep the edit state unchanged.
* Background images now have a reset action in the available-images list: the new button sits next to edit, restores translation/scale/rotation plus image and XVI-grid visibility to their default state, preserves the XVI root, and converts the reset result back to a `THXTherionImageInsertConfig`.
* Available scraps now lists scraps in the reverse order of TH2 storage so the top row matches the topmost scrap on the canvas, while drag-and-drop still reorders the stored TH2 scrap sequence correctly.
* Background image editing now uses one combined transform mode instead of separate move/scale states: the active image shows Inkscape-style black resize handles, dragging the image still moves it, dragging handles scales it with `Ctrl` aspect-ratio lock, `Shift` symmetric scaling, and `Alt` fine control, and the first true scale action converts legacy XTherion images to `MPImageInsertConfig` while preserving undo/redo and runtime image caches.
* Background image edit overlays now match Inkscape more closely by drawing the resize handles as outward black scale arrows and removing the brown editable-image border.
* Background image corner scale handles now keep a true 45-degree orientation relative to the image box instead of drifting with the image aspect ratio.
* Background image editing now has a first dedicated image-move workflow: each image row exposes an edit toggle before delete, entering move mode highlights the active image on the canvas with a mode label, dragging follows current snap targets from the image's top-left anchor, and the resulting move stays undoable for both legacy-converted and Mapiah-backed image inserts.
* Background image scale handles now react more reliably in the live canvas: resize drags are anchored to the true image edge instead of the offset visual handle center, and handle hit-testing accepts the painted handle footprint instead of only a small fixed box.
* Background image scale handles now show hover feedback on the live canvas: the hovered arrow keeps a slightly thicker black outline while its interior fills cyan, making the active resize handle easier to spot before dragging.
* Background image move/scale mode now updates the mouse cursor by hover target: the image body shows the move hand, scale handles show direction-matching resize cursors, empty canvas falls back to the normal arrow, and the diagonal corner cursors now match the visible handle directions.
* Background image move mode now supports Inkscape-style drag modifiers: `Alt` starts moving the selected image even when the drag begins away from the image body, `Ctrl` constrains the move to the dominant horizontal or vertical axis, and `Shift` temporarily disables snapping, with the modifiers working in combination.
* Selected element dragging now supports the same move modifiers as background images: `Alt` starts moving the current selection even when the drag begins away from the selected element, `Ctrl` constrains the move to the dominant horizontal or vertical axis, and `Shift` temporarily disables snapping.
* Single-line end/control point dragging now supports the same move modifiers as background images: `Alt` starts moving the current point selection even when the drag begins away from the selected point, `Ctrl` constrains the move to the dominant horizontal or vertical axis, and `Shift` temporarily disables snapping.
* Refactored move-modifier handling for selected elements, single-line end/control points, and background-image moves into one shared state-machine helper so the `Alt`/`Ctrl`/`Shift` drag behavior now lives in a single implementation.
* Alt+click scrap switching now also works when a file has exactly two scraps, so clicking inside the other scrap no longer gets blocked by the minimum-scrap guard.
* Background image editing now includes a dedicated rotate mode: clicking the selected image while already in move/scale mode toggles into rotation, the overlay switches to curved corner handles plus a pivot marker, rotation and pivot dragging are undoable through Mapiah image-insert commands, legacy XTherion image inserts are converted on first rotate entry, `Ctrl` snaps rotation to the configured angle, `Shift` keeps the opposite corner fixed, and XVI images with an `xviRoot` show a disabled non-draggable pivot.
* Background image rotation handles now keep the curved corner arrows proportionate and oriented correctly, instead of appearing squeezed and rotated away from the expected corner direction.
* Raster background images now default their rotation pivot to the image center until the user explicitly drags the pivot marker, and the chosen pivot position stays preserved through rotation undo/redo and Mapiah image metadata.
* While the available-images or available-scraps panel is open, the top-right `Snap` and `Remove` action buttons are now hidden so those management modes no longer show unrelated canvas actions, and the change-image/change-scrap overlay visibility now updates reactively enough for full widget coverage of that toolbar behavior.
* Raster background images are no longer painted upside down: the bitmap is now flipped back inside its existing transform, keeping the image box, handles, and interaction geometry unchanged.
* Available images now lists backgrounds in the reverse order of TH2 storage so the top row matches the topmost image on the canvas, while drag-and-drop still reorders the stored TH2 image sequence correctly.
* `MPXVIImageInsertConfig` now preserves `isGridVisible` through `toMap()`/`fromMap()`, so Mapiah-side XVI image metadata no longer drops the grid-visibility state when cloned or deserialized.
* Scrap `-stations` now follows Therion's single-argument rule: a single station may stay bare, quoted or bracketed station lists are split on spaces, and Mapiah always writes multiple stations back as a bracketed list.
* Merge areas: selected LTSA borders are now always treated as closed during merge, split at all crossings (including internal crossings and self-crossing Bézier segments), and validated so leftover segments are discarded only when they are strictly internal to the chosen outer boundary.
* Add area by clicking existing lines: when clicked lines had no THID yet, only the last clicked line ended up referenced by the new area. The add-area flow now wraps the area creation command only on the first clicked border and keeps later clicks as pure border additions, so all clicked lines remain attached to the area.
* Select all (Ctrl+A) now works while the editor is in the "add line border to area" state, so you can leave that mode by selecting all elements without cancelling the flow first.
* Renamed the "Node edit" tool/button to "Node/line edit" to reflect that the same mode is used to edit both line nodes and line-level geometry.
* Default options overlay no longer offers the point `-name` option, and its hidden-option exclusions are now maintained in one static list in the option edit controller.
* Scrap `-stations` options now preserve bracketed station lists in memory, so fixtures like `[1.35 1.36 1.37]` are parsed into individual stations instead of being dropped or collapsed into one string. [reported by Axel Hack]
* Internal links inside help pages now jump to the correct section within the same document, including headings with accents such as `Bézier curve line segments`. [reported by Axel Hack]
* Point stations now remember the last `-name` that was set, auto-assign the next unused station name within the active scrap when creating a station point or converting a point to type `station`, and keep the type change and auto-name assignment as two separate undo steps for point-to-station conversions. [request by Axel Hack]
* The `-extend`, `-from`, and `-name` option editor now splits station references into `station name` and optional `survey` fields, validates them with Therion keyword rules, and shows the encoded `@` separator explicitly in the UI.
* Removed the point `-extend` option from parsing and editing because Therion does not support it.
* Fixed flaky UI test `t3202_ui_open_file_then_new_file_test`: window-title updates now go through a safe async helper that ignores missing `window_size` plugin registrations in widget-test and unsupported-platform environments, avoiding uncaught plugin-channel failures from the package's `void async` API.
* Point stations now expose the `-from` option in the option list, matching Therion's support for choosing the origin branch for station points in extended-elevation scraps.
* Normalized freshly written `xth_me_image_insert` entries so simple `yy` values are emitted as bare numbers like `28` instead of single-value braces like `{28}`, while keeping wrapped output for composite `yy xviRoot` payloads.
* Infrastructure maintenance:
* Added Therion startup/run diagnostics for Windows command-line troubleshooting: Mapiah now logs the raw startup arguments, parsed launch mode, current directory, run attempt number, resolved THConfig path, process working directory, configured Therion executable path, and configured run parameters to help compare the initial automatic run with `Rerun Therion`.
* Moved the available-images reset workflow out of `MPAvailableImagesWidget` and into `TH2FileEditMoveScaleRotateElementController`, keeping the widget as a thin UI trigger and centralizing image-transform business logic with the other move/scale/rotate actions.
* Replaced remaining image-transform helper magic numbers with shared constants, including handle sizing, overlay border width, and named handle-group sets used by the resize-axis logic.
* Extracted the pure image-rotation preview calculations out of `MPTH2FileEditStateImageRotate` into `mp_image_transform_aux.dart`, keeping the state focused on interaction flow while shared transform math now lives beside the other image geometry helpers.
* Updated EN/PT image-edit help and keyboard-shortcut pages for the new transform workflow, and brought both TH2 edit help-page indexes back in sync with their actual section headings.
* Extracted TH2FileEditMoveScaleRotateElementController: moved move, scale, and rotate-related element/image workflow code out of the generic element-edit controller so transform logic now lives in its own MobX store, instantiated directly by TH2FileEditController.
* Completed Phase 6 state-machine preparation for Mapiah image inserts: the editor now has dedicated `imageScale`, `imageMove`, and `imageRotate` states, image-edit controller entry points lazily convert legacy XTherion images before entering those states, and the state controller now tracks which image each MP-only image state owns for future transform actions.
* Refined the shared image runtime contract so both `THXTherionImageInsertConfig` and `MPImageInsertConfig` expose their common base placement APIs through the same mixin, removing the remaining image-family switches from move commands, image state handling, bounding-box aggregation, and generic image collection paths while keeping type-specific branching only where XTherion and Mapiah behavior still genuinely differs.
* Completed Phase 5 of the Mapiah image-insert migration: image add/remove command paths and controller removal now accept both legacy XTherion and Mapiah-backed image entries, the shared command/controller APIs were renamed to generic image-insert terminology, and MP-only image transform preparation lazily converts legacy XTherion image inserts into `MPImageInsertConfig` with stable MPIDs, preserved image semantics, and undo/redo coverage.
* Renamed the underlying image-insert command enum values from XTherion-specific names to generic `addImageInsertConfig` / `removeImageInsertConfig`, keeping the command classes, command factory wiring, and undo-text mapping aligned with the mixed-image runtime model.
* Split the legacy XTherion image model into `THXVIXTherionImageInsertConfig` and `THRasterXTherionImageInsertConfig`, keeping the old `THXTherionImageInsertConfig` factory-style entry points while moving raster/XVI-specific runtime state into the matching subclasses and preserving legacy XTherion writer output.
* Aligned the legacy XTherion image codec with the Mapiah image model by adding a `format` discriminator to `THXTherionImageInsertConfig`, moving `xviRoot` fully behind the XVI runtime interface, and routing `fromMap()` by subtype before reading XVI-only fields.
* Finished folding the remaining runtime `isXVI` branches into the new image adapters, so the available-images UI and the legacy XTherion runtime helpers now follow the same `asXVIImage`/`asRasterImage` path as the rest of the mixed-image runtime flow.
* Refined the runtime image abstraction for mixed XTherion/Mapiah image entries by adding dedicated raster/XVI runtime interfaces plus `asRasterImage`/`asXVIImage` adapters, removing the remaining format switches from image widgets and related controller paths.
* Completed Phase 4 runtime preparation for the new Mapiah image-insert model: runtime image loading/rendering paths now accept both legacy `THXTherionImageInsertConfig` and Mapiah-backed image entries, while raster/XVI loading stays in the descendant models and regression coverage now includes mixed-image runtime access plus XVI runtime cache/grid-visibility syncing.
* Completed Phase 3 writer integration for the new Mapiah image-insert metadata model: `##MAPIAH## image_insert_v1` entries now serialize in the same top-level config block as XTherion settings and image inserts, preserving the file order among mixed config entries, with regression coverage for the shared block ordering.
* Added Phase 2 parser regression coverage for the new Mapiah image-insert metadata model, including explicit tests for XTherion image inserts, Mapiah raster/XVI entries, malformed `##MAPIAH## image_insert_v1` lines, and mixed files containing both persisted image styles. Malformed Mapiah image inserts are now reported as parser errors instead of aborting file parsing.
* Simplified the main `MPImageInsertConfig` raster/XVI constructors to take plain `double` values with defaults for transform fields, while keeping the string-based parsing path in `MPImageInsertConfig.fromString()` and extending regression coverage for both constructor styles.
* Added Phase 1 of the new Mapiah image-insert metadata model: `MPImageInsertConfig` base/XVI/raster classes, versioned `##MAPIAH## image_insert_v1` parser/writer support, and regression tests for codec and TH2 round-tripping.
* Added regression coverage for line-segment type conversion, including mixed lines, same-type no-op conversions, multi-line selection conversion, keyboard shortcuts (`J` / `Shift+J`), and undo restoration. Updated EN/PT help pages and keyboard-shortcuts documentation for the new actions.
* Added `MPElementEditAux.getNextStationName()` plus unit tests covering station-name increment rules for numeric, alphabetic, separator-terminated, and survey-suffixed names.
* Added merge-area regression tests covering crossing mixed straight/Bézier border cases, including open borders that must be auto-closed before merging and a self-crossing Bézier border case that must be treated as an intersection during merge.
* TH2FileEditSplitMergeController now routes its snackbar messages through the local `_showSnackbar()` helper instead of repeating the same `ScaffoldMessenger` boilerplate at each call site.
* Updated TH2 file edit help pages (EN/PT) to document the join-lines-at-coinciding-extremities and merge-areas actions more accurately, including index entries and current selection/merge behavior.
* Renamed top-level test files to analyzer-friendly lowercase underscore names (with a `t` prefix before numeric ordering keys), removing the `file_names` lint noise from `flutter analyze`.
* Cleaned up the remaining analyzer infos by fixing doc comments, removing redundant source getters that duplicated MobX `@readonly` generated getters, and dropping a shadowing `snapController` field plus two unnecessary test imports so `flutter analyze` now reports no issues.
* Split the historical 0.2 and 0.3 TODO sections out of `TODO.md` into dedicated `TODO-0.2.md` and `TODO-0.3.md` files, leaving the main TODO focused on current and future roadmap items.
* Fixing ext_keyword parsing.
* Added regression coverage for controller-driven station-name generation, active-scrap station-name collision skipping, automatic station naming on point creation, and the separate undo steps when converting a point into a station.
* Added parser regression coverage for point station names written as `-station`, complementing the existing `-name` read tests while keeping normalized output on `-station`. * Renamed `THStationNameCommandOption`'s stored parameter from `reference` to `name` and updated station-name parser, UI, controller, and regression-test call sites to match.

Regards,

Rodrigo Severo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.speleo.sk/pipermail/therion/attachments/20260409/e98a5da9/attachment-0001.htm>


More information about the Therion mailing list