gui: Add feature highlight for browser WebGUI#10631
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces the Select & Highlight Browser widget to the web interface, mirroring the Qt GUI's SelectHighlightWindow. It adds the frontend SelectHighlightWidget and integrates it into the build system, main application, and menu bar. On the backend, it implements handlers for selection and highlight management, including deselecting, clearing, grouping, and inspecting items, as well as rendering colored overlay shapes. The review feedback suggests correcting a hex color mismatch for the 'purple' highlight group and refactoring the JSON item creation helper to return a boost::json::object directly, which simplifies and optimizes the list-building logic in handleSelectionList.
| { name: 'dark_magenta', hex: '#800080' }, | ||
| { name: 'blue', hex: '#0000ff' }, | ||
| { name: 'orange', hex: '#ffa500' }, | ||
| { name: 'purple', hex: '#800080' }, |
There was a problem hiding this comment.
The hex color for 'purple' is set to '#800080', which is identical to 'dark_magenta'. In the backend (gui::Painter::kHighlightColors), the color for purple is (128, 0, 255), which corresponds to #8000ff. This mismatch causes the frontend color swatch/picker to display a different color than what is actually rendered on the layout map.
| { name: 'purple', hex: '#800080' }, | |
| { name: 'purple', hex: '#8000ff' }, |
| // Append {id,name,type,bbox} for `sel` to `arr`. | ||
| void appendBrowserItem(boost::json::array& arr, | ||
| int id, | ||
| const gui::Selected& sel) | ||
| { | ||
| boost::json::object item; | ||
| item["id"] = id; | ||
| item["name"] = sel.getName(); | ||
| item["type"] = sel.getTypeName(); | ||
| odb::Rect bbox; | ||
| if (sel.getBBox(bbox)) { | ||
| item["bbox"] = bboxArray(bbox); | ||
| } | ||
| arr.emplace_back(std::move(item)); | ||
| } |
There was a problem hiding this comment.
The helper function appendBrowserItem appends directly to a boost::json::array. In handleSelectionList, this forces a roundabout and inefficient pattern for the highlighted list where a temporary array tmp is created for every single item, the item is appended, then extracted back out via tmp.front().as_object().
Refactoring appendBrowserItem to a static helper makeBrowserItem that returns a boost::json::object directly avoids this overhead and simplifies the calling code.
// Create {id,name,type,bbox} for `sel` as a JSON object.
static boost::json::object makeBrowserItem(int id, const gui::Selected& sel)
{
boost::json::object item;
item["id"] = id;
item["name"] = sel.getName();
item["type"] = sel.getTypeName();
odb::Rect bbox;
if (sel.getBBox(bbox)) {
item["bbox"] = bboxArray(bbox);
}
return item;
}| boost::json::array sel_arr; | ||
| state.browser_selected.clear(); | ||
| for (const auto& s : state.selection_set) { | ||
| if (!s) { | ||
| continue; | ||
| } | ||
| const int id = static_cast<int>(state.browser_selected.size()); | ||
| state.browser_selected.push_back(s); | ||
| appendBrowserItem(sel_arr, id, s); | ||
| } | ||
| root["selected"] = std::move(sel_arr); | ||
|
|
||
| boost::json::array hl_arr; | ||
| state.browser_highlighted.clear(); | ||
| for (int g = 0; g < gui::kNumHighlightSet; ++g) { | ||
| for (const auto& s : state.highlight_groups[g]) { | ||
| if (!s) { | ||
| continue; | ||
| } | ||
| const int id = static_cast<int>(state.browser_highlighted.size()); | ||
| state.browser_highlighted.emplace_back(s, g); | ||
| boost::json::array tmp; | ||
| appendBrowserItem(tmp, id, s); | ||
| auto item = tmp.front().as_object(); | ||
| item["group"] = g; | ||
| hl_arr.emplace_back(std::move(item)); | ||
| } | ||
| } | ||
| root["highlighted"] = std::move(hl_arr); |
There was a problem hiding this comment.
Simplify the list building logic by utilizing the refactored makeBrowserItem helper. This eliminates the creation and extraction overhead of the temporary boost::json::array tmp for each highlighted item.
boost::json::array sel_arr;
state.browser_selected.clear();
for (const auto& s : state.selection_set) {
if (!s) {
continue;
}
const int id = static_cast<int>(state.browser_selected.size());
state.browser_selected.push_back(s);
sel_arr.emplace_back(makeBrowserItem(id, s));
}
root["selected"] = std::move(sel_arr);
boost::json::array hl_arr;
state.browser_highlighted.clear();
for (int g = 0; g < gui::kNumHighlightSet; ++g) {
for (const auto& s : state.highlight_groups[g]) {
if (!s) {
continue;
}
const int id = static_cast<int>(state.browser_highlighted.size());
state.browser_highlighted.emplace_back(s, g);
auto item = makeBrowserItem(id, s);
item["group"] = g;
hl_arr.emplace_back(std::move(item));
}
}
root["highlighted"] = std::move(hl_arr);Signed-off-by: Jorge Ferreira <jorge.ferreira@precisioninno.com>
2cad6af to
49d52ea
Compare
|
|
This doesn't seem to be a complete fix for all the issues in #10619 |
Addresses a portion of #10619
2.6 Selection, highlight & inspection
selectHighlightWindow