diff --git a/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui b/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui
index 0932af9c5..cb4ae2af8 100644
--- a/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui
+++ b/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui
@@ -6,8 +6,8 @@
0
0
- 571
- 331
+ 649
+ 333
@@ -89,76 +89,120 @@ brightness of the color used.
6
- -
+
-
+
+
+ Net coloring
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 16
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ The color in which the rulers are drawn
+
+
+
+
+
+
+ -
+
+
+ or
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ -100
+
+
+ 100
+
+
+ 10
+
+
+
+ -
+
+
+ % intensity increase
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 201
+ 20
+
+
+
+
+
+
+
+ -
Net highlighting
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Fixed
-
-
-
- 16
- 20
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
- QSizePolicy::Fixed
-
-
-
- 16
- 20
-
-
-
-
- -
-
-
- or
-
-
- Qt::AlignCenter
-
-
-
- -
-
-
- % intensity increase
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 201
- 20
-
-
-
-
- -
+
-
QFrame::NoFrame
@@ -182,6 +226,53 @@ brightness of the color used.
0
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 16
+ 20
+
+
+
+
+ -
+
+
+ Auto-color with palette
+
+
+
-
@@ -196,27 +287,6 @@ brightness of the color used.
- -
-
-
- ...
-
-
-
- -
-
-
- ...
-
-
-
- -
-
-
- ...
-
-
-
-
@@ -231,6 +301,13 @@ brightness of the color used.
+ -
+
+
+ ...
+
+
+
-
@@ -238,6 +315,20 @@ brightness of the color used.
+ -
+
+
+ ...
+
+
+
+ -
+
+
+ ...
+
+
+
-
@@ -254,49 +345,6 @@ brightness of the color used.
- -
-
-
- Auto-color with palette
-
-
-
- -
-
-
- Net coloring
-
-
-
- -
-
-
- -100
-
-
- 100
-
-
- 10
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- The color in which the rulers are drawn
-
-
-
-
-
-
diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc
index ba3284341..452708079 100644
--- a/src/laybasic/laybasic/layNetlistBrowserPage.cc
+++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc
@@ -31,6 +31,7 @@
#include
#include
+#include
namespace lay
{
@@ -89,6 +90,8 @@ static size_t index_from_attr (const Attr *attr, const Iter &begin, const Iter &
NetColorizer::NetColorizer ()
{
m_auto_colors_enabled = false;
+ m_update_needed = false;
+ m_signals_enabled = true;
}
void
@@ -102,21 +105,27 @@ NetColorizer::configure (const QColor &marker_color, const lay::ColorPalette *au
m_auto_colors_enabled = false;
}
- emit colors_changed ();
+ emit_colors_changed ();
+}
+
+bool
+NetColorizer::has_color_for_net (const db::Net *net)
+{
+ return m_auto_colors_enabled || m_custom_color.find (net) != m_custom_color.end ();
}
void
NetColorizer::set_color_of_net (const db::Net *net, const QColor &color)
{
m_custom_color[net] = color;
- emit colors_changed ();
+ emit_colors_changed ();
}
void
NetColorizer::reset_color_of_net (const db::Net *net)
{
m_custom_color.erase (net);
- emit colors_changed ();
+ emit_colors_changed ();
}
void
@@ -124,7 +133,38 @@ NetColorizer::clear ()
{
m_net_index_by_object.clear ();
m_custom_color.clear ();
- emit colors_changed ();
+ emit_colors_changed ();
+}
+
+void
+NetColorizer::begin_changes ()
+{
+ if (m_signals_enabled) {
+ m_update_needed = false;
+ m_signals_enabled = false;
+ }
+}
+
+void
+NetColorizer::end_changes ()
+{
+ if (! m_signals_enabled) {
+ m_signals_enabled = true;
+ if (m_update_needed) {
+ emit colors_changed ();
+ }
+ m_update_needed = false;
+ }
+}
+
+void
+NetColorizer::emit_colors_changed ()
+{
+ if (! m_signals_enabled) {
+ m_update_needed = true;
+ } else {
+ emit colors_changed ();
+ }
}
QColor
@@ -907,7 +947,7 @@ static QIcon net_icon_with_color (const QColor &color)
QIcon
NetlistBrowserModel::icon_for_net (const db::Net *net) const
{
- if (mp_colorizer) {
+ if (mp_colorizer && mp_colorizer->has_color_for_net (net)) {
QColor color = mp_colorizer->color_of_net (net);
@@ -1097,7 +1137,7 @@ NetlistBrowserModel::index (int row, int column, const QModelIndex &parent) cons
void
NetlistBrowserModel::colors_changed ()
{
- // @@@ TODO: refresh colors of nets
+ emit dataChanged (index (0, 0, QModelIndex ()), index (rowCount (QModelIndex()) - 1, 0, QModelIndex ()));
}
const db::Net *
@@ -1481,12 +1521,23 @@ NetlistBrowserPage::NetlistBrowserPage (QWidget * /*parent*/)
{
Ui::NetlistBrowserPage::setupUi (this);
+ // @@@ insert into menu
m_show_all_action = new QAction (QObject::tr ("Show All"), this);
m_show_all_action->setCheckable (true);
m_show_all_action->setChecked (m_show_all);
+ QAction *color_action = new QAction (QObject::tr ("Colorize Nets"), directory_tree);
+ QMenu *menu = new QMenu (directory_tree);
+ lay::ColorButton::build_color_menu (menu, this, SLOT (browse_color_for_net ()), SLOT (select_color_for_net ()));
+ color_action->setMenu (menu);
+
directory_tree->addAction (actionCollapseAll);
directory_tree->addAction (actionExpandAll);
+ QAction *sep;
+ sep = new QAction (directory_tree);
+ sep->setSeparator (true);
+ directory_tree->addAction (sep);
+ directory_tree->addAction (color_action);
lay::HTMLItemDelegate *delegate;
@@ -1581,10 +1632,67 @@ NetlistBrowserPage::current_index_changed (const QModelIndex &index)
void *id = index.internalPointer ();
add_to_history (id, true);
- NetlistBrowserModel *model = dynamic_cast (directory_tree->model ());
- tl_assert (model != 0);
- show_net (model->net_from_index (index));
+ }
+}
+std::vector
+NetlistBrowserPage::selected_nets ()
+{
+ NetlistBrowserModel *model = dynamic_cast (directory_tree->model ());
+ tl_assert (model != 0);
+
+ std::vector nets;
+
+ QModelIndexList selection = directory_tree->selectionModel ()->selectedIndexes ();
+ for (QModelIndexList::const_iterator i = selection.begin (); i != selection.end (); ++i) {
+ const db::Net *net = model->net_from_index (*i);
+ if (net) {
+ nets.push_back (net);
+ }
+ }
+
+ return nets;
+}
+
+void
+NetlistBrowserPage::net_selection_changed ()
+{
+ highlight_nets (selected_nets ());
+}
+
+void
+NetlistBrowserPage::set_color_for_selected_nets (const QColor &color)
+{
+ std::vector nets = selected_nets ();
+
+ m_colorizer.begin_changes ();
+ for (std::vector::const_iterator n = nets.begin (); n != nets.end (); ++n) {
+ if (color.isValid ()) {
+ m_colorizer.set_color_of_net (*n, color);
+ } else {
+ m_colorizer.reset_color_of_net (*n);
+ }
+ }
+ m_colorizer.end_changes ();
+
+ update_highlights ();
+}
+
+void
+NetlistBrowserPage::browse_color_for_net ()
+{
+ QColor c = QColorDialog::getColor (QColor (), this);
+ if (c.isValid ()) {
+ set_color_for_selected_nets (c);
+ }
+}
+
+void
+NetlistBrowserPage::select_color_for_net ()
+{
+ QAction *action = dynamic_cast (sender ());
+ if (action) {
+ set_color_for_selected_nets (action->data ().value ());
}
}
@@ -1610,7 +1718,7 @@ NetlistBrowserPage::navigate_to (void *id, bool fwd)
add_to_history (id, fwd);
- show_net (model->net_from_index (index));
+ net_selection_changed ();
}
void
@@ -1697,7 +1805,7 @@ NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
mp_database.reset (database);
clear_markers ();
- show_net (0);
+ highlight_nets (std::vector ());
if (! database) {
directory_tree->setModel (0);
@@ -1709,6 +1817,7 @@ NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
directory_tree->setModel (new_model);
connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &)));
+ connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ()));
directory_tree->header ()->setSortIndicatorShown (true);
@@ -1718,14 +1827,14 @@ NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
}
void
-NetlistBrowserPage::show_net (const db::Net *net)
+NetlistBrowserPage::highlight_nets (const std::vector &nets)
{
- if (net != mp_current_net) {
+ if (nets != m_current_nets) {
- mp_current_net = net;
+ m_current_nets = nets;
clear_markers ();
- if (net) {
+ if (! nets.empty ()) {
adjust_view ();
update_highlights ();
}
@@ -1753,7 +1862,7 @@ NetlistBrowserPage::enable_updates (bool f)
void
NetlistBrowserPage::adjust_view ()
{
- if (! mp_database.get () || ! mp_view || ! mp_current_net || ! mp_current_net->circuit ()) {
+ if (! mp_database.get () || ! mp_view) {
return;
}
@@ -1771,28 +1880,36 @@ NetlistBrowserPage::adjust_view ()
return;
}
- db::cell_index_type cell_index = mp_current_net->circuit ()->cell_index ();
- size_t cluster_id = mp_current_net->cluster_id ();
-
db::DBox bbox;
- // @@@std::map > tv_by_layer = mp_view->cv_transform_variants_by_layer (m_cv_index);
- std::vector tv = mp_view->cv_transform_variants (m_cv_index);
+ for (std::vector::const_iterator net = m_current_nets.begin (); net != m_current_nets.end (); ++net) {
- const db::Connectivity &conn = mp_database->connectivity ();
- for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
-
- // @@@ TODO: how to get the original layer?
-
- db::Box layer_bbox;
- db::recursive_cluster_shape_iterator shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
- while (! shapes.at_end ()) {
- layer_bbox += shapes.trans () * shapes->box ();
- ++shapes;
+ if (! (*net)->circuit ()) {
+ continue;
}
- for (std::vector::const_iterator t = tv.begin (); t != tv.end (); ++t) {
- bbox += *t * db::CplxTrans (layout->dbu ()) * layer_bbox;
+ db::cell_index_type cell_index = (*net)->circuit ()->cell_index ();
+ size_t cluster_id = (*net)->cluster_id ();
+
+ // @@@std::map > tv_by_layer = mp_view->cv_transform_variants_by_layer (m_cv_index);
+ std::vector tv = mp_view->cv_transform_variants (m_cv_index);
+
+ const db::Connectivity &conn = mp_database->connectivity ();
+ for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
+
+ // @@@ TODO: how to get the original layer?
+
+ db::Box layer_bbox;
+ db::recursive_cluster_shape_iterator shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
+ while (! shapes.at_end ()) {
+ layer_bbox += shapes.trans () * shapes->box ();
+ ++shapes;
+ }
+
+ for (std::vector::const_iterator t = tv.begin (); t != tv.end (); ++t) {
+ bbox += *t * db::CplxTrans (layout->dbu ()) * layer_bbox;
+ }
+
}
}
@@ -1830,7 +1947,7 @@ NetlistBrowserPage::update_highlights ()
clear_markers ();
- if (! mp_database.get () || ! mp_view || ! mp_current_net || ! mp_current_net->circuit ()) {
+ if (! mp_database.get () || ! mp_view) {
return;
}
@@ -1839,64 +1956,73 @@ NetlistBrowserPage::update_highlights ()
return;
}
- db::cell_index_type cell_index = mp_current_net->circuit ()->cell_index ();
- size_t cluster_id = mp_current_net->cluster_id ();
-
// @@@std::map > tv_by_layer = mp_view->cv_transform_variants_by_layer (m_cv_index);
std::vector tv = mp_view->cv_transform_variants (m_cv_index);
size_t n_markers = 0;
- QColor net_color = m_colorizer.color_of_net (mp_current_net);
- const db::Connectivity &conn = mp_database->connectivity ();
- for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
+ for (std::vector::const_iterator net = m_current_nets.begin (); net != m_current_nets.end (); ++net) {
- // @@@ TODO: how to get the original layer?
+ if (! (*net)->circuit ()) {
+ continue;
+ }
- db::recursive_cluster_shape_iterator shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
- while (! shapes.at_end () && n_markers < m_max_shape_count) {
+ db::cell_index_type cell_index = (*net)->circuit ()->cell_index ();
+ size_t cluster_id = (*net)->cluster_id ();
- mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
- mp_markers.back ()->set (*shapes, shapes.trans (), tv);
+ QColor net_color = m_colorizer.color_of_net (*net);
-#if 0
-// @@@
- if (! original.at_end ()) {
- mp_markers.back ()->set_line_width (original->width (true));
- mp_markers.back ()->set_vertex_size (1);
- mp_markers.back ()->set_dither_pattern (original->dither_pattern (true));
- if (view ()->background_color ().green () < 128) {
- mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100));
- mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100));
- } else {
- mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (-m_marker_intensity * 255) / 100));
- mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (-m_marker_intensity * 255) / 100));
+ const db::Connectivity &conn = mp_database->connectivity ();
+ for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
+
+ // @@@ TODO: how to get the original layer?
+
+ db::recursive_cluster_shape_iterator shapes (mp_database->net_clusters (), *layer, cell_index, cluster_id);
+ while (! shapes.at_end () && n_markers < m_max_shape_count) {
+
+ mp_markers.push_back (new lay::Marker (mp_view, m_cv_index));
+ mp_markers.back ()->set (*shapes, shapes.trans (), tv);
+
+ #if 0
+ // @@@
+ if (! original.at_end ()) {
+ mp_markers.back ()->set_line_width (original->width (true));
+ mp_markers.back ()->set_vertex_size (1);
+ mp_markers.back ()->set_dither_pattern (original->dither_pattern (true));
+ if (view ()->background_color ().green () < 128) {
+ mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (m_marker_intensity * 255) / 100));
+ mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (m_marker_intensity * 255) / 100));
+ } else {
+ mp_markers.back ()->set_color (original->eff_fill_color_brighter (true, (-m_marker_intensity * 255) / 100));
+ mp_markers.back ()->set_frame_color (original->eff_frame_color_brighter (true, (-m_marker_intensity * 255) / 100));
+ }
}
- }
-#endif
- // @@@
- mp_markers.back ()->set_color (net_color);
- mp_markers.back ()->set_frame_color (net_color);
- // @@@
+ #endif
+ // @@@
+ mp_markers.back ()->set_color (net_color);
+ mp_markers.back ()->set_frame_color (net_color);
+ // @@@
- if (m_marker_line_width >= 0) {
- mp_markers.back ()->set_line_width (m_marker_line_width);
- }
+ if (m_marker_line_width >= 0) {
+ mp_markers.back ()->set_line_width (m_marker_line_width);
+ }
- if (m_marker_vertex_size >= 0) {
- mp_markers.back ()->set_vertex_size (m_marker_vertex_size);
- }
+ if (m_marker_vertex_size >= 0) {
+ mp_markers.back ()->set_vertex_size (m_marker_vertex_size);
+ }
- if (m_marker_halo >= 0) {
- mp_markers.back ()->set_halo (m_marker_halo);
- }
+ if (m_marker_halo >= 0) {
+ mp_markers.back ()->set_halo (m_marker_halo);
+ }
- if (m_marker_dither_pattern >= 0) {
- mp_markers.back ()->set_dither_pattern (m_marker_dither_pattern);
- }
+ if (m_marker_dither_pattern >= 0) {
+ mp_markers.back ()->set_dither_pattern (m_marker_dither_pattern);
+ }
- ++shapes;
- ++n_markers;
+ ++shapes;
+ ++n_markers;
+
+ }
}
diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.h b/src/laybasic/laybasic/layNetlistBrowserPage.h
index b5d5c1e9b..b5b7b8c03 100644
--- a/src/laybasic/laybasic/layNetlistBrowserPage.h
+++ b/src/laybasic/laybasic/layNetlistBrowserPage.h
@@ -55,12 +55,16 @@ public:
NetColorizer ();
void configure (const QColor &marker_color, const lay::ColorPalette *auto_colors);
+ bool has_color_for_net (const db::Net *net);
void set_color_of_net (const db::Net *net, const QColor &color);
void reset_color_of_net (const db::Net *net);
void clear ();
QColor color_of_net (const db::Net *net) const;
+ void begin_changes ();
+ void end_changes ();
+
signals:
void colors_changed ();
@@ -69,7 +73,11 @@ private:
lay::ColorPalette m_auto_colors;
bool m_auto_colors_enabled;
std::map m_custom_color;
+ bool m_update_needed;
+ bool m_signals_enabled;
mutable std::map m_net_index_by_object;
+
+ void emit_colors_changed ();
};
// ----------------------------------------------------------------------------------
@@ -295,6 +303,9 @@ private slots:
void navigate_back ();
void navigate_forward ();
void current_index_changed (const QModelIndex &index);
+ void net_selection_changed ();
+ void browse_color_for_net ();
+ void select_color_for_net ();
private:
bool m_show_all;
@@ -318,13 +329,15 @@ private:
std::vector mp_markers;
bool m_enable_updates;
bool m_update_needed;
- const db::Net *mp_current_net;
+ std::vector m_current_nets;
void add_to_history (void *id, bool fwd);
void navigate_to (void *id, bool forward = true);
void adjust_view ();
void clear_markers ();
- void show_net (const db::Net *net);
+ void highlight_nets (const std::vector &nets);
+ std::vector selected_nets ();
+ void set_color_for_selected_nets (const QColor &color);
};
} // namespace lay
diff --git a/src/laybasic/laybasic/layWidgets.cc b/src/laybasic/laybasic/layWidgets.cc
index 529bdaa14..0a37d34e7 100644
--- a/src/laybasic/laybasic/layWidgets.cc
+++ b/src/laybasic/laybasic/layWidgets.cc
@@ -815,14 +815,18 @@ const char *color_icon =
"xxxxE44ExxD33Dxxxx"
"xxxxxeexxxxddxxxxx";
-void
-ColorButton::build_menu ()
+void
+ColorButton::build_color_menu (QMenu *menu, QObject *receiver, const char *browse_slot, const char *selected_slot)
{
- menu ()->clear ();
+ tl_assert (selected_slot != 0);
- menu ()->addAction (QObject::tr ("Automatic"), this, SLOT (menu_selected ()))->setData (QVariant (QColor ()));
- menu ()->addAction (QObject::tr ("Choose ..."), this, SLOT (browse_selected ()));
- menu ()->addSeparator ();
+ menu->clear ();
+
+ menu->addAction (QObject::tr ("Automatic"), receiver, selected_slot)->setData (QVariant (QColor ()));
+ if (browse_slot) {
+ menu->addAction (QObject::tr ("Choose ..."), receiver, browse_slot);
+ }
+ menu->addSeparator ();
try {
@@ -858,7 +862,7 @@ ColorButton::build_menu ()
}
}
- submenu = menu ()->addMenu (QPixmap::fromImage (icon), tl::to_qstring (tl::sprintf ("#%d .. %d", i + 1, std::min (i + 6, palette.colors ()))));
+ submenu = menu->addMenu (QPixmap::fromImage (icon), tl::to_qstring (tl::sprintf ("#%d .. %d", i + 1, std::min (i + 6, palette.colors ()))));
}
@@ -868,13 +872,19 @@ ColorButton::build_menu ()
QPixmap icon (16, 16);
icon.fill (color);
- submenu->addAction (QIcon (icon), tl::to_qstring (name), this, SLOT (menu_selected ()))->setData (QVariant (color));
+ submenu->addAction (QIcon (icon), tl::to_qstring (name), receiver, selected_slot)->setData (QVariant (color));
}
} catch (...) { }
}
+void
+ColorButton::build_menu ()
+{
+ build_color_menu (menu (), this, SLOT (browse_selected ()), SLOT (menu_selected ()));
+}
+
void
ColorButton::set_color (QColor c)
{
diff --git a/src/laybasic/laybasic/layWidgets.h b/src/laybasic/laybasic/layWidgets.h
index cad674045..cde82c8eb 100644
--- a/src/laybasic/laybasic/layWidgets.h
+++ b/src/laybasic/laybasic/layWidgets.h
@@ -325,6 +325,7 @@ public:
ColorButton (QWidget *parent, const char *name = 0);
QColor get_color () const;
+ static void build_color_menu (QMenu *menu, QObject *receiver, const char *browse_slot, const char *selected_slot);
signals:
void color_changed (QColor color);