Skip to content

Commit 858ff90

Browse files
committed
gui: extend set display controls to access color information
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
1 parent 4597d96 commit 858ff90

6 files changed

Lines changed: 183 additions & 45 deletions

File tree

src/gui/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,8 +739,8 @@ gui::set_display_controls
739739
| Switch Name | Description |
740740
| ---- | ---- |
741741
| `name` | is the name of the control. For example, for the power nets option this would be ``Signals/Power`` or could be ``Layers/*`` to set the option for all the layers. |
742-
| `display_type` | is either ``visible`` or ``selectable`` |
743-
| `value` |is either ``true`` or ``false`` |
742+
| `display_type` | is either ``visible``, ``selectable``, ``color`` |
743+
| `value` | is either ``true`` or ``false`` for ``visible`` or ``selectable`` or the name of the color |
744744

745745
### Check Display Controls
746746

src/gui/include/gui/gui.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,8 @@ class Gui
635635
// modify display controls
636636
void setDisplayControlsVisible(const std::string& name, bool value);
637637
void setDisplayControlsSelectable(const std::string& name, bool value);
638+
void setDisplayControlsColor(const std::string& name,
639+
const Painter::Color& color);
638640
// Get the visibility/selectability for a control in the 'Display Control'
639641
// panel.
640642
bool checkDisplayControlsVisible(const std::string& name);

src/gui/src/displayControls.cpp

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,48 @@ void DisplayControls::displayItemSelected(const QItemSelection& selection)
995995
}
996996
}
997997

998+
std::tuple<QColor*, Qt::BrushStyle*, bool> DisplayControls::lookupColor(
999+
QStandardItem* item,
1000+
const QModelIndex* index)
1001+
{
1002+
if (item == misc_.background.swatch) {
1003+
return {&background_color_, nullptr, false};
1004+
} else if (item == blockages_.blockages.swatch) {
1005+
return {&placement_blockage_color_, &placement_blockage_pattern_, false};
1006+
} else if (item == misc_.regions.swatch) {
1007+
return {&region_color_, &region_pattern_, false};
1008+
} else if (item == instance_shapes_.names.swatch) {
1009+
return {&instance_name_color_, nullptr, false};
1010+
} else if (item == instance_shapes_.iterm_labels.swatch) {
1011+
return {&iterm_label_color_, nullptr, false};
1012+
} else if (item == rulers_.swatch) {
1013+
return {&ruler_color_, nullptr, false};
1014+
} else {
1015+
QVariant tech_layer_data = item->data(user_data_item_idx_);
1016+
if (!tech_layer_data.isValid()) {
1017+
return {nullptr, nullptr, false};
1018+
}
1019+
auto tech_layer = tech_layer_data.value<dbTechLayer*>();
1020+
auto site = tech_layer_data.value<odb::dbSite*>();
1021+
if (tech_layer != nullptr) {
1022+
QColor* item_color = &layer_color_[tech_layer];
1023+
Qt::BrushStyle* item_pattern = &layer_pattern_[tech_layer];
1024+
if (tech_layer->getType() != dbTechLayerType::ROUTING) {
1025+
if (index && index->row() != 0) {
1026+
// ensure if a via is the first layer, it can still be modified
1027+
return {item_color, item_pattern, false};
1028+
}
1029+
} else {
1030+
return {item_color, item_pattern, true};
1031+
}
1032+
} else if (site != nullptr) {
1033+
return {&site_color_[site], nullptr, false};
1034+
}
1035+
}
1036+
1037+
return {nullptr, nullptr, false};
1038+
}
1039+
9981040
void DisplayControls::displayItemDblClicked(const QModelIndex& index)
9991041
{
10001042
if (index.column() == 0) {
@@ -1013,43 +1055,10 @@ void DisplayControls::displayItemDblClicked(const QModelIndex& index)
10131055
Qt::BrushStyle* item_pattern = nullptr;
10141056
bool has_sibling = false;
10151057

1016-
// check if placement
1017-
if (color_item == misc_.background.swatch) {
1018-
item_color = &background_color_;
1019-
} else if (color_item == blockages_.blockages.swatch) {
1020-
item_color = &placement_blockage_color_;
1021-
item_pattern = &placement_blockage_pattern_;
1022-
} else if (color_item == misc_.regions.swatch) {
1023-
item_color = &region_color_;
1024-
item_pattern = &region_pattern_;
1025-
} else if (color_item == instance_shapes_.names.swatch) {
1026-
item_color = &instance_name_color_;
1027-
} else if (color_item == instance_shapes_.iterm_labels.swatch) {
1028-
item_color = &iterm_label_color_;
1029-
} else if (color_item == rulers_.swatch) {
1030-
item_color = &ruler_color_;
1031-
} else {
1032-
QVariant tech_layer_data = color_item->data(user_data_item_idx_);
1033-
if (!tech_layer_data.isValid()) {
1034-
return;
1035-
}
1036-
auto tech_layer = tech_layer_data.value<dbTechLayer*>();
1037-
auto site = tech_layer_data.value<odb::dbSite*>();
1038-
if (tech_layer != nullptr) {
1039-
item_color = &layer_color_[tech_layer];
1040-
item_pattern = &layer_pattern_[tech_layer];
1041-
if (tech_layer->getType() != dbTechLayerType::ROUTING) {
1042-
if (index.row() != 0) {
1043-
// ensure if a via is the first layer, it can still be modified
1044-
return;
1045-
}
1046-
} else {
1047-
has_sibling = true;
1048-
}
1049-
} else if (site != nullptr) {
1050-
item_color = &site_color_[site];
1051-
}
1052-
}
1058+
const auto lookup = lookupColor(color_item, &index);
1059+
item_color = std::get<0>(lookup);
1060+
item_pattern = std::get<1>(lookup);
1061+
has_sibling = std::get<2>(lookup);
10531062

10541063
if (item_color == nullptr) {
10551064
return;
@@ -1107,6 +1116,31 @@ void DisplayControls::setControlByPath(const std::string& path,
11071116
}
11081117
}
11091118

1119+
// path is separated by "/", so setting Standard Cells, would be
1120+
// Instances/StdCells
1121+
void DisplayControls::setControlByPath(const std::string& path,
1122+
const QColor& color)
1123+
{
1124+
std::vector<QStandardItem*> items;
1125+
findControlsInItems(path, Swatch, items);
1126+
1127+
if (items.empty()) {
1128+
logger_->error(utl::GUI, 40, "Unable to find {} display control", path);
1129+
} else {
1130+
for (auto* item : items) {
1131+
const auto& [item_color, item_style, sibling] = lookupColor(item);
1132+
if (sibling || item_color == nullptr) {
1133+
continue;
1134+
}
1135+
*item_color = color;
1136+
item->setIcon(makeSwatchIcon(color));
1137+
}
1138+
}
1139+
if (!items.empty()) {
1140+
emit colorChanged();
1141+
}
1142+
}
1143+
11101144
// path is separated by "/", so setting Standard Cells, would be
11111145
// Instances/StdCells
11121146
bool DisplayControls::checkControlByPath(const std::string& path,
@@ -2033,8 +2067,11 @@ void DisplayControls::buildRestoreTclCommands(std::vector<std::string>& cmds,
20332067
if (item->hasChildren()) {
20342068
buildRestoreTclCommands(cmds, item, name + "/");
20352069
} else {
2036-
bool visible = parent->child(r, Visible)->checkState() == Qt::Checked;
2037-
cmds.push_back(fmt::format(FMT_RUNTIME(visible_restore), name, visible));
2070+
auto* visible = parent->child(r, Visible);
2071+
if (visible) {
2072+
bool vis = visible->checkState() == Qt::Checked;
2073+
cmds.push_back(fmt::format(FMT_RUNTIME(visible_restore), name, vis));
2074+
}
20382075
auto* selectable = parent->child(r, Selectable);
20392076
if (selectable != nullptr) {
20402077
bool select = selectable->checkState() == Qt::Checked;

src/gui/src/displayControls.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <optional>
2424
#include <set>
2525
#include <string>
26+
#include <tuple>
2627
#include <vector>
2728

2829
#include "db_sta/dbNetwork.hh"
@@ -156,6 +157,7 @@ class DisplayControls : public QDockWidget,
156157
void setControlByPath(const std::string& path,
157158
bool is_visible,
158159
Qt::CheckState value);
160+
void setControlByPath(const std::string& path, const QColor& color);
159161
bool checkControlByPath(const std::string& path, bool is_visible);
160162

161163
void registerRenderer(Renderer* renderer);
@@ -478,6 +480,10 @@ class DisplayControls : public QDockWidget,
478480

479481
void checkLiberty(bool assume_loaded = false);
480482

483+
std::tuple<QColor*, Qt::BrushStyle*, bool> lookupColor(
484+
QStandardItem* item,
485+
const QModelIndex* index = nullptr);
486+
481487
QTreeView* view_;
482488
DisplayControlModel* model_;
483489
QMenu* routing_layers_menu_;

src/gui/src/gui.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,13 @@ void Gui::selectMarkers(odb::dbMarkerCategory* markers)
583583
main_window->getDRCViewer()->selectCategory(markers);
584584
}
585585

586+
void Gui::setDisplayControlsColor(const std::string& name,
587+
const Painter::Color& color)
588+
{
589+
const QColor qcolor(color.r, color.g, color.b, color.a);
590+
main_window->getControls()->setControlByPath(name, qcolor);
591+
}
592+
586593
void Gui::setDisplayControlsVisible(const std::string& name, bool value)
587594
{
588595
main_window->getControls()->setControlByPath(

src/gui/src/gui.i

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,25 +301,111 @@ void clear_highlights(int highlight_group = 0)
301301
gui->clearHighlights(highlight_group);
302302
}
303303

304-
void set_display_controls(const char* name, const char* display_type, bool value)
304+
void set_display_controls(const char* name, const char* display_type, const char* value)
305305
{
306306
if (!check_gui("set_display_controls")) {
307307
return;
308308
}
309309
auto gui = gui::Gui::get();
310+
auto logger = ord::OpenRoad::openRoad()->getLogger();
310311

311312
std::string disp_type = display_type;
313+
std::string str_value = value;
312314
// make lower case
313315
std::transform(disp_type.begin(),
314316
disp_type.end(),
315317
disp_type.begin(),
316318
[](char c) { return std::tolower(c); });
317319
if (disp_type == "visible") {
318-
gui->setDisplayControlsVisible(name, value);
320+
bool bval = str_value == "true" || str_value == "1";
321+
gui->setDisplayControlsVisible(name, bval);
319322
} else if (disp_type == "selectable") {
320-
gui->setDisplayControlsSelectable(name, value);
323+
bool bval = str_value == "true" || str_value == "1";
324+
gui->setDisplayControlsSelectable(name, bval);
325+
} else if (disp_type == "color") {
326+
gui::Painter::Color color = gui::Painter::black;
327+
if (str_value.empty()) {
328+
logger->error(GUI, 41, "Color is required");
329+
}
330+
if (str_value[0] == '#' && (str_value.size() == 7 || str_value.size() == 9)) {
331+
uint hex_color = 0;
332+
for (int i = 1; i < str_value.size(); i++) {
333+
const char c = std::tolower(str_value[i]);
334+
hex_color *= 16;
335+
if (c >= '0' && c <= '9') {
336+
hex_color += c - '0';
337+
} else if (c >= 'a' && c <= 'f') {
338+
hex_color += c - 'a' + 10;
339+
} else {
340+
logger->error(GUI, 43, "Unable to decode color: {}", str_value);
341+
}
342+
}
343+
if (str_value.size() == 7) {
344+
hex_color *= 256;
345+
hex_color += 255;
346+
}
347+
color.r = (hex_color & 0xff000000) >> 24;
348+
color.g = (hex_color & 0x00ff0000) >> 16;
349+
color.b = (hex_color & 0x0000ff00) >> 8;
350+
color.a = hex_color & 0x000000ff;
351+
} else if (str_value == "black") {
352+
color = gui::Painter::black;
353+
} else if (str_value == "white") {
354+
color = gui::Painter::white;
355+
} else if (str_value == "dark_gray") {
356+
color = gui::Painter::dark_gray;
357+
} else if (str_value == "gray") {
358+
color = gui::Painter::gray;
359+
} else if (str_value == "light_gray") {
360+
color = gui::Painter::light_gray;
361+
} else if (str_value == "red") {
362+
color = gui::Painter::red;
363+
} else if (str_value == "green") {
364+
color = gui::Painter::green;
365+
} else if (str_value == "blue") {
366+
color = gui::Painter::blue;
367+
} else if (str_value == "cyan") {
368+
color = gui::Painter::cyan;
369+
} else if (str_value == "magenta") {
370+
color = gui::Painter::magenta;
371+
} else if (str_value == "yellow") {
372+
color = gui::Painter::yellow;
373+
} else if (str_value == "dark_red") {
374+
color = gui::Painter::dark_red;
375+
} else if (str_value == "dark_green") {
376+
color = gui::Painter::dark_green;
377+
} else if (str_value == "dark_blue") {
378+
color = gui::Painter::dark_blue;
379+
} else if (str_value == "dark_cyan") {
380+
color = gui::Painter::dark_cyan;
381+
} else if (str_value == "dark_magenta") {
382+
color = gui::Painter::dark_magenta;
383+
} else if (str_value == "dark_yellow") {
384+
color = gui::Painter::dark_yellow;
385+
} else if (str_value == "orange") {
386+
color = gui::Painter::orange;
387+
} else if (str_value == "purple") {
388+
color = gui::Painter::purple;
389+
} else if (str_value == "lime") {
390+
color = gui::Painter::lime;
391+
} else if (str_value == "teal") {
392+
color = gui::Painter::teal;
393+
} else if (str_value == "pink") {
394+
color = gui::Painter::pink;
395+
} else if (str_value == "brown") {
396+
color = gui::Painter::brown;
397+
} else if (str_value == "indigo") {
398+
color = gui::Painter::indigo;
399+
} else if (str_value == "turquoise") {
400+
color = gui::Painter::turquoise;
401+
} else if (str_value == "transparent") {
402+
color = gui::Painter::transparent;
403+
} else {
404+
logger->error(GUI, 42, "Color not recognized: {}", str_value);
405+
}
406+
407+
gui->setDisplayControlsColor(name, color);
321408
} else {
322-
auto logger = ord::OpenRoad::openRoad()->getLogger();
323409
logger->error(GUI, 7, "Unknown display control type: {}", display_type);
324410
}
325411
}

0 commit comments

Comments
 (0)