Skip to content

Qtfred briefing map widget fixes - #7663

Open
MjnMixael wants to merge 5 commits into
scp-fs2open:masterfrom
MjnMixael:qtfred-briefing-map-rtt
Open

Qtfred briefing map widget fixes#7663
MjnMixael wants to merge 5 commits into
scp-fs2open:masterfrom
MjnMixael:qtfred-briefing-map-rtt

Conversation

@MjnMixael

Copy link
Copy Markdown
Contributor

This reworks the QtFRED Briefing Editor's map viewport, which previously embedded its render as a native QWindow that painted over the surrounding controls and refused to shrink inside the dialog's layout. The briefing is now rendered into an off-screen render target, read back into a QImage, and painted in an ordinary QWidget, so it participates in the layout and resizes/letterboxes cleanly in every direction while staying DPI-correct. It composes at the retail GR_1024 briefing map size (Brief_grid_coords[GR_1024], 888×371), what the game and Lua's ui.drawBriefingMap() default to, rather than the FRED-only $FRED Briefing window resolution setting that the game ignores, making the editor an unconditional WYSIWYG preview of the actual shipped briefing.

Clicking overlapping icons now cycles top-to-bottom through the stack on repeated clicks, so icons layered underneath others are finally selectable.

The letterbox/pillarbox bars get a subtle, theme-appropriate grey checkerboard matte so the map's true edges are clearly distinguishable from the empty space around them.

Finally, a small shared Theme::currentThemeIsDark() accessor was added for that and adopted by VariableDialog and the help browser in place of three separate ad-hoc dark-mode checks.

The briefing map widget rendered directly into the window at the widget's
size, which broke at display scaling > 100% (the briefing filled only the
top-left 1/dpr of the surface) and never matched the in-game framing or
icon proportions.

Render the briefing once into an offscreen render target at the reference
resolution (Briefing_window_resolution, retail default 888x371) using the
same setup the game uses, then letterbox-blit that finished image into the
widget. Scaling a canonical image means icon sizes, grid, line thickness
and text all scale together, so the editor view is a faithful WYSIWYG copy
of the briefing at any widget size or DPI.

Mouse picking and dragging now map input into reference-resolution space
via the blit rectangle. Selection brackets are drawn as a crisp window-
space overlay after the blit (editor UI, not part of the briefing image).
The briefing map used a native QWindow embedded via createWindowContainer.
Native child windows paint over their siblings and won't shrink inside a
constrained layout, so the map couldn't resize with the dialog without
overlapping the surrounding controls.

Now that the briefing renders into an off-screen render target, read the
finished frame back into a QImage and paint it (aspect-fit, letterboxed)
in an ordinary QWidget. Selection brackets are drawn as a QPainter overlay
and mouse input maps through the paint rectangle. The widget participates
in the layout like any other, so it clips and resizes cleanly.

Drop the map's aspect-ratio pin and minimum size (the image scales to any
size), leaving the left pane free to shrink so the dialog resizes in every
direction without clipping.
The briefing map was composed at Briefing_window_resolution (the "$FRED
Briefing window resolution" table setting). That setting is only consumed
by FRED2 (an icon-scale-vs-window-size hack) and is ignored by the game
and SCPUI, so honoring it in QtFRED could only make the editor preview
diverge from the shipped briefing.

Pin the compose/render resolution to Brief_grid_coords[GR_1024] instead --
the retail briefing map size, and what Lua's ui.drawBriefingMap() defaults
to -- so the editor is an unconditional WYSIWYG preview of the game and
follows retail automatically if that constant ever changes. BriefingViewport
getSize() is the single source of truth; renderFrame() reads it rather than
duplicating the lookup.
Clicking the briefing map always selected the top-most icon under the
cursor, so overlapping icons underneath were unreachable.

The hit-test now collects every icon under the cursor (top-most first).
A plain click advances to the next icon underneath the currently-selected
one, wrapping bottom to top, so repeated clicks roll through the whole
stack; if nothing in the stack is selected it takes the top-most.
Shift-click and empty-space clicks are unchanged.
Fill the briefing map's letterbox/pillarbox bars with a subtle,
theme-appropriate grey checkerboard so the (pure-black) map's edges are
clearly distinguishable from the surrounding matte. Two close grey shades
per theme keep it quiet; the tile is cached and rebuilt only when the
editor theme changes.

Add a shared Theme::currentThemeIsDark() that returns the effective dark
state from the applied theme preference (resolving System against the OS
scheme) and adopt it here, in VariableDialog's row tints, and in the help
browser's isDarkMode() in place of three separate palette-lightness checks.
@MjnMixael MjnMixael added the qtfred A feature or issue related to qtFred. label Jul 28, 2026
@github-project-automation github-project-automation Bot moved this to Work In Progress (PRs) in qtFRED2 Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

qtfred A feature or issue related to qtFred.

Projects

Status: Work In Progress (PRs)

Development

Successfully merging this pull request may close these issues.

1 participant