mirror of https://github.com/KLayout/klayout.git
Fixed #73 (allow 'change layers' on PCells which support a single layer parameter)
This commit is contained in:
parent
fb69dfd866
commit
363c0c9fed
|
|
@ -1884,6 +1884,26 @@ Layout::is_pcell_instance (cell_index_type cell_index) const
|
|||
}
|
||||
}
|
||||
|
||||
const Layout::pcell_declaration_type *
|
||||
Layout::pcell_declaration_for_pcell_variant (cell_index_type variant_cell_index) const
|
||||
{
|
||||
const Cell *variant_cell = &cell (variant_cell_index);
|
||||
|
||||
const LibraryProxy *lib_proxy = dynamic_cast<const LibraryProxy *> (variant_cell);
|
||||
if (lib_proxy) {
|
||||
Library *lib = LibraryManager::instance ().lib (lib_proxy->lib_id ());
|
||||
tl_assert (lib != 0);
|
||||
return lib->layout ().pcell_declaration_for_pcell_variant (lib_proxy->library_cell_index ());
|
||||
}
|
||||
|
||||
const PCellVariant *pcell_variant = dynamic_cast<const PCellVariant *> (variant_cell);
|
||||
if (pcell_variant) {
|
||||
return pcell_declaration (pcell_variant->pcell_id ());
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<db::Library *, db::cell_index_type>
|
||||
Layout::defining_library (cell_index_type cell_index) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -881,11 +881,22 @@ public:
|
|||
*/
|
||||
std::pair<db::Library *, db::cell_index_type> defining_library (cell_index_type cell_index) const;
|
||||
|
||||
/**
|
||||
* @brief Gets the PCell declaration object for a PCell instance
|
||||
*
|
||||
* This method determines the PCell declaration object for a given PCell variant cell.
|
||||
* Note, that the declaration may originate from a different layout than this, if the PCell
|
||||
* is imported from a library.
|
||||
*
|
||||
* The cell given cell is not a PCell variant cell, 0 is returned.
|
||||
*/
|
||||
const Layout::pcell_declaration_type *pcell_declaration_for_pcell_variant (cell_index_type cell_index) const;
|
||||
|
||||
/**
|
||||
* @brief Get the PCell parameters of a PCell instance
|
||||
*
|
||||
* For the order of the parameters, ask the PCell declaration (available trough Layout::pcell_declaration
|
||||
* from the PCell id).
|
||||
* from the PCell id or from Layout::pcell_declaration_for_pcell_variant from the cell_index).
|
||||
*
|
||||
* @return A list of parameters in the order they are declared.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1906,12 +1906,10 @@ MainService::cm_change_layer ()
|
|||
// get (common) cellview index of the selected shapes
|
||||
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
|
||||
for (edt::Service::obj_iterator s = (*es)->selection ().begin (); s != (*es)->selection ().end (); ++s) {
|
||||
if (! s->is_cell_inst ()) {
|
||||
if (cv_index >= 0 && cv_index != int (s->cv_index ())) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Selections originate from different layouts - cannot switch layer in this case.")));
|
||||
}
|
||||
cv_index = int (s->cv_index ());
|
||||
if (cv_index >= 0 && cv_index != int (s->cv_index ())) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Selections originate from different layouts - cannot switch layer in this case.")));
|
||||
}
|
||||
cv_index = int (s->cv_index ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1975,17 +1973,58 @@ MainService::cm_change_layer ()
|
|||
// Insert and delete the shape. This exploits the fact, that a shape can be erased multiple times -
|
||||
// this is important since the selection potentially contains the same shape multiple times.
|
||||
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
|
||||
|
||||
for (edt::Service::obj_iterator s = (*es)->selection ().begin (); s != (*es)->selection ().end (); ++s) {
|
||||
|
||||
if (!s->is_cell_inst () && int (s->layer ()) != layer) {
|
||||
|
||||
db::Cell &cell = layout.cell (s->cell_index ());
|
||||
if (cell.shapes (s->layer ()).is_valid (s->shape ())) {
|
||||
cell.shapes (layer).insert (s->shape ());
|
||||
cell.shapes (s->layer ()).erase_shape (s->shape ());
|
||||
}
|
||||
|
||||
} else if (s->is_cell_inst ()) {
|
||||
|
||||
// If the selected object is a PCell instance, and there is exactly one visible, writable layer type parameter, change this one
|
||||
|
||||
db::Instance inst = s->back ().inst_ptr;
|
||||
db::Cell &cell = layout.cell (s->cell_index ());
|
||||
|
||||
if (cell.is_valid (inst)) {
|
||||
|
||||
const db::PCellDeclaration *pcell_decl = layout.pcell_declaration_for_pcell_variant (inst.cell_index ());
|
||||
if (pcell_decl) {
|
||||
|
||||
size_t layer_par_index = 0;
|
||||
int n_layer_par = 0;
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator d = pcell_decl->parameter_declarations ().begin (); d != pcell_decl->parameter_declarations ().end () && n_layer_par < 2; ++d) {
|
||||
if (d->get_type () == db::PCellParameterDeclaration::t_layer && !d->is_hidden () && !d->is_readonly ()) {
|
||||
++n_layer_par;
|
||||
layer_par_index = size_t (d - pcell_decl->parameter_declarations ().begin ());
|
||||
}
|
||||
}
|
||||
|
||||
if (n_layer_par == 1) {
|
||||
std::vector<tl::Variant> parameters = cell.get_pcell_parameters (inst);
|
||||
tl_assert (layer_par_index < parameters.size ());
|
||||
parameters [layer_par_index] = layout.get_properties (layer);
|
||||
cell.change_pcell_parameters (inst, parameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remove superfluous proxies
|
||||
layout.cleanup ();
|
||||
|
||||
// The selection is no longer valid
|
||||
view ()->clear_selection ();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue