Skip to content

feat(web): add right-click context menu and search/navigation to Web GUI#10946

Open
jorge-ferreira-pii wants to merge 1 commit into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:feature-WebGUI-contextmenu-search-navigation
Open

feat(web): add right-click context menu and search/navigation to Web GUI#10946
jorge-ferreira-pii wants to merge 1 commit into
The-OpenROAD-Project:masterfrom
The-OpenROAD-Project-staging:feature-WebGUI-contextmenu-search-navigation

Conversation

@jorge-ferreira-pii

Copy link
Copy Markdown
Contributor

Addresses a portion of #10619

2.7 Right-click context menu

Feature GUI Web Status
Select → Connected (insts / output / input / all nets / buffer trees) LayoutViewer::selectHighlightConnectedInst/Nets/BufferTreesGui::selectHighlightConnected* right-click first selects the object under the cursor, then a context_action (select_connected_insts / select_connected_output+input nets / select_connected_nets / select_connected_buffer_trees); the server handleContextAction builds the set once via computeConnectedSet. The buffer-tree walk can toggle whether inverters are followed, and the number of objects added is surfaced as a toast ❌ → ✅
Menu enabled by selection type LayoutViewer::updateContextMenuItems() + Gui::anyObjectInSet() disabling menu_actions_[kSelect*Act] every selection response is tagged with sel_has_inst / sel_has_net (addSelectionTypeFlags); the menu greys out items that don't apply — e.g. over a net only Connected Insts is enabled, and both submenus are disabled with nothing selected ❌ → ✅
Highlight → same + color groups connected-* functions with a highlight_group, colored by Painter::kHighlight the Highlight submenu issues the same context_actions with a group index and a 4×4 color-picker; overlay shapes (rects and flight lines for unrouted nets) reuse the 2.6 highlight pipeline (16 groups) ❌ → ✅
View → Zoom In / Out / Fit LayoutViewer::zoomIn / zoomOut, Gui::zoomTo the View submenu is dropped from the context menu; Fit becomes an on-canvas L.Control next to Leaflet's built-in zoom ± buttons (plus the f shortcut), where users expect it ❌ → ✅
Save (visible / entire) Gui::saveImage / gui::save_image (server-side render) client-side WYSIWYG composite (capture.js) of the displayed scene — base tiles + heatmap + highlight/selection overlay + ruler/label SVG panes — drawn onto a canvas via per-tile getBoundingClientRect (correct under fractional zoom); Visible captures the viewport, Entire fits the whole design, waits for the tiles to settle, captures, then restores the previous view ❌ → ✅
Clear (selections / focus nets / route guides / rulers / all) Gui::clearSelections / clearHighlights / clearRulers context_action clear_selections / clear_focus_nets / clear_route_guides / clear_all; rulers are cleared client-side ❌ → ✅

2.8 Search & navigation

Feature GUI Web Status
Find (by name / glob) MainWindow::showFindDialogFindObjectDialogblock->findInst / findNet new WebSocketRequest::kFind + SelectHandler::handleFind: {obj_type: inst|net|port, pattern, match_case}, matched by glob (fnmatch, optional case-fold), selection capped at 1000; a modal (type dropdown + Match Case + close button) drives it. Web addition: the view auto-zooms to the union bbox of the matches (map.fitBounds) — the Qt dialog only selects — and the hit count is reported ❌ → ✅
Go to position (x, y, size) MainWindow::showGotoDialogGotoLocationDialog frontend-only modal (µm, prefilled with the current view center); converts µm→DBU and map.setView, or fitBounds a box of the requested size; Shift+G shortcut ❌ → ✅

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several new features to the web-based layout viewer, mirroring capabilities from the Qt GUI. These additions include a canvas right-click context menu for selecting and highlighting connected objects, search and navigation dialogs (Find and Go to Position), and a WYSIWYG layout capture tool that composites Leaflet layers and SVG overlays into a downloadable PNG. On the backend, support has been added for handling find and context action requests, rendering colored polygons, and serving image downloads via a new HTTP route. The review feedback highlights a few important issues: an uninitialized Color bg struct in web.cpp that could lead to undefined behavior, a logic flaw in capture.js where transparent background values prevent the fallback color from being applied, and a duplicate hex color code for dark_magenta in context-menu.js.

Comment thread src/web/src/web.cpp Outdated

// Background color (RRGGBB hex) so the saved image matches the viewer's
// background; absent => transparent.
Color bg; // {0,0,0,0}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Color bg; variable is declared on the stack without initialization. In C++, POD structs are not zero-initialized by default when declared on the stack, which leads to undefined behavior (reading garbage values from the stack for the background color of the exported image). Value-initializing it with {} ensures it is safely zero-initialized (transparent).

Suggested change
Color bg; // {0,0,0,0}
Color bg{}; // {0,0,0,0}

Comment thread src/web/src/capture.js Outdated
canvas.height = h;
const ctx = canvas.getContext('2d');
// Background matches the viewer (--bg-map).
ctx.fillStyle = getComputedStyle(container).backgroundColor || '#111';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In JavaScript, standard transparent background values like 'transparent' or 'rgba(0, 0, 0, 0)' are truthy strings. Therefore, the logical OR fallback || '#111' will never be triggered if the computed background is transparent. This results in a transparent background in the exported PNG, making light-colored layout elements invisible on standard white image viewers. Checking for these transparent values explicitly ensures the fallback background color is correctly applied.

Suggested change
ctx.fillStyle = getComputedStyle(container).backgroundColor || '#111';
ctx.fillStyle = (getComputedStyle(container).backgroundColor !== 'transparent' && getComputedStyle(container).backgroundColor !== 'rgba(0, 0, 0, 0)') ? (getComputedStyle(container).backgroundColor || '#111') : '#111';

{ name: 'magenta', hex: '#ff00ff' },
{ name: 'red', hex: '#ff0000' },
{ name: 'dark_green', hex: '#008000' },
{ name: 'dark_magenta', hex: '#800080' },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The hex color for dark_magenta is set to #800080, which is identical to the hex color for purple (also #800080). Standard dark magenta is #8b008b. Correcting this hex value avoids duplicate colors and ensures the color swatches in the context menu are distinct.

Suggested change
{ name: 'dark_magenta', hex: '#800080' },
{ name: 'dark_magenta', hex: '#8b008b' },

@openroad-ci
openroad-ci force-pushed the feature-WebGUI-contextmenu-search-navigation branch from c3691c3 to ec12f88 Compare July 18, 2026 02:02
Brings Qt-GUI parity (issue The-OpenROAD-Project#10619 tables 2.7 and 2.8) to the web viewer.

Table 2.7 - right-click context menu:
- Select -> Connected insts / output / input / all nets / buffer trees
- Highlight with the 8-color highlight groups
- Save layout (visible viewport and entire design)
- Clear (selections / focus nets / route guides / rulers / all)
- Menu items enable/disable based on the type under the cursor; the
  View submenu is replaced by an on-canvas Fit control next to zoom.

Table 2.8 - search & navigation:
- Find by name/glob (fnmatch) with auto-zoom to the result
- Go to position (x, y, size)
- Ctrl/Cmd+F and Shift+G shortcuts

Save layout is a client-side WYSIWYG composite of the displayed scene
(base layers + heatmap + highlights/selection + rulers), for both the
current viewport and the whole design (fit -> wait for tiles -> capture
-> restore view).

Backend: WebSocket handlers (handleSelect / handleFind /
handleContextAction) in request_handler, whole-die image render in
tile_generator, and a /download/image route with exception-free query
parsing in web.cpp.

Tests: FindHandler gtests plus JS unit tests for the context menu,
search & navigation, and layout capture.

Signed-off-by: Jorge Ferreira <jorge.ferreira@precisioninno.com>
@openroad-ci
openroad-ci force-pushed the feature-WebGUI-contextmenu-search-navigation branch from ec12f88 to a6d9141 Compare July 18, 2026 02:14
@jorge-ferreira-pii
jorge-ferreira-pii marked this pull request as ready for review July 18, 2026 02:44
@jorge-ferreira-pii
jorge-ferreira-pii requested a review from a team as a code owner July 18, 2026 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant