gui: Add context menu to WebGUI#10630
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a context menu and label management system to the web layout viewer, allowing users to select, highlight, clear, and download layout images. It also adds backend support for processing these context actions and rendering colored polygons. The review identified two issues: an open polygon outline bug in TileGenerator::drawColoredPolygons where the final edge is not drawn, and a signed-to-unsigned conversion bug in toWebHighlightColor that can cause incorrect modulo results when the highlight group index is negative.
| for (int i = 0; i < n - 1; ++i) { | ||
| const int px0 | ||
| = static_cast<int>((points[i].x() - dbu_tile.xMin()) * scale); | ||
| const int py0 | ||
| = 255 - static_cast<int>((points[i].y() - dbu_tile.yMin()) * scale); | ||
| const int px1 | ||
| = static_cast<int>((points[i + 1].x() - dbu_tile.xMin()) * scale); | ||
| const int py1 | ||
| = 255 | ||
| - static_cast<int>((points[i + 1].y() - dbu_tile.yMin()) * scale); | ||
| drawLine(image, px0, py0, px1, py1, border); | ||
| } |
There was a problem hiding this comment.
The loop only draws lines between consecutive points up to n - 1, which leaves the polygon outline open because the final edge connecting the last point (points[n-1]) back to the first point (points[0]) is never drawn.
To ensure the polygon outline is fully closed (regardless of whether the input points list is already closed or open), we should iterate up to n and use modulo arithmetic to wrap around to the first point.
for (int i = 0; i < n; ++i) {
const auto& p0 = points[i];
const auto& p1 = points[(i + 1) % n];
const int px0
= static_cast<int>((p0.x() - dbu_tile.xMin()) * scale);
const int py0
= 255 - static_cast<int>((p0.y() - dbu_tile.yMin()) * scale);
const int px1
= static_cast<int>((p1.x() - dbu_tile.xMin()) * scale);
const int py1
= 255
- static_cast<int>((p1.y() - dbu_tile.yMin()) * scale);
drawLine(image, px0, py0, px1, py1, border);
}| Color toWebHighlightColor(const int group) | ||
| { | ||
| const auto& colors = gui::Painter::kHighlightColors; | ||
| const auto& c | ||
| = colors[((group % colors.size()) + colors.size()) % colors.size()]; | ||
| return Color{static_cast<unsigned char>(c.r), | ||
| static_cast<unsigned char>(c.g), | ||
| static_cast<unsigned char>(c.b), | ||
| static_cast<unsigned char>(c.a)}; | ||
| } |
There was a problem hiding this comment.
In toWebHighlightColor, colors.size() is of type size_t (unsigned). When performing group % colors.size(), the signed group is implicitly converted to size_t (unsigned). If group is negative, this leads to incorrect modulo results on non-power-of-two sizes, and can also trigger compiler warnings (e.g., -Wsign-conversion).
We should cast colors.size() to int first to ensure signed arithmetic is used, and also add a defensive check to prevent division by zero if colors is empty.
Color toWebHighlightColor(const int group)
{
const auto& colors = gui::Painter::kHighlightColors;
const int num_colors = static_cast<int>(colors.size());
if (num_colors == 0) {
return Color{0, 0, 0, 255};
}
const auto& c
= colors[((group % num_colors) + num_colors) % num_colors];
return Color{static_cast<unsigned char>(c.r),
static_cast<unsigned char>(c.g),
static_cast<unsigned char>(c.b),
static_cast<unsigned char>(c.a)};
}|
Frontend (UI & Interactions) context-menu.js, add-label-widget.js, main.js, style.css & CMakeLists.txt: Added a custom right-click context menu to the layout viewer. The menu allows users to add/remove custom text labels, select or highlight connected objects (instances, nets, buffer trees) with specific colors, clear highlights, and download images of the layout. The mouse events were updated to support both the new menu and the existing right-click drag zoom. request_handler.cpp & .h: Added a new WebSocket handler for context_action messages. It implements the logic to traverse the database to find connected nets, instances, and buffer trees, and updates the session state to track these new colored highlights and net flightlines. tile_generator.cpp/h & web.cpp: Enhanced the tile generator to support drawing colored polygons for highlights. Extracted the PNG generation logic into a new in-memory function (renderImagePng) and created a new HTTP endpoint (/download/image) to serve layout screenshots directly to the user's browser. |
90a810e to
c52ef75
Compare
Signed-off-by: Jorge Ferreira <jorge.ferreira@precisioninno.com>
c52ef75 to
019659d
Compare
Addresses a portion of #10619
2.7 Right-click context menu (layout canvas)
layoutViewer2.12 Rulers & labels
label.{h,cpp},add_label