diff --git a/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui b/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui index 31000d54e..9139b7fa9 100644 --- a/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui +++ b/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui @@ -7,7 +7,7 @@ 0 0 649 - 333 + 351 @@ -17,7 +17,7 @@ - Net Appearance + Marker Appearance @@ -38,11 +38,10 @@ - By default, the original layer's style is used for the highlighted net. -This style can be overridden by specifying a color, stipple, line width etc. -Leave those fields empty to use the original style. -With "original color", the color intensity adjustment allows increasing or decreasing the -brightness of the color used. + Nets, circuits and devices are highlighted using the given styles. +Nets can be highlighted using the drawing colors for original layers with a higher or lower +intensity, drawn with the highlight color or auto-colored with a cycling color from the palette. +Non-net objects are drawn using the highlight color. false @@ -92,7 +91,7 @@ brightness of the color used. - Net coloring + Net auto-coloring @@ -182,7 +181,7 @@ brightness of the color used. - % intensity increase + % intensity increase (for net shapes on original layers) @@ -205,7 +204,7 @@ brightness of the color used. - Net highlighting + Highlight color @@ -469,7 +468,7 @@ brightness of the color used. - true + false diff --git a/src/laybasic/laybasic/layNetlistBrowserModel.h b/src/laybasic/laybasic/layNetlistBrowserModel.h index 72556eeb0..6f8eb805e 100644 --- a/src/laybasic/laybasic/layNetlistBrowserModel.h +++ b/src/laybasic/laybasic/layNetlistBrowserModel.h @@ -143,6 +143,11 @@ public: std::pair device_from_index (const QModelIndex &index) const; + bool is_circuit_index (const QModelIndex &index) const + { + return is_id_circuit (index.internalPointer ()); + } + void set_item_visibility (QTreeView *view, bool show_all, bool with_warnings); private slots: diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index 86ae197ca..aeacbebb7 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -55,13 +55,25 @@ extern const std::string cfg_l2ndb_show_all; // ---------------------------------------------------------------------------------- // NetlistBrowserPage implementation +template +inline const db::Circuit *deref_circuit (const Obj *obj) +{ + return obj->circuit (); +} + +template <> +inline const db::Circuit *deref_circuit (const db::Circuit *obj) +{ + return obj; +} + template static db::ICplxTrans trans_for (const Obj *objs, const db::Layout &ly, const db::Cell &cell, db::ContextCache &cc, const db::DCplxTrans &initial = db::DCplxTrans ()) { db::DCplxTrans t = initial; - const db::Circuit *circuit = objs->circuit (); + const db::Circuit *circuit = deref_circuit (objs); while (circuit) { if (circuit->cell_index () == cell.cell_index ()) { circuit = 0; @@ -372,6 +384,27 @@ NetlistBrowserPage::selected_nets () return nets; } +std::vector +NetlistBrowserPage::selected_circuits () +{ + NetlistBrowserModel *model = dynamic_cast (directory_tree->model ()); + tl_assert (model != 0); + + std::vector circuits; + + QModelIndexList selection = directory_tree->selectionModel ()->selectedIndexes (); + for (QModelIndexList::const_iterator i = selection.begin (); i != selection.end (); ++i) { + if (i->column () == 0 && model->is_circuit_index (*i)) { + const db::Circuit *circuit = model->circuit_from_index (*i).first; + if (circuit) { + circuits.push_back (circuit); + } + } + } + + return circuits; +} + std::vector NetlistBrowserPage::selected_subcircuits () { @@ -426,7 +459,9 @@ NetlistBrowserPage::selection_changed () std::vector subcircuits = selected_subcircuits (); - highlight (nets, devices, subcircuits); + std::vector circuits = selected_circuits (); + + highlight (nets, devices, subcircuits, circuits); } void @@ -682,7 +717,7 @@ NetlistBrowserPage::set_db (db::LayoutToNetlist *l2ndb) mp_database.reset (l2ndb); clear_markers (); - highlight (std::vector (), std::vector (), std::vector ()); + highlight (std::vector (), std::vector (), std::vector (), std::vector ()); if (! mp_database.get ()) { delete directory_tree->model (); @@ -764,17 +799,18 @@ NetlistBrowserPage::set_db (db::LayoutToNetlist *l2ndb) } void -NetlistBrowserPage::highlight (const std::vector &nets, const std::vector &devices, const std::vector &subcircuits) +NetlistBrowserPage::highlight (const std::vector &nets, const std::vector &devices, const std::vector &subcircuits, const std::vector &circuits) { - if (nets != m_current_nets || devices != m_current_devices || subcircuits != m_current_subcircuits) { + if (nets != m_current_nets || devices != m_current_devices || subcircuits != m_current_subcircuits || circuits != m_current_circuits) { m_current_nets = nets; m_current_devices = devices; m_current_subcircuits = subcircuits; + m_current_circuits = circuits; clear_markers (); - if (! nets.empty () || ! devices.empty () || ! subcircuits.empty ()) { + if (! nets.empty () || ! devices.empty () || ! subcircuits.empty () || ! circuits.empty ()) { adjust_view (); update_highlights (); } @@ -817,6 +853,16 @@ bbox_for_subcircuit (const db::Layout *layout, const db::SubCircuit *subcircuit) return layout->cell (subcircuit->circuit_ref ()->cell_index ()).bbox (); } +static db::Box +bbox_for_circuit (const db::Layout *layout, const db::Circuit *circuit) +{ + if (! layout->is_valid_cell_index (circuit->cell_index ())) { + return db::Box (); + } + + return layout->cell (circuit->cell_index ()).bbox (); +} + void NetlistBrowserPage::adjust_view () { @@ -834,15 +880,17 @@ NetlistBrowserPage::adjust_view () } const db::Layout *layout = mp_database->internal_layout (); - if (! layout) { + const db::Cell *cell = mp_database->internal_top_cell (); + if (! layout || ! cell) { return; } + db::Box bbox; for (std::vector::const_iterator net = m_current_nets.begin (); net != m_current_nets.end (); ++net) { - db::ICplxTrans net_trans = trans_for (*net, *mp_database->internal_layout (), *mp_database->internal_top_cell (), m_cell_context_cache); + db::ICplxTrans net_trans = trans_for (*net, *layout, *cell, m_cell_context_cache); db::cell_index_type cell_index = (*net)->circuit ()->cell_index (); size_t cluster_id = (*net)->cluster_id (); @@ -865,7 +913,7 @@ NetlistBrowserPage::adjust_view () for (std::vector::const_iterator device = m_current_devices.begin (); device != m_current_devices.end (); ++device) { - db::ICplxTrans trans = trans_for (*device, *mp_database->internal_layout (), *mp_database->internal_top_cell (), m_cell_context_cache); + db::ICplxTrans trans = trans_for (*device, *layout, *cell, m_cell_context_cache, (*device)->trans ()); bbox += trans * bbox_for_device_abstract (layout, (*device)->device_abstract (), db::DCplxTrans ()); @@ -877,7 +925,11 @@ NetlistBrowserPage::adjust_view () } for (std::vector::const_iterator subcircuit = m_current_subcircuits.begin (); subcircuit != m_current_subcircuits.end (); ++subcircuit) { - bbox += trans_for (*subcircuit, *mp_database->internal_layout (), *mp_database->internal_top_cell (), m_cell_context_cache) * bbox_for_subcircuit (layout, *subcircuit); + bbox += trans_for (*subcircuit, *layout, *cell, m_cell_context_cache, (*subcircuit)->trans ()) * bbox_for_subcircuit (layout, *subcircuit); + } + + for (std::vector::const_iterator circuit = m_current_circuits.begin (); circuit != m_current_circuits.end (); ++circuit) { + bbox += trans_for (*circuit, *layout, *cell, m_cell_context_cache, db::DCplxTrans ()) * bbox_for_circuit (layout, *circuit); } if (! bbox.empty ()) { @@ -943,6 +995,7 @@ NetlistBrowserPage::produce_highlights_for_device (const db::Device *device, siz mp_markers.back ()->set (device_bbox, device_trans, tv); mp_markers.back ()->set_color (color); mp_markers.back ()->set_frame_color (color); + configure_marker (mp_markers.back (), false); } @@ -962,6 +1015,7 @@ NetlistBrowserPage::produce_highlights_for_device (const db::Device *device, siz mp_markers.back ()->set (da_box, device_trans, tv); mp_markers.back ()->set_color (color); mp_markers.back ()->set_frame_color (color); + configure_marker (mp_markers.back (), false); } @@ -993,6 +1047,35 @@ NetlistBrowserPage::produce_highlights_for_subcircuit (const db::SubCircuit *sub mp_markers.back ()->set (circuit_bbox, subcircuit_trans, tv); mp_markers.back ()->set_color (color); mp_markers.back ()->set_frame_color (color); + configure_marker (mp_markers.back (), false); + + return false; +} + +bool +NetlistBrowserPage::produce_highlights_for_circuit (const db::Circuit *circuit, size_t &n_markers, const std::vector &tv) +{ + const db::Layout *layout = mp_database->internal_layout (); + const db::Cell *cell = mp_database->internal_top_cell (); + db::ICplxTrans circuit_trans = trans_for (circuit, *layout, *cell, m_cell_context_cache, db::DCplxTrans ()); + + QColor color = make_valid_color (m_colorizer.marker_color ()); + db::Box circuit_bbox = bbox_for_circuit (layout, circuit); + if (circuit_bbox.empty ()) { + return false; + } + + if (n_markers == m_max_shape_count) { + return true; + } + + ++n_markers; + + mp_markers.push_back (new lay::Marker (mp_view, m_cv_index)); + mp_markers.back ()->set (circuit_bbox, circuit_trans, tv); + mp_markers.back ()->set_color (color); + mp_markers.back ()->set_frame_color (color); + configure_marker (mp_markers.back (), false); return false; } @@ -1051,21 +1134,7 @@ NetlistBrowserPage::produce_highlights_for_net (const db::Net *net, size_t &n_ma } - 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_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); - } + configure_marker (mp_markers.back (), true); ++shapes; ++n_markers; @@ -1077,6 +1146,26 @@ NetlistBrowserPage::produce_highlights_for_net (const db::Net *net, size_t &n_ma return false; } +void +NetlistBrowserPage::configure_marker (Marker *marker, bool with_fill) +{ + 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_halo >= 0) { + mp_markers.back ()->set_halo (m_marker_halo); + } + + if (m_marker_dither_pattern >= 0 && with_fill) { + mp_markers.back ()->set_dither_pattern (m_marker_dither_pattern); + } +} + void NetlistBrowserPage::update_highlights () { @@ -1134,6 +1223,10 @@ NetlistBrowserPage::update_highlights () } } + for (std::vector::const_iterator circuit = m_current_circuits.begin (); circuit != m_current_circuits.end () && ! not_all_shapes_are_shown; ++circuit) { + not_all_shapes_are_shown = produce_highlights_for_circuit (*circuit, n_markers, tv); + } + if (not_all_shapes_are_shown) { info_label->setText (tl::to_qstring ("

" + tl::to_string (QObject::tr ("Not all shapes are highlighted")) + diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.h b/src/laybasic/laybasic/layNetlistBrowserPage.h index 33ac4bec8..17924cded 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.h +++ b/src/laybasic/laybasic/layNetlistBrowserPage.h @@ -203,6 +203,7 @@ private: std::vector m_current_nets; std::vector m_current_devices; std::vector m_current_subcircuits; + std::vector m_current_circuits; lay::NetInfoDialog *mp_info_dialog; tl::DeferredMethod dm_update_highlights; db::ContextCache m_cell_context_cache; @@ -212,16 +213,19 @@ private: void navigate_to (void *id, bool forward = true); void adjust_view (); void clear_markers (); - void highlight (const std::vector &nets, const std::vector &devices, const std::vector &subcircuits); + void highlight (const std::vector &nets, const std::vector &devices, const std::vector &subcircuits, const std::vector &circuits); std::vector selected_nets (); std::vector selected_devices (); std::vector selected_subcircuits (); + std::vector selected_circuits (); void set_color_for_selected_nets (const QColor &color); void layer_list_changed (int); QColor make_valid_color (const QColor &color); bool produce_highlights_for_net(const db::Net *net, size_t &n_markers, const std::map &display_by_lp, const std::vector &tv); bool produce_highlights_for_device (const db::Device *device, size_t &n_markers, const std::vector &tv); bool produce_highlights_for_subcircuit (const db::SubCircuit *subcircuit, size_t &n_markers, const std::vector &tv); + bool produce_highlights_for_circuit (const db::Circuit *circuit, size_t &n_markers, const std::vector &tv); + void configure_marker (lay::Marker *marker, bool with_fill); void export_nets (const std::vector *nets); };