mirror of https://github.com/KLayout/klayout.git
WIP: recent configurations for instances, some bug fixes there. Views now reset tool if the tab changes.
This commit is contained in:
parent
399e4f4fc7
commit
9a19ced4e0
|
|
@ -88,20 +88,19 @@ void get_inst_options (std::vector < std::pair<std::string, std::string> > &opti
|
|||
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor inst_cfg_descriptors[] =
|
||||
{
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_lib_name, tl::to_string (tr ("Library")), edt::RecentConfigurationPage::Text),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_cell_name, tl::to_string (tr ("Cell")), edt::RecentConfigurationPage::Text),
|
||||
// encode this into the cell?
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_pcell_parameters, tl::to_string (tr ("PCell parameters")), edt::RecentConfigurationPage::PCellParamters),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_lib_name, tl::to_string (tr ("Library")), edt::RecentConfigurationPage::CellLibraryName),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_cell_name, tl::to_string (tr ("Cell")), edt::RecentConfigurationPage::CellDisplayName),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_angle, tl::to_string (tr ("Angle")), edt::RecentConfigurationPage::Double),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_mirror, tl::to_string (tr ("Mirror")), edt::RecentConfigurationPage::Bool),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_scale, tl::to_string (tr ("Scale")), edt::RecentConfigurationPage::Double),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_array, tl::to_string (tr ("Array")), edt::RecentConfigurationPage::Bool),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_rows, tl::to_string (tr ("Rows")), edt::RecentConfigurationPage::Double),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_row_x, tl::to_string (tr ("Row step (x)")), edt::RecentConfigurationPage::Double),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_row_y, tl::to_string (tr ("Row step (y)")), edt::RecentConfigurationPage::Double),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_columns, tl::to_string (tr ("Columns")), edt::RecentConfigurationPage::Double),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_column_x, tl::to_string (tr ("Column step (x)")), edt::RecentConfigurationPage::Double),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_column_y, tl::to_string (tr ("Column step (y)")), edt::RecentConfigurationPage::Double)
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_array, tl::to_string (tr ("Array")), edt::RecentConfigurationPage::ArrayFlag),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_rows, tl::to_string (tr ("Rows")), edt::RecentConfigurationPage::IntIfArray),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_row_x, tl::to_string (tr ("Row step (x)")), edt::RecentConfigurationPage::DoubleIfArray),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_row_y, tl::to_string (tr ("Row step (y)")), edt::RecentConfigurationPage::DoubleIfArray),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_columns, tl::to_string (tr ("Columns")), edt::RecentConfigurationPage::IntIfArray),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_column_x, tl::to_string (tr ("Column step (x)")), edt::RecentConfigurationPage::DoubleIfArray),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_column_y, tl::to_string (tr ("Column step (y)")), edt::RecentConfigurationPage::DoubleIfArray),
|
||||
edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_pcell_parameters, tl::to_string (tr ("PCell parameters")), edt::RecentConfigurationPage::PCellParameters)
|
||||
};
|
||||
|
||||
static
|
||||
|
|
|
|||
|
|
@ -21,10 +21,14 @@
|
|||
*/
|
||||
|
||||
#include "edtRecentConfigurationPage.h"
|
||||
#include "edtUtils.h"
|
||||
#include "layDispatcher.h"
|
||||
#include "dbLibraryManager.h"
|
||||
#include "dbLibrary.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
|
||||
namespace edt
|
||||
{
|
||||
|
|
@ -37,11 +41,19 @@ RecentConfigurationPage::init ()
|
|||
QVBoxLayout *ly = new QVBoxLayout (this);
|
||||
ly->setMargin (0);
|
||||
|
||||
QLabel *label = new QLabel (this);
|
||||
label->setText (tr ("Click to select a recent configuration"));
|
||||
ly->addWidget (label);
|
||||
|
||||
mp_tree_widget = new QTreeWidget (this);
|
||||
mp_tree_widget->setRootIsDecorated (false);
|
||||
mp_tree_widget->setUniformRowHeights (true);
|
||||
mp_tree_widget->setSelectionMode (QAbstractItemView::NoSelection);
|
||||
mp_tree_widget->setAllColumnsShowFocus (true);
|
||||
ly->addWidget (mp_tree_widget);
|
||||
|
||||
connect (mp_tree_widget, SIGNAL (itemClicked (QTreeWidgetItem *, int)), this, SLOT (item_clicked (QTreeWidgetItem *)));
|
||||
|
||||
mp_tree_widget->setColumnCount (int (m_cfg.size ()));
|
||||
|
||||
QStringList column_labels;
|
||||
|
|
@ -107,13 +119,112 @@ RecentConfigurationPage::set_stored_values (const std::list<std::vector<std::str
|
|||
}
|
||||
|
||||
void
|
||||
render_to (QTreeWidgetItem *item, int column, const std::string &v, RecentConfigurationPage::ConfigurationRendering rendering)
|
||||
RecentConfigurationPage::render_to (QTreeWidgetItem *item, int column, const std::vector<std::string> &values, RecentConfigurationPage::ConfigurationRendering rendering)
|
||||
{
|
||||
// store original value
|
||||
item->setData (column, Qt::UserRole, tl::to_qstring (v));
|
||||
item->setData (column, Qt::UserRole, tl::to_qstring (values [column]));
|
||||
|
||||
// @@@ rendering
|
||||
item->setText (column, tl::to_qstring (v));
|
||||
switch (rendering) {
|
||||
|
||||
case RecentConfigurationPage::ArrayFlag:
|
||||
case RecentConfigurationPage::Bool:
|
||||
{
|
||||
bool f = false;
|
||||
tl::from_string (values [column], f);
|
||||
static QString checkmark = QString::fromUtf8 ("\xe2\x9c\x93");
|
||||
item->setText (column, f ? checkmark : QString ()); // "checkmark"
|
||||
}
|
||||
break;
|
||||
|
||||
case RecentConfigurationPage::Layer:
|
||||
// @@@
|
||||
item->setText (column, tl::to_qstring (values [column]));
|
||||
break;
|
||||
|
||||
case RecentConfigurationPage::Int:
|
||||
case RecentConfigurationPage::Double:
|
||||
case RecentConfigurationPage::Text:
|
||||
case RecentConfigurationPage::CellLibraryName:
|
||||
item->setText (column, tl::to_qstring (values [column]));
|
||||
break;
|
||||
|
||||
case RecentConfigurationPage::IntIfArray:
|
||||
case RecentConfigurationPage::DoubleIfArray:
|
||||
{
|
||||
bool is_array = false;
|
||||
int flag_column = 0;
|
||||
for (std::list<ConfigurationDescriptor>::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++flag_column) {
|
||||
if (c->rendering == RecentConfigurationPage::ArrayFlag) {
|
||||
tl::from_string (values [flag_column], is_array);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array) {
|
||||
item->setText (column, tl::to_qstring (values [column]));
|
||||
} else {
|
||||
item->setText (column, QString ());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RecentConfigurationPage::CellDisplayName:
|
||||
{
|
||||
// search for a libname
|
||||
int libname_column = 0;
|
||||
const db::Library *lib = 0;
|
||||
for (std::list<ConfigurationDescriptor>::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++libname_column) {
|
||||
if (c->rendering == RecentConfigurationPage::CellLibraryName) {
|
||||
lib = db::LibraryManager::instance ().lib_ptr_by_name (values [libname_column]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lib) {
|
||||
|
||||
// search for a PCell parameters
|
||||
int pcp_column = 0;
|
||||
std::map<std::string, tl::Variant> pcp;
|
||||
for (std::list<ConfigurationDescriptor>::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++pcp_column) {
|
||||
if (c->rendering == RecentConfigurationPage::PCellParameters) {
|
||||
pcp = pcell_parameters_from_string (values [pcp_column]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool, db::Layout::pcell_id_type> pcid = lib->layout ().pcell_by_name (values [column].c_str ());
|
||||
if (pcid.first) {
|
||||
const db::PCellDeclaration *pc_decl = lib->layout ().pcell_declaration (pcid.second);
|
||||
if (pc_decl) {
|
||||
item->setText (column, tl::to_qstring (pc_decl->get_display_name (pc_decl->map_parameters (pcp))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
item->setText (column, tl::to_qstring (values [column]));
|
||||
}
|
||||
break;
|
||||
|
||||
case RecentConfigurationPage::PCellParameters:
|
||||
{
|
||||
std::map<std::string, tl::Variant> pcp;
|
||||
pcp = pcell_parameters_from_string (values [column]);
|
||||
std::string r;
|
||||
for (std::map<std::string, tl::Variant>::const_iterator p = pcp.begin (); p != pcp.end (); ++p) {
|
||||
if (p != pcp.begin ()) {
|
||||
r += ",";
|
||||
}
|
||||
r += p->first;
|
||||
r += "=";
|
||||
r += p->second.to_string ();
|
||||
}
|
||||
|
||||
item->setText (column, tl::to_qstring (r));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +245,7 @@ RecentConfigurationPage::update_list (const std::list<std::vector<std::string> >
|
|||
int column = 0;
|
||||
for (std::list<ConfigurationDescriptor>::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++column) {
|
||||
if (column < int (v->size ())) {
|
||||
render_to (item, column, (*v) [column], c->rendering);
|
||||
render_to (item, column, *v, c->rendering);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +258,17 @@ RecentConfigurationPage::update_list (const std::list<std::vector<std::string> >
|
|||
mp_tree_widget->header ()->resizeSections (QHeaderView::ResizeToContents);
|
||||
}
|
||||
|
||||
void
|
||||
RecentConfigurationPage::item_clicked (QTreeWidgetItem *item)
|
||||
{
|
||||
int column = 0;
|
||||
for (std::list<ConfigurationDescriptor>::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++column) {
|
||||
std::string v = tl::to_string (item->data (column, Qt::UserRole).toString ());
|
||||
dispatcher ()->config_set (c->cfg_name, v);
|
||||
}
|
||||
dispatcher ()->config_end ();
|
||||
}
|
||||
|
||||
void
|
||||
RecentConfigurationPage::commit_recent (lay::Dispatcher *root)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,7 +52,12 @@ public:
|
|||
Double = 2,
|
||||
Int = 3,
|
||||
Layer = 4,
|
||||
PCellParamters = 5
|
||||
PCellParameters = 5,
|
||||
CellLibraryName = 6,
|
||||
CellDisplayName = 7,
|
||||
ArrayFlag = 8,
|
||||
DoubleIfArray = 9,
|
||||
IntIfArray = 10
|
||||
};
|
||||
|
||||
struct ConfigurationDescriptor
|
||||
|
|
@ -80,6 +85,9 @@ public:
|
|||
virtual void setup (lay::Dispatcher * /*root*/) { }
|
||||
virtual void commit_recent (lay::Dispatcher *root);
|
||||
|
||||
private slots:
|
||||
void item_clicked (QTreeWidgetItem *item);
|
||||
|
||||
private:
|
||||
std::string m_recent_cfg_name;
|
||||
std::list<ConfigurationDescriptor> m_cfg;
|
||||
|
|
@ -89,6 +97,7 @@ private:
|
|||
void update_list (const std::list<std::vector<std::string> > &stored_values);
|
||||
std::list<std::vector<std::string> > get_stored_values () const;
|
||||
void set_stored_values (const std::list<std::vector<std::string> > &values) const;
|
||||
void render_to (QTreeWidgetItem *item, int column, const std::vector<std::string> &values, RecentConfigurationPage::ConfigurationRendering rendering);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1093,7 +1093,7 @@ InstService::InstService (db::Manager *manager, lay::LayoutView *view)
|
|||
m_array (false), m_rows (1), m_columns (1),
|
||||
m_row_x (0.0), m_row_y (0.0), m_column_x (0.0), m_column_y (0.0),
|
||||
m_place_origin (false), m_reference_transaction_id (0),
|
||||
m_needs_update (true), m_has_valid_cell (false), m_in_drag_drop (false),
|
||||
m_needs_update (true), m_parameters_changed (false), m_has_valid_cell (false), m_in_drag_drop (false),
|
||||
m_current_cell (0), mp_current_layout (0), mp_pcell_decl (0), m_cv_index (-1)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
|
|
@ -1137,6 +1137,8 @@ InstService::drag_enter_event (const db::DPoint &p, const lay::DragDropDataBase
|
|||
view ()->cancel ();
|
||||
set_edit_marker (0);
|
||||
|
||||
bool switch_parameters = true;
|
||||
|
||||
// configure from the drag/drop data
|
||||
if (cd->library ()) {
|
||||
|
||||
|
|
@ -1168,6 +1170,7 @@ InstService::drag_enter_event (const db::DPoint &p, const lay::DragDropDataBase
|
|||
|
||||
if (! cd->pcell_params ().empty ()) {
|
||||
m_pcell_parameters = pcell_decl->named_parameters (cd->pcell_params ());
|
||||
switch_parameters = false;
|
||||
}
|
||||
|
||||
} else if (cd->layout ()->is_valid_cell_index (cd->cell_index ())) {
|
||||
|
|
@ -1178,7 +1181,7 @@ InstService::drag_enter_event (const db::DPoint &p, const lay::DragDropDataBase
|
|||
return false;
|
||||
}
|
||||
|
||||
switch_cell_or_pcell ();
|
||||
switch_cell_or_pcell (switch_parameters);
|
||||
|
||||
sync_to_config ();
|
||||
m_in_drag_drop = true;
|
||||
|
|
@ -1550,6 +1553,7 @@ InstService::configure (const std::string &name, const std::string &value)
|
|||
m_is_pcell = ! value.empty ();
|
||||
|
||||
m_needs_update = true;
|
||||
m_parameters_changed = true;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1714,7 +1718,7 @@ InstService::configure (const std::string &name, const std::string &value)
|
|||
}
|
||||
|
||||
void
|
||||
InstService::switch_cell_or_pcell ()
|
||||
InstService::switch_cell_or_pcell (bool switch_parameters)
|
||||
{
|
||||
// if the library or cell name has changed, store the current pcell parameters and try to reuse
|
||||
// an existing parameter set
|
||||
|
|
@ -1722,11 +1726,15 @@ InstService::switch_cell_or_pcell ()
|
|||
|
||||
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 ();
|
||||
if (switch_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 ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1759,22 +1767,32 @@ InstService::config_finalize ()
|
|||
{
|
||||
if (m_needs_update) {
|
||||
|
||||
switch_cell_or_pcell ();
|
||||
// don't switch parameters if they have been updated explicitly
|
||||
// since the last "config_finalize". This means the sender of the configuration events
|
||||
// wants the parameters to be set in a specific way. Don't interfere.
|
||||
bool switch_parameters = ! m_parameters_changed;
|
||||
|
||||
switch_cell_or_pcell (switch_parameters);
|
||||
|
||||
m_has_valid_cell = false;
|
||||
update_marker ();
|
||||
m_needs_update = false;
|
||||
|
||||
// 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 ());
|
||||
if (switch_parameters) {
|
||||
// Reflects any changes in PCell parameters in the configuration
|
||||
// TODO: it's somewhat questionable to do this inside "config_finalize" as this method is supposed
|
||||
// to reflect changes rather than induce some.
|
||||
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 ());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_needs_update = false;
|
||||
m_parameters_changed = false;
|
||||
|
||||
edt::Service::config_finalize ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ private:
|
|||
double m_row_x, m_row_y, m_column_x, m_column_y;
|
||||
bool m_place_origin;
|
||||
db::Manager::transaction_id_t m_reference_transaction_id;
|
||||
bool m_needs_update;
|
||||
bool m_needs_update, m_parameters_changed;
|
||||
bool m_has_valid_cell;
|
||||
bool m_in_drag_drop;
|
||||
db::cell_index_type m_current_cell;
|
||||
|
|
@ -253,7 +253,7 @@ private:
|
|||
std::pair<bool, db::cell_index_type> make_cell (const lay::CellView &cv);
|
||||
tl::Variant get_default_layer_for_pcell ();
|
||||
void sync_to_config ();
|
||||
void switch_cell_or_pcell ();
|
||||
void switch_cell_or_pcell (bool switch_parameters);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2603,6 +2603,8 @@ MainWindow::select_view (int index)
|
|||
|
||||
try {
|
||||
|
||||
cancel ();
|
||||
|
||||
tl_assert (index >= 0 && index < int (views ()));
|
||||
|
||||
mp_tab_bar->setCurrentIndex (index);
|
||||
|
|
|
|||
Loading…
Reference in New Issue