From 4428ef808b8392704f8f106a3b9c449b1db11264 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 1 Aug 2019 22:52:20 +0200 Subject: [PATCH] WIP: library browser - PCell variants as children of PCells --- src/db/db/dbPCellHeader.h | 17 ++++++ src/lay/lay/layMainWindow.cc | 3 + src/laybasic/laybasic/layCellTreeModel.cc | 71 ++++++++++++++++++----- src/laybasic/laybasic/layCellTreeModel.h | 24 ++++---- src/laybasic/laybasic/layLibrariesView.cc | 13 +++-- 5 files changed, 97 insertions(+), 31 deletions(-) diff --git a/src/db/db/dbPCellHeader.h b/src/db/db/dbPCellHeader.h index e49a41f03..cbae06690 100644 --- a/src/db/db/dbPCellHeader.h +++ b/src/db/db/dbPCellHeader.h @@ -51,6 +51,7 @@ class DB_PUBLIC PCellHeader { public: typedef std::map variant_map_t; + typedef variant_map_t::const_iterator variant_iterator; /** * @brief The default constructor @@ -112,6 +113,22 @@ public: */ void register_variant (PCellVariant *variant); + /** + * @brief Iterates the variants (begin) + */ + variant_iterator begin () const + { + return m_variant_map.begin (); + } + + /** + * @brief Iterates the variants (end) + */ + variant_iterator end () const + { + return m_variant_map.end (); + } + /** * @brief Get the PCell Id for this variant */ diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 31f3d8ce3..67475dff5 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -1248,6 +1248,7 @@ MainWindow::close_all () mp_views.pop_back (); mp_lp_stack->removeWidget (mp_views.size ()); mp_hp_stack->removeWidget (mp_views.size ()); + mp_libs_stack->removeWidget (mp_views.size ()); mp_view_stack->removeWidget (mp_views.size ()); delete view; @@ -3299,6 +3300,7 @@ MainWindow::select_view (int index) mp_view_stack->raiseWidget (index); mp_hp_stack->raiseWidget (index); mp_lp_stack->raiseWidget (index); + mp_libs_stack->raiseWidget (index); mp_setup_form->setup (); } @@ -3970,6 +3972,7 @@ MainWindow::close_view (int index) mp_view_stack->removeWidget (index); mp_lp_stack->removeWidget (index); mp_hp_stack->removeWidget (index); + mp_libs_stack->removeWidget (index); view_closed_event (int (index)); diff --git a/src/laybasic/laybasic/layCellTreeModel.cc b/src/laybasic/laybasic/layCellTreeModel.cc index 1c39a2559..eede8efef 100644 --- a/src/laybasic/laybasic/layCellTreeModel.cc +++ b/src/laybasic/laybasic/layCellTreeModel.cc @@ -25,6 +25,7 @@ #include "layLayoutView.h" #include "tlGlobPattern.h" #include "dbPCellHeader.h" +#include "dbPCellVariant.h" #include #include @@ -82,8 +83,8 @@ struct cmp_cell_tree_item_vs_name_f // -------------------------------------------------------------------- // CellTreeItem implementation -CellTreeItem::CellTreeItem (const db::Layout *layout, CellTreeItem *parent, bool is_pcell, size_t cell_or_pcell_index, bool flat, CellTreeModel::Sorting s) - : mp_layout (layout), mp_parent (parent), m_sorting (s), m_is_pcell (is_pcell), m_index (0), m_children (), m_cell_or_pcell_index (cell_or_pcell_index) +CellTreeItem::CellTreeItem (const db::Layout *layout, bool is_pcell, size_t cell_or_pcell_index, bool flat, CellTreeModel::Sorting s) + : mp_layout (layout), mp_parent (0), m_sorting (s), m_is_pcell (is_pcell), m_index (0), m_children (), m_cell_or_pcell_index (cell_or_pcell_index) { if (! flat && ! is_pcell) { m_child_count = int (mp_layout->cell (cell_index ()).child_cells ()); @@ -100,6 +101,12 @@ CellTreeItem::~CellTreeItem () m_children.clear (); } +bool +CellTreeItem::is_valid () const +{ + return m_is_pcell || mp_layout->is_valid_cell_index (cell_index ()); +} + std::string CellTreeItem::display_text () const { @@ -130,21 +137,38 @@ CellTreeItem::child (int index) m_children.reserve (m_child_count); for (db::Cell::child_cell_iterator child = cell->begin_child_cells (); ! child.at_end (); ++child) { - CellTreeItem *child_item = new CellTreeItem (mp_layout, this, false, *child, false, m_sorting); - m_children.push_back (child_item); + add_child (new CellTreeItem (mp_layout, false, *child, false, m_sorting)); } - std::sort (m_children.begin (), m_children.end (), cmp_cell_tree_items_f (m_sorting)); - - for (size_t i = 0; i < m_children.size (); ++i) { - m_children [i]->set_index (i); - } + finish_children (); } return m_children [index]; } +void +CellTreeItem::add_child (CellTreeItem *item) +{ + // explicitly added + if (size_t (m_child_count) == m_children.size ()) { + ++m_child_count; + } + + item->mp_parent = this; + m_children.push_back (item); +} + +void +CellTreeItem::finish_children () +{ + std::sort (m_children.begin (), m_children.end (), cmp_cell_tree_items_f (m_sorting)); + + for (size_t i = 0; i < m_children.size (); ++i) { + m_children [i]->set_index (i); + } +} + db::cell_index_type CellTreeItem::cell_index () const { @@ -452,7 +476,7 @@ CellTreeModel::build_top_level () if (mp_base) { m_toplevel.reserve (mp_base->child_cells ()); for (db::Cell::child_cell_iterator child = mp_base->begin_child_cells (); ! child.at_end (); ++child) { - CellTreeItem *item = new CellTreeItem (mp_layout, 0, false, *child, true, m_sorting); + CellTreeItem *item = new CellTreeItem (mp_layout, false, *child, true, m_sorting); m_toplevel.push_back (item); } } @@ -464,7 +488,7 @@ CellTreeModel::build_top_level () if (mp_base) { m_toplevel.reserve (mp_base->parent_cells ()); for (db::Cell::parent_cell_iterator parent = mp_base->begin_parent_cells (); parent != mp_base->end_parent_cells (); ++parent) { - CellTreeItem *item = new CellTreeItem (mp_layout, 0, false, *parent, true, m_sorting); + CellTreeItem *item = new CellTreeItem (mp_layout, false, *parent, true, m_sorting); m_toplevel.push_back (item); } } @@ -479,11 +503,11 @@ CellTreeModel::build_top_level () while (top != mp_layout->end_top_down ()) { if (m_flat) { - CellTreeItem *item = new CellTreeItem (mp_layout, 0, false, *top, true, m_sorting); + CellTreeItem *item = new CellTreeItem (mp_layout, false, *top, true, m_sorting); m_toplevel.push_back (item); } else if (mp_layout->cell (*top).is_top ()) { if ((m_flags & BasicCells) == 0 || ! mp_layout->cell (*top).is_proxy ()) { - CellTreeItem *item = new CellTreeItem (mp_layout, 0, false, *top, (m_flags & TopCells) != 0, m_sorting); + CellTreeItem *item = new CellTreeItem (mp_layout, false, *top, (m_flags & TopCells) != 0, m_sorting); m_toplevel.push_back (item); } } else { @@ -495,10 +519,25 @@ CellTreeModel::build_top_level () } if ((m_flags & BasicCells) != 0) { + for (db::Layout::pcell_iterator pc = mp_layout->begin_pcells (); pc != mp_layout->end_pcells (); ++pc) { - CellTreeItem *item = new CellTreeItem (mp_layout, 0, true, pc->second, true, m_sorting); + + CellTreeItem *item = new CellTreeItem (mp_layout, true, pc->second, true, m_sorting); m_toplevel.push_back (item); + + if ((m_flags & WithVariants) != 0) { + + const db::PCellHeader *pcell_header = mp_layout->pcell_header (pc->second); + for (db::PCellHeader::variant_iterator v = pcell_header->begin (); v != pcell_header->end (); ++v) { + item->add_child (new CellTreeItem (mp_layout, false, v->second->cell_index (), true, m_sorting)); + } + + item->finish_children (); + + } + } + } } @@ -699,7 +738,7 @@ CellTreeModel::rowCount (const QModelIndex &parent) const CellTreeItem *item = (CellTreeItem *) parent.internalPointer (); if (! item) { return 0; - } else if (! mp_layout->is_valid_cell_index (item->cell_index ())) { + } else if (! item->is_valid ()) { // for safety we return 0 children for invalid cells return 0; } else { @@ -719,7 +758,7 @@ CellTreeModel::index (int row, int column, const QModelIndex &parent) const CellTreeItem *item = (CellTreeItem *) parent.internalPointer (); if (! item) { return QModelIndex (); - } else if (! mp_layout->is_valid_cell_index (item->cell_index ())) { + } else if (! item->is_valid ()) { // for safety we don't return valid child indexes for invalid cells return QModelIndex (); } else { diff --git a/src/laybasic/laybasic/layCellTreeModel.h b/src/laybasic/laybasic/layCellTreeModel.h index c0ceb0eff..0a72cba86 100644 --- a/src/laybasic/laybasic/layCellTreeModel.h +++ b/src/laybasic/laybasic/layCellTreeModel.h @@ -56,18 +56,19 @@ class CellTreeModel { public: enum Flags { - Flat = 1, // flat list (rather than hierarchy) - Children = 2, // direct children of cell "base" - Parents = 4, // direct parents of cell "base" - TopCells = 8, // show top cells only - BasicCells = 16, // show basic cells (PCells included, no proxies) - NoPadding = 32 // enable padding of display string with a blank at the beginning and end + Flat = 1, // flat list (rather than hierarchy) + Children = 2, // direct children of cell "base" + Parents = 4, // direct parents of cell "base" + TopCells = 8, // show top cells only + BasicCells = 16, // show basic cells (PCells included, no proxies) + WithVariants = 32, // show PCell variants below PCells + NoPadding = 64 // disable padding of display string with a blank at the beginning and end }; enum Sorting { - ByName, // sort by name - ByArea, // sort by cell area (small to large) - ByAreaReverse // sort by cell area (large to small) + ByName, // sort by name + ByArea, // sort by cell area (small to large) + ByAreaReverse // sort by cell area (large to small) }; /** @@ -247,7 +248,7 @@ private: class CellTreeItem { public: - CellTreeItem (const db::Layout *layout, CellTreeItem *parent, bool is_pcell, size_t cell_or_pcell_index, bool flat, CellTreeModel::Sorting sorting); + CellTreeItem (const db::Layout *layout, bool is_pcell, size_t cell_or_pcell_index, bool flat, CellTreeModel::Sorting sorting); ~CellTreeItem (); int children () const; @@ -261,6 +262,9 @@ public: bool name_equals (const char *name) const; bool name_matches (const tl::GlobPattern &p) const; std::string display_text () const; + void add_child (CellTreeItem *item); + void finish_children (); + bool is_valid () const; bool is_pcell () const { diff --git a/src/laybasic/laybasic/layLibrariesView.cc b/src/laybasic/laybasic/layLibrariesView.cc index 0485c5f87..e43dc03a3 100644 --- a/src/laybasic/laybasic/layLibrariesView.cc +++ b/src/laybasic/laybasic/layLibrariesView.cc @@ -333,8 +333,6 @@ LibrariesView::LibrariesView (lay::LayoutView *view, QWidget *parent, const char sp.setVerticalStretch (0); setSizePolicy (sp); - db::LibraryManager::instance ().changed_event.add (this, &LibrariesView::update_required); - do_update_content (); } @@ -714,9 +712,14 @@ LibrariesView::do_update_content (int lib_index) size_t imin = (lib_index < 0 ? 0 : (size_t) lib_index); size_t imax = (lib_index < 0 ? std::numeric_limits ::max () : (size_t) lib_index); + // rebuild all events + detach_from_all_events (); + db::LibraryManager::instance ().changed_event.add (this, &LibrariesView::update_required); + std::vector libraries; for (db::LibraryManager::iterator lib = db::LibraryManager::instance ().begin (); lib != db::LibraryManager::instance ().end (); ++lib) { libraries.push_back (db::LibraryManager::instance ().lib (lib->second)); + libraries.back ()->layout ().hier_changed_event.add (this, &LibrariesView::update_required); } for (size_t i = imin; i < libraries.size () && i <= imax; ++i) { @@ -791,7 +794,7 @@ LibrariesView::do_update_content (int lib_index) LibraryTreeWidget *cell_list = new LibraryTreeWidget (cl_frame, "tree", mp_view->view_object_widget ()); cl_ly->addWidget (cell_list); - cell_list->setModel (new CellTreeModel (cell_list, &m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells, 0)); + cell_list->setModel (new CellTreeModel (cell_list, &m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0)); cell_list->setUniformRowHeights (true); pl = cell_list->palette (); @@ -805,7 +808,7 @@ LibrariesView::do_update_content (int lib_index) cell_list->header ()->hide (); cell_list->setSelectionMode (QTreeView::ExtendedSelection); - cell_list->setRootIsDecorated (false); + cell_list->setRootIsDecorated (true); cell_list->setContextMenuPolicy (Qt::CustomContextMenu); connect (cell_list, SIGNAL (customContextMenuRequested (const QPoint &)), this, SLOT (context_menu (const QPoint &))); @@ -866,7 +869,7 @@ LibrariesView::do_update_content (int lib_index) CellTreeModel *model = dynamic_cast (mp_cell_lists [i]->model ()); if (model) { - model->configure (& m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells, 0); + model->configure (& m_libraries [i]->layout (), CellTreeModel::Flat | CellTreeModel::TopCells | CellTreeModel::BasicCells | CellTreeModel::WithVariants, 0); } }