Regions

{# Only ever populated from a real file the user picked. #}
These ROIs belong to a different image.
Nothing is shown, and editing is off, so regions cannot be attached to the wrong image. Export them to keep them.
Changed in another session.
Someone -- probably another tab -- saved since this one loaded.
{# The three that MAKE a shape start disabled, because until the store has loaded this panel does not yet know whether there is a category to put one in -- and offering a live pen that refuses every stroke is worse than one that visibly waits. The first render decides. #}
Hold Space to pan. The wheel always zooms.
{# A project starts with none: the names are the user's to choose, so the panel asks rather than shipping an "Uncategorized" nobody picked. #}
Name what you are about to outline — Tumor, Stroma, Necrosis — then draw.
{# Deliberately not a
. This markup is server-rendered and on screen before the plugin's scripts have finished loading, so for a moment there is nobody to call preventDefault -- and an Enter in that window submits natively and NAVIGATES THE PAGE, taking the panel and anything unsaved with it. No form, no default action to suppress. #}
{# Compact on purpose. This block appears and disappears as regions are clicked, right under the category list the user is also working in, so every row it costs is a row the list loses. The two things worth reading -- what it is called and what it is -- sit on one line; the two things worth doing are icons on the heading. #}
{# Both padlocks ship, and CSS picks which one shows. Swapping the class in JS does not work here: FontAwesome's SVG mode has already replaced these spans with elements by the time anything is selected, so there is no span left to rewrite -- and rewriting the svg's class strips what FA put there. The `fa-*` class survives onto the svg, which is what the rule in roi.css hangs on. #}
{# The swatch is a sibling sitting over the select's left padding: a native
{# One of these two, never both. A project with a native destination gets the file write; a CSV or image-only project gets the download in the same place and at the same size, because "how do I keep this?" is the same question either way. The name field is a step in the save, not part of the resting panel: the first click on the button opens it with the name already filled in, and the second click writes. Most saves are the same name as last time, so standing the field up permanently would spend three rows of a 320px column on a decision almost nobody is making. Enter writes, Escape and the x close it. #}
{# The two ways out of this panel, side by side, because they are the same size of decision: one keeps the shapes, the other puts them on the rows. Stacked they read as a sequence -- save, THEN map -- which is not true; either can be done without the other, in either order. Exactly one save button is ever shown, so the row is two buttons wide whatever the project is. Both say "Save": which file it lands in is what the hint above and the tooltip are for, and a button label is not the place to name a storage format. #}
{# Only for a project that has cells. The save buttons write the polygons somewhere; this writes onto the rows, which is a different thing to want and is meaningless without a table -- so it is absent rather than disabled for a project that is nothing but an image. #} {# The one control on this panel whose result a user cannot see before pressing it -- it writes onto their own rows, and the rules it writes by (overlaps, image scope, what a blank means) do not fit in a line of hint text under a button. They used to be attempted in one, which said only what the columns were called. #}
{# Opened by the ? above. Plain : it is modal, Escape closes it and focus is handled by the browser, none of which is worth reimplementing. The prose is static -- it is the same for every project -- except for the one line naming the columns, which follows the save name. #}

Map to cells

Assigns each cell to the ROI(s) that contain it and writes the annotations directly to the data table.

For the current save name, Plexora creates:

{# The only two values in here that are about THIS project. Written by openMapInfo() from the save name, not hard-coded: a fixed pair of names would be wrong for every user who saved under their own, and this dialog exists to tell them what they are about to get. #}
  • rois_category — ROI category, e.g. Tumour
  • rois_name — specific ROI name, e.g. Tumour 1

If a cell falls within overlapping ROIs, values are joined with _. Duplicate categories are collapsed, while distinct ROI names are retained.

Cells outside all ROIs are left blank. Only cells belonging to the currently displayed image are evaluated; cells from other images are not modified.

Existing columns are not overwritten automatically. If they already exist, Plexora prompts you to replace them or use a new save name.

Note: Map to cells saves ROI assignments to individual cells. The separate Save function saves the ROI shapes themselves.

Saved