mirror of https://github.com/KLayout/klayout.git
WIP: PCell parameters are now remembered for each PCell name/library
This commit is contained in:
parent
4ffae9668e
commit
e8668ed092
|
|
@ -1,73 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>PCellParametersDialog</class>
|
|
||||||
<widget class="QDialog" name="PCellParametersDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>469</width>
|
|
||||||
<height>429</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>PCell Parameters</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="edt::PCellParametersPage" name="parameters" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDialogButtonBox" name="buttons">
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>edt::PCellParametersPage</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>edtPCellParametersPage.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttons</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>PCellParametersDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>321</x>
|
|
||||||
<y>405</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>337</x>
|
|
||||||
<y>423</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttons</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>PCellParametersDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>427</x>
|
|
||||||
<y>405</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>443</x>
|
|
||||||
<y>425</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
||||||
|
|
@ -41,7 +41,6 @@ FORMS = \
|
||||||
PolygonPropertiesPage.ui \
|
PolygonPropertiesPage.ui \
|
||||||
RoundCornerOptionsDialog.ui \
|
RoundCornerOptionsDialog.ui \
|
||||||
TextPropertiesPage.ui \
|
TextPropertiesPage.ui \
|
||||||
PCellParametersDialog.ui \
|
|
||||||
DistributeOptionsDialog.ui \
|
DistributeOptionsDialog.ui \
|
||||||
EditorOptionsInstPCellParam.ui
|
EditorOptionsInstPCellParam.ui
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ MainService::MainService (db::Manager *manager, lay::LayoutView *view, lay::Disp
|
||||||
: lay::Plugin (view),
|
: lay::Plugin (view),
|
||||||
lay::Editable (view),
|
lay::Editable (view),
|
||||||
db::Object (manager),
|
db::Object (manager),
|
||||||
|
dm_setup_pages (this, &MainService::do_setup_pages),
|
||||||
mp_view (view),
|
mp_view (view),
|
||||||
mp_root (root),
|
mp_root (root),
|
||||||
m_needs_update (false),
|
m_needs_update (false),
|
||||||
|
|
@ -2358,6 +2359,14 @@ private:
|
||||||
|
|
||||||
void
|
void
|
||||||
MainService::config_finalize ()
|
MainService::config_finalize ()
|
||||||
|
{
|
||||||
|
// It's important that the editor option pages are updated last - because the
|
||||||
|
// configuration change may trigger other configuration changes
|
||||||
|
dm_setup_pages ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MainService::do_setup_pages ()
|
||||||
{
|
{
|
||||||
setup_pages (view ());
|
setup_pages (view ());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,9 @@ public:
|
||||||
virtual void config_finalize ();
|
virtual void config_finalize ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// The deferred execution handler for the config_finalize event
|
||||||
|
tl::DeferredMethod<edt::MainService> dm_setup_pages;
|
||||||
|
|
||||||
// The layout view that this service is attached to
|
// The layout view that this service is attached to
|
||||||
lay::LayoutView *mp_view;
|
lay::LayoutView *mp_view;
|
||||||
lay::Dispatcher *mp_root;
|
lay::Dispatcher *mp_root;
|
||||||
|
|
@ -242,6 +245,7 @@ private:
|
||||||
lay::FlattenInstOptionsDialog *flatten_inst_options_dialog ();
|
lay::FlattenInstOptionsDialog *flatten_inst_options_dialog ();
|
||||||
edt::MakeCellOptionsDialog *make_cell_options_dialog ();
|
edt::MakeCellOptionsDialog *make_cell_options_dialog ();
|
||||||
edt::MakeArrayOptionsDialog *make_array_options_dialog ();
|
edt::MakeArrayOptionsDialog *make_array_options_dialog ();
|
||||||
|
void do_setup_pages ();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,8 @@ PCellParametersPage::init ()
|
||||||
mp_parameters_area = 0;
|
mp_parameters_area = 0;
|
||||||
|
|
||||||
QGridLayout *frame_layout = new QGridLayout (this);
|
QGridLayout *frame_layout = new QGridLayout (this);
|
||||||
|
// spacing and margin for tool windows
|
||||||
|
frame_layout->setMargin (0);
|
||||||
setLayout (frame_layout);
|
setLayout (frame_layout);
|
||||||
|
|
||||||
mp_error_icon = new QLabel (this);
|
mp_error_icon = new QLabel (this);
|
||||||
|
|
@ -200,6 +202,7 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int
|
||||||
m_widgets.clear ();
|
m_widgets.clear ();
|
||||||
|
|
||||||
mp_parameters_area = new QScrollArea (this);
|
mp_parameters_area = new QScrollArea (this);
|
||||||
|
mp_parameters_area->setFrameShape (QFrame::NoFrame);
|
||||||
QGridLayout *frame_layout = dynamic_cast<QGridLayout *> (QFrame::layout ());
|
QGridLayout *frame_layout = dynamic_cast<QGridLayout *> (QFrame::layout ());
|
||||||
frame_layout->addWidget (mp_parameters_area, 0, 0, 1, 2);
|
frame_layout->addWidget (mp_parameters_area, 0, 0, 1, 2);
|
||||||
frame_layout->setRowStretch (0, 1);
|
frame_layout->setRowStretch (0, 1);
|
||||||
|
|
@ -211,6 +214,9 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int
|
||||||
|
|
||||||
QGridLayout *inner_grid = new QGridLayout (inner_frame);
|
QGridLayout *inner_grid = new QGridLayout (inner_frame);
|
||||||
inner_frame->setLayout (inner_grid);
|
inner_frame->setLayout (inner_grid);
|
||||||
|
inner_grid->setMargin (4);
|
||||||
|
inner_grid->setHorizontalSpacing (6);
|
||||||
|
inner_grid->setVerticalSpacing (2);
|
||||||
|
|
||||||
QWidget *main_frame = inner_frame;
|
QWidget *main_frame = inner_frame;
|
||||||
QGridLayout *main_grid = inner_grid;
|
QGridLayout *main_grid = inner_grid;
|
||||||
|
|
@ -247,6 +253,9 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int
|
||||||
main_grid->addWidget (gb, main_row, 0, 1, 2);
|
main_grid->addWidget (gb, main_row, 0, 1, 2);
|
||||||
|
|
||||||
inner_grid = new QGridLayout (gb);
|
inner_grid = new QGridLayout (gb);
|
||||||
|
inner_grid->setMargin (4);
|
||||||
|
inner_grid->setHorizontalSpacing (6);
|
||||||
|
inner_grid->setVerticalSpacing (2);
|
||||||
gb->setLayout (inner_grid);
|
gb->setLayout (inner_grid);
|
||||||
inner_frame = gb;
|
inner_frame = gb;
|
||||||
|
|
||||||
|
|
@ -286,6 +295,7 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int
|
||||||
QHBoxLayout *hb = new QHBoxLayout (f);
|
QHBoxLayout *hb = new QHBoxLayout (f);
|
||||||
hb->setMargin (0);
|
hb->setMargin (0);
|
||||||
f->setLayout (hb);
|
f->setLayout (hb);
|
||||||
|
f->setFrameShape (QFrame::NoFrame);
|
||||||
|
|
||||||
QLineEdit *le = new QLineEdit (f);
|
QLineEdit *le = new QLineEdit (f);
|
||||||
le->setEnabled (! p->is_readonly ());
|
le->setEnabled (! p->is_readonly ());
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,12 @@ Service::snap2 (const db::DPoint &p, const db::DPoint &plast, bool connect) cons
|
||||||
return lay::obj_snap (m_snap_to_objects ? view () : 0, plast, p, m_edit_grid == db::DVector () ? m_global_grid : m_edit_grid, connect ? connect_ac () : move_ac (), snap_range).second;
|
return lay::obj_snap (m_snap_to_objects ? view () : 0, plast, p, m_edit_grid == db::DVector () ? m_global_grid : m_edit_grid, connect ? connect_ac () : move_ac (), snap_range).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Service::service_configuration_changed ()
|
||||||
|
{
|
||||||
|
// The base class implementation does nothing
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Service::configure (const std::string &name, const std::string &value)
|
Service::configure (const std::string &name, const std::string &value)
|
||||||
{
|
{
|
||||||
|
|
@ -238,27 +244,58 @@ Service::configure (const std::string &name, const std::string &value)
|
||||||
edt::ACConverter acc;
|
edt::ACConverter acc;
|
||||||
|
|
||||||
if (name == cfg_edit_global_grid) {
|
if (name == cfg_edit_global_grid) {
|
||||||
|
|
||||||
egc.from_string (value, m_global_grid);
|
egc.from_string (value, m_global_grid);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
} else if (name == cfg_edit_show_shapes_of_instances) {
|
} else if (name == cfg_edit_show_shapes_of_instances) {
|
||||||
|
|
||||||
tl::from_string (value, m_show_shapes_of_instances);
|
tl::from_string (value, m_show_shapes_of_instances);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
} else if (name == cfg_edit_max_shapes_of_instances) {
|
} else if (name == cfg_edit_max_shapes_of_instances) {
|
||||||
|
|
||||||
tl::from_string (value, m_max_shapes_of_instances);
|
tl::from_string (value, m_max_shapes_of_instances);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
} else if (name == cfg_edit_grid) {
|
} else if (name == cfg_edit_grid) {
|
||||||
|
|
||||||
egc.from_string (value, m_edit_grid);
|
egc.from_string (value, m_edit_grid);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
return true; // taken
|
return true; // taken
|
||||||
|
|
||||||
} else if (name == cfg_edit_snap_to_objects) {
|
} else if (name == cfg_edit_snap_to_objects) {
|
||||||
|
|
||||||
tl::from_string (value, m_snap_to_objects);
|
tl::from_string (value, m_snap_to_objects);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
return true; // taken
|
return true; // taken
|
||||||
|
|
||||||
} else if (name == cfg_edit_move_angle_mode) {
|
} else if (name == cfg_edit_move_angle_mode) {
|
||||||
|
|
||||||
acc.from_string (value, m_move_ac);
|
acc.from_string (value, m_move_ac);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
return true; // taken
|
return true; // taken
|
||||||
|
|
||||||
} else if (name == cfg_edit_connect_angle_mode) {
|
} else if (name == cfg_edit_connect_angle_mode) {
|
||||||
|
|
||||||
acc.from_string (value, m_connect_ac);
|
acc.from_string (value, m_connect_ac);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
return true; // taken
|
return true; // taken
|
||||||
|
|
||||||
} else if (name == cfg_edit_top_level_selection) {
|
} else if (name == cfg_edit_top_level_selection) {
|
||||||
|
|
||||||
tl::from_string (value, m_top_level_sel);
|
tl::from_string (value, m_top_level_sel);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
} else if (name == cfg_edit_hier_copy_mode) {
|
} else if (name == cfg_edit_hier_copy_mode) {
|
||||||
|
|
||||||
tl::from_string (value, m_hier_copy_mode);
|
tl::from_string (value, m_hier_copy_mode);
|
||||||
|
service_configuration_changed ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // not taken
|
return false; // not taken
|
||||||
|
|
|
||||||
|
|
@ -455,6 +455,11 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void do_cancel_edit () { }
|
virtual void do_cancel_edit () { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when a configuration parameter provided by the service base class has changed
|
||||||
|
*/
|
||||||
|
virtual void service_configuration_changed ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Install a marker for representing the edited object
|
* @brief Install a marker for representing the edited object
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1288,10 +1288,6 @@ InstService::do_begin_edit (const db::DPoint &p)
|
||||||
m_trans = db::VCplxTrans (1.0 / cv->layout ().dbu ()) * tv [0] * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ();
|
m_trans = db::VCplxTrans (1.0 / cv->layout ().dbu ()) * tv [0] * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ();
|
||||||
}
|
}
|
||||||
|
|
||||||
lay::Marker *marker = new lay::Marker (view (), m_cv_index, ! show_shapes_of_instances (), show_shapes_of_instances () ? max_shapes_of_instances () : 0);
|
|
||||||
marker->set_vertex_shape (lay::ViewOp::Cross);
|
|
||||||
marker->set_vertex_size (9 /*cross vertex size*/);
|
|
||||||
set_edit_marker (marker);
|
|
||||||
update_marker ();
|
update_marker ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1505,18 +1501,33 @@ InstService::do_cancel_edit ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InstService::service_configuration_changed ()
|
||||||
|
{
|
||||||
|
m_needs_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InstService::configure (const std::string &name, const std::string &value)
|
InstService::configure (const std::string &name, const std::string &value)
|
||||||
{
|
{
|
||||||
if (name == cfg_edit_inst_cell_name) {
|
if (name == cfg_edit_inst_cell_name) {
|
||||||
|
|
||||||
|
if (value != m_cell_or_pcell_name) {
|
||||||
m_cell_or_pcell_name = value;
|
m_cell_or_pcell_name = value;
|
||||||
m_needs_update = true;
|
m_needs_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
return true; // taken
|
return true; // taken
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name == cfg_edit_inst_lib_name) {
|
if (name == cfg_edit_inst_lib_name) {
|
||||||
|
|
||||||
|
if (value != m_lib_name) {
|
||||||
|
m_lib_name_previous = m_lib_name;
|
||||||
m_lib_name = value;
|
m_lib_name = value;
|
||||||
m_needs_update = true;
|
m_needs_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
return true; // taken
|
return true; // taken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1603,9 +1614,58 @@ void
|
||||||
InstService::config_finalize ()
|
InstService::config_finalize ()
|
||||||
{
|
{
|
||||||
if (m_needs_update) {
|
if (m_needs_update) {
|
||||||
|
|
||||||
|
// if the library or cell name has changed, store the current pcell parameters and try to reuse
|
||||||
|
// an existing parameter set
|
||||||
|
if (! m_cell_or_pcell_name_previous.empty () && (m_cell_or_pcell_name_previous != m_cell_or_pcell_name || m_lib_name_previous != m_lib_name)) {
|
||||||
|
|
||||||
|
m_stored_pcell_parameters[std::make_pair (m_cell_or_pcell_name_previous, m_lib_name_previous)] = m_pcell_parameters;
|
||||||
|
|
||||||
|
std::map<std::pair<std::string, std::string>, std::map<std::string, tl::Variant> >::const_iterator p = m_stored_pcell_parameters.find (std::make_pair (m_cell_or_pcell_name, m_lib_name));
|
||||||
|
if (p != m_stored_pcell_parameters.end ()) {
|
||||||
|
m_pcell_parameters = p->second;
|
||||||
|
} else {
|
||||||
|
m_pcell_parameters.clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_is_pcell = false;
|
||||||
|
|
||||||
|
const lay::CellView &cv = view ()->cellview (m_cv_index);
|
||||||
|
if (cv.is_valid ()) {
|
||||||
|
|
||||||
|
db::Library *lib = db::LibraryManager::instance ().lib_ptr_by_name (m_lib_name);
|
||||||
|
|
||||||
|
// find the layout the cell has to be looked up: that is either the layout of the current instance or
|
||||||
|
// the library selected
|
||||||
|
const db::Layout *layout;
|
||||||
|
if (lib) {
|
||||||
|
layout = &lib->layout ();
|
||||||
|
} else {
|
||||||
|
layout = &cv->layout ();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_is_pcell = layout->pcell_by_name (m_cell_or_pcell_name.c_str ()).first;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
m_has_valid_cell = false;
|
m_has_valid_cell = false;
|
||||||
update_marker ();
|
update_marker (); // NOTE: sets m_is_pcell
|
||||||
m_needs_update = false;
|
m_needs_update = false;
|
||||||
|
|
||||||
|
// remember the current cell or library name
|
||||||
|
m_cell_or_pcell_name_previous = m_cell_or_pcell_name;
|
||||||
|
m_lib_name_previous = m_lib_name;
|
||||||
|
|
||||||
|
// Reflects any changes in PCell parameters induced by reuse of make_cell (called from update_marker)
|
||||||
|
// in the configuration
|
||||||
|
if (m_is_pcell) {
|
||||||
|
dispatcher ()->config_set (cfg_edit_inst_pcell_parameters, pcell_parameters_to_string (m_pcell_parameters));
|
||||||
|
} else {
|
||||||
|
dispatcher ()->config_set (cfg_edit_inst_pcell_parameters, std::string ());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
edt::Service::config_finalize ();
|
edt::Service::config_finalize ();
|
||||||
|
|
@ -1614,13 +1674,16 @@ InstService::config_finalize ()
|
||||||
void
|
void
|
||||||
InstService::update_marker ()
|
InstService::update_marker ()
|
||||||
{
|
{
|
||||||
lay::Marker *marker = dynamic_cast<lay::Marker *> (edit_marker ());
|
lay::Marker *marker = new lay::Marker (view (), m_cv_index, ! show_shapes_of_instances (), show_shapes_of_instances () ? max_shapes_of_instances () : 0);
|
||||||
if (marker) {
|
marker->set_vertex_shape (lay::ViewOp::Cross);
|
||||||
marker->set ();
|
marker->set_vertex_size (9 /*cross vertex size*/);
|
||||||
|
set_edit_marker (marker);
|
||||||
|
|
||||||
db::CellInstArray inst;
|
db::CellInstArray inst;
|
||||||
if (get_inst (inst)) {
|
if (get_inst (inst)) {
|
||||||
marker->set (inst, m_trans);
|
marker->set (inst, m_trans);
|
||||||
}
|
} else {
|
||||||
|
marker->set ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,8 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool configure (const std::string &name, const std::string &value);
|
bool configure (const std::string &name, const std::string &value);
|
||||||
|
void service_configuration_changed ();
|
||||||
|
|
||||||
void config_finalize ();
|
void config_finalize ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -228,7 +230,9 @@ private:
|
||||||
bool m_mirror;
|
bool m_mirror;
|
||||||
db::DPoint m_disp;
|
db::DPoint m_disp;
|
||||||
std::string m_cell_or_pcell_name, m_lib_name;
|
std::string m_cell_or_pcell_name, m_lib_name;
|
||||||
|
std::string m_cell_or_pcell_name_previous, m_lib_name_previous;
|
||||||
std::map<std::string, tl::Variant> m_pcell_parameters;
|
std::map<std::string, tl::Variant> m_pcell_parameters;
|
||||||
|
std::map<std::pair<std::string, std::string>, std::map<std::string, tl::Variant> > m_stored_pcell_parameters;
|
||||||
bool m_is_pcell;
|
bool m_is_pcell;
|
||||||
bool m_array;
|
bool m_array;
|
||||||
unsigned int m_rows, m_columns;
|
unsigned int m_rows, m_columns;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue