a56070fe97
1 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 3c80f93203 |
Import map screenshots into the board, and edit entities from the map
The existing clipboard button now routes images: a map-table shot goes to the vision pipeline, anything else to the text OCR path as before. The decision runs in a worker, since even the cheap pre-filter costs ~0.3s and solve() takes 10-20s. solve() rejecting counts as "not a map" and falls through to OCR, because it is the reliable verdict (0 false positives over 122 text screenshots) where the pre-filter lets ~6% through; reporting a failure there would mean a text screenshot never got read at all. Grid first, units second. The one modal confirms or fixes the geometry only: the screenshot with the reconstructed lattice drawn over it, plus four draggable handles on one cell's corners. Four corners pin a homography exactly (8 DOF, 2 equations each), and dragging any of them refits the whole grid live. Detection deliberately does not run until this is accepted -- every unit position is expressed in grid coordinates, so detecting against a grid about to be dragged would only be thrown away. Once accepted the screenshot is rectified into board space and drawn as the map's backdrop. Pre-warping is what makes it drawable at all: cairo has no projective transform, but a rectified image places with a plain scale and translate. Detected units then appear as proposals ON the map, drawn hollow -- the same shape the map already uses for "this might be where it is", which is exactly what a proposal is. Clicking one offers accept (with the detected type or a corrected one) or reject; the header gains accept-all and remove-screenshot, and removing the screenshot drops every proposal never accepted, since they were only ever readings of it. Separately, right-clicking any entity now opens an edit menu: change type, change id, change position, delete. Which actions appear follows what the entity actually has -- only Target/Ally carry a TargetType, Spotter's id is an int, and the Nest is singular so it cannot be deleted. Changing an existing target's type or id had no UI at all before this. Also fixes warp_to_map, which composed only the lattice homography and dropped the discrete (si,sj,du,dv) mapping that pins lattice indices to named cells, so every automatically solved screenshot landed in the wrong place. It happened to test fine because manual solutions have an identity mapping. While there, the same routine had an off-by-one for a negative axis sign (si*u+du runs from col+1 down to col across a cell, so floor() named the neighbour); both now go through one shared GridSolution.grid_of. Verified end to end through the real widgets on a fixture: grid phase yields no proposals, four handles, a drag refits and still names cells correctly, reset restores, a degenerate drag survives, accept warps to a 2000x1000 overlay, detection then yields proposals that hit-test, accept and reject correctly, and removing the screenshot keeps accepted units only. Completes the FEnigma rename in app.py (APP_ID, window title, class). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |