WIP: recent configurations for instances, some bug fixes there. Views now reset tool if the tab changes.

This commit is contained in:
Matthias Koefferlein 2020-08-18 00:01:59 +02:00
parent 399e4f4fc7
commit 9a19ced4e0
6 changed files with 185 additions and 35 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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);
};
}

View File

@ -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 ();
}

View File

@ -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);
};
}

View File

@ -2603,6 +2603,8 @@ MainWindow::select_view (int index)
try {
cancel ();
tl_assert (index >= 0 && index < int (views ()));
mp_tab_bar->setCurrentIndex (index);