@@ -489,6 +489,7 @@ DisplayControls::DisplayControls(QWidget* parent)
489489
490490 region_color_ = QColor (0x70 , 0x70 , 0x70 , 0x70 ); // semi-transparent mid-gray
491491 region_pattern_ = Qt::SolidPattern;
492+ background_color_ = Qt::black;
492493 makeLeafItem (misc_.scale_bar , " Scale bar" , misc, Qt::Checked);
493494 makeLeafItem (misc_.access_points , " Access points" , misc, Qt::Unchecked);
494495 makeLeafItem (
@@ -499,6 +500,8 @@ DisplayControls::DisplayControls(QWidget* parent)
499500 makeLeafItem (
500501 misc_.manufacturing_grid , " Manufacturing grid" , misc, Qt::Unchecked);
501502 makeLeafItem (misc_.gcell_grid , " GCell grid" , misc, Qt::Unchecked);
503+ makeLeafItem (
504+ misc_.background , " Background" , misc, {}, false , background_color_);
502505 toggleParent (misc_group_);
503506
504507 checkLiberty ();
@@ -523,6 +526,8 @@ DisplayControls::DisplayControls(QWidget* parent)
523526 this ,
524527 &DisplayControls::itemContextMenu);
525528
529+ connect (
530+ this , &DisplayControls::colorChanged, this , &DisplayControls::changed);
526531 // register renderers
527532 if (gui::Gui::get () != nullptr ) {
528533 for (auto renderer : gui::Gui::get ()->renderers ()) {
@@ -604,7 +609,9 @@ void DisplayControls::writeSettingsForRow(QSettings* settings,
604609 name->child (r, Selectable));
605610 }
606611 } else {
607- settings->setValue (" visible" , asBool (visible));
612+ if (visible != nullptr ) {
613+ settings->setValue (" visible" , asBool (visible));
614+ }
608615 if (selectable != nullptr ) {
609616 settings->setValue (" selectable" , asBool (selectable));
610617 }
@@ -643,7 +650,9 @@ void DisplayControls::readSettingsForRow(QSettings* settings,
643650 name->child (r, Selectable));
644651 }
645652 } else {
646- visible->setCheckState (getChecked (settings, " visible" , visible));
653+ if (visible != nullptr ) {
654+ visible->setCheckState (getChecked (settings, " visible" , visible));
655+ }
647656 if (selectable != nullptr ) {
648657 selectable->setCheckState (getChecked (settings, " selectable" , selectable));
649658 }
@@ -680,6 +689,7 @@ void DisplayControls::readSettings(QSettings* settings)
680689
681690 settings->beginGroup (" other" );
682691 settings->beginGroup (" color" );
692+ getColor (misc_.background , background_color_, " background" );
683693 getColor (
684694 blockages_.blockages , placement_blockage_color_, " blockages_placement" );
685695 getColor (rulers_, ruler_color_, " ruler" );
@@ -753,6 +763,7 @@ void DisplayControls::writeSettings(QSettings* settings)
753763
754764 settings->beginGroup (" other" );
755765 settings->beginGroup (" color" );
766+ settings->setValue (" background" , background_color_);
756767 settings->setValue (" blockages_placement" , placement_blockage_color_);
757768 settings->setValue (" ruler" , ruler_color_);
758769 settings->setValue (" instance_name" , instance_name_color_);
@@ -876,7 +887,9 @@ void DisplayControls::toggleParent(const QStandardItem* parent,
876887
877888void DisplayControls::toggleParent (ModelRow& row)
878889{
879- toggleParent (row.name , row.visible , Visible);
890+ if (row.visible != nullptr ) {
891+ toggleParent (row.name , row.visible , Visible);
892+ }
880893 if (row.selectable != nullptr ) {
881894 toggleParent (row.name , row.selectable , Selectable);
882895 }
@@ -982,6 +995,52 @@ void DisplayControls::displayItemSelected(const QItemSelection& selection)
982995 }
983996}
984997
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+ }
1005+ if (item == blockages_.blockages .swatch ) {
1006+ return {&placement_blockage_color_, &placement_blockage_pattern_, false };
1007+ }
1008+ if (item == misc_.regions .swatch ) {
1009+ return {®ion_color_, ®ion_pattern_, false };
1010+ }
1011+ if (item == instance_shapes_.names .swatch ) {
1012+ return {&instance_name_color_, nullptr , false };
1013+ }
1014+ if (item == instance_shapes_.iterm_labels .swatch ) {
1015+ return {&iterm_label_color_, nullptr , false };
1016+ }
1017+ if (item == rulers_.swatch ) {
1018+ return {&ruler_color_, nullptr , false };
1019+ }
1020+ QVariant tech_layer_data = item->data (user_data_item_idx_);
1021+ if (!tech_layer_data.isValid ()) {
1022+ return {nullptr , nullptr , false };
1023+ }
1024+ auto tech_layer = tech_layer_data.value <dbTechLayer*>();
1025+ auto site = tech_layer_data.value <odb::dbSite*>();
1026+ if (tech_layer != nullptr ) {
1027+ QColor* item_color = &layer_color_[tech_layer];
1028+ Qt::BrushStyle* item_pattern = &layer_pattern_[tech_layer];
1029+ if (tech_layer->getType () != dbTechLayerType::ROUTING ) {
1030+ if (index && index->row () != 0 ) {
1031+ // ensure if a via is the first layer, it can still be modified
1032+ return {item_color, item_pattern, false };
1033+ }
1034+ } else {
1035+ return {item_color, item_pattern, true };
1036+ }
1037+ } else if (site != nullptr ) {
1038+ return {&site_color_[site], nullptr , false };
1039+ }
1040+
1041+ return {nullptr , nullptr , false };
1042+ }
1043+
9851044void DisplayControls::displayItemDblClicked (const QModelIndex& index)
9861045{
9871046 if (index.column () == 0 ) {
@@ -1000,41 +1059,10 @@ void DisplayControls::displayItemDblClicked(const QModelIndex& index)
10001059 Qt::BrushStyle* item_pattern = nullptr ;
10011060 bool has_sibling = false ;
10021061
1003- // check if placement
1004- if (color_item == blockages_.blockages .swatch ) {
1005- item_color = &placement_blockage_color_;
1006- item_pattern = &placement_blockage_pattern_;
1007- } else if (color_item == misc_.regions .swatch ) {
1008- item_color = ®ion_color_;
1009- item_pattern = ®ion_pattern_;
1010- } else if (color_item == instance_shapes_.names .swatch ) {
1011- item_color = &instance_name_color_;
1012- } else if (color_item == instance_shapes_.iterm_labels .swatch ) {
1013- item_color = &iterm_label_color_;
1014- } else if (color_item == rulers_.swatch ) {
1015- item_color = &ruler_color_;
1016- } else {
1017- QVariant tech_layer_data = color_item->data (user_data_item_idx_);
1018- if (!tech_layer_data.isValid ()) {
1019- return ;
1020- }
1021- auto tech_layer = tech_layer_data.value <dbTechLayer*>();
1022- auto site = tech_layer_data.value <odb::dbSite*>();
1023- if (tech_layer != nullptr ) {
1024- item_color = &layer_color_[tech_layer];
1025- item_pattern = &layer_pattern_[tech_layer];
1026- if (tech_layer->getType () != dbTechLayerType::ROUTING ) {
1027- if (index.row () != 0 ) {
1028- // ensure if a via is the first layer, it can still be modified
1029- return ;
1030- }
1031- } else {
1032- has_sibling = true ;
1033- }
1034- } else if (site != nullptr ) {
1035- item_color = &site_color_[site];
1036- }
1037- }
1062+ const auto lookup = lookupColor (color_item, &index);
1063+ item_color = std::get<0 >(lookup);
1064+ item_pattern = std::get<1 >(lookup);
1065+ has_sibling = std::get<2 >(lookup);
10381066
10391067 if (item_color == nullptr ) {
10401068 return ;
@@ -1065,7 +1093,7 @@ void DisplayControls::displayItemDblClicked(const QModelIndex& index)
10651093 *item_pattern = display_dialog->getSelectedPattern ();
10661094 }
10671095 view_->repaint ();
1068- emit changed ();
1096+ emit colorChanged ();
10691097 }
10701098 }
10711099}
@@ -1092,6 +1120,31 @@ void DisplayControls::setControlByPath(const std::string& path,
10921120 }
10931121}
10941122
1123+ // path is separated by "/", so setting Standard Cells, would be
1124+ // Instances/StdCells
1125+ void DisplayControls::setControlByPath (const std::string& path,
1126+ const QColor& color)
1127+ {
1128+ std::vector<QStandardItem*> items;
1129+ findControlsInItems (path, Swatch, items);
1130+
1131+ if (items.empty ()) {
1132+ logger_->error (utl::GUI , 40 , " Unable to find {} display control" , path);
1133+ } else {
1134+ for (auto * item : items) {
1135+ const auto & [item_color, item_style, sibling] = lookupColor (item);
1136+ if (sibling || item_color == nullptr ) {
1137+ continue ;
1138+ }
1139+ *item_color = color;
1140+ item->setIcon (makeSwatchIcon (color));
1141+ }
1142+ }
1143+ if (!items.empty ()) {
1144+ emit colorChanged ();
1145+ }
1146+ }
1147+
10951148// path is separated by "/", so setting Standard Cells, would be
10961149// Instances/StdCells
10971150bool DisplayControls::checkControlByPath (const std::string& path,
@@ -1291,7 +1344,7 @@ QStandardItem* DisplayControls::makeParentItem(ModelRow& row,
12911344void DisplayControls::makeLeafItem (ModelRow& row,
12921345 const QString& text,
12931346 QStandardItem* parent,
1294- Qt::CheckState checked,
1347+ std::optional< Qt::CheckState> checked,
12951348 bool add_selectable,
12961349 const QColor& color,
12971350 const QVariant& user_data)
@@ -1309,16 +1362,18 @@ void DisplayControls::makeLeafItem(ModelRow& row,
13091362 row.swatch ->setData (user_data, user_data_item_idx_);
13101363 }
13111364
1312- row.visible = new QStandardItem (" " );
1313- row.visible ->setCheckable (true );
1314- row.visible ->setEditable (false );
1315- row.visible ->setCheckState (checked);
1365+ if (checked.has_value ()) {
1366+ row.visible = new QStandardItem (" " );
1367+ row.visible ->setCheckable (true );
1368+ row.visible ->setEditable (false );
1369+ row.visible ->setCheckState (checked.value ());
1370+ }
13161371
13171372 if (add_selectable) {
13181373 row.selectable = new QStandardItem (" " );
13191374 row.selectable ->setCheckable (true );
13201375 row.selectable ->setEditable (false );
1321- row.selectable ->setCheckState (checked);
1376+ row.selectable ->setCheckState (checked. value_or (Qt::Unchecked) );
13221377 }
13231378
13241379 parent->appendRow ({row.name , row.swatch , row.visible , row.selectable });
@@ -1354,6 +1409,11 @@ QIcon DisplayControls::makeSwatchIcon(const QColor& color)
13541409 return QIcon (swatch);
13551410}
13561411
1412+ QColor DisplayControls::background ()
1413+ {
1414+ return background_color_;
1415+ }
1416+
13571417QColor DisplayControls::color (const dbTechLayer* layer)
13581418{
13591419 auto it = layer_color_.find (layer);
@@ -2011,8 +2071,11 @@ void DisplayControls::buildRestoreTclCommands(std::vector<std::string>& cmds,
20112071 if (item->hasChildren ()) {
20122072 buildRestoreTclCommands (cmds, item, name + " /" );
20132073 } else {
2014- bool visible = parent->child (r, Visible)->checkState () == Qt::Checked;
2015- cmds.push_back (fmt::format (FMT_RUNTIME (visible_restore), name, visible));
2074+ auto * visible = parent->child (r, Visible);
2075+ if (visible) {
2076+ bool vis = visible->checkState () == Qt::Checked;
2077+ cmds.push_back (fmt::format (FMT_RUNTIME (visible_restore), name, vis));
2078+ }
20162079 auto * selectable = parent->child (r, Selectable);
20172080 if (selectable != nullptr ) {
20182081 bool select = selectable->checkState () == Qt::Checked;
0 commit comments