mirror of https://github.com/KLayout/klayout.git
WIP: library browser - PCell variants as children of PCells
This commit is contained in:
parent
0c18171e63
commit
4428ef808b
|
|
@ -51,6 +51,7 @@ class DB_PUBLIC PCellHeader
|
|||
{
|
||||
public:
|
||||
typedef std::map<const pcell_parameters_type *, db::PCellVariant *, PCellParametersCompareFunc> 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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "layLayoutView.h"
|
||||
#include "tlGlobPattern.h"
|
||||
#include "dbPCellHeader.h"
|
||||
#include "dbPCellVariant.h"
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QPalette>
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 <size_t>::max () : (size_t) lib_index);
|
||||
|
||||
// rebuild all events
|
||||
detach_from_all_events ();
|
||||
db::LibraryManager::instance ().changed_event.add (this, &LibrariesView::update_required);
|
||||
|
||||
std::vector<db::Library *> 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 <CellTreeModel *> (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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue