mirror of https://github.com/KLayout/klayout.git
WIP: some enhancements on recent options page, rotate with right mouse button now changes options too.
This commit is contained in:
parent
ee5cd9cb63
commit
399e4f4fc7
|
|
@ -88,7 +88,10 @@ 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_cell_name, tl::to_string (tr ("Cell name")), edt::RecentConfigurationPage::Text),
|
||||
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_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),
|
||||
|
|
@ -104,7 +107,7 @@ edt::RecentConfigurationPage::ConfigurationDescriptor inst_cfg_descriptors[] =
|
|||
static
|
||||
void get_inst_editor_options_pages (std::vector<edt::EditorOptionsPage *> &ret, lay::Dispatcher *dispatcher)
|
||||
{
|
||||
ret.push_back (new RecentConfigurationPage (dispatcher, 22, tl::to_string (tr ("Recent")),
|
||||
ret.push_back (new RecentConfigurationPage (dispatcher, "edit-recent-inst-param",
|
||||
&inst_cfg_descriptors[0], &inst_cfg_descriptors[sizeof (inst_cfg_descriptors) / sizeof (inst_cfg_descriptors[0])]));
|
||||
ret.push_back (new EditorOptionsInstPCellParam (dispatcher));
|
||||
ret.push_back (new EditorOptionsInst (dispatcher));
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
namespace edt
|
||||
{
|
||||
|
||||
static const size_t max_entries = 100;
|
||||
|
||||
void
|
||||
RecentConfigurationPage::init ()
|
||||
{
|
||||
|
|
@ -36,6 +38,8 @@ RecentConfigurationPage::init ()
|
|||
ly->setMargin (0);
|
||||
|
||||
mp_tree_widget = new QTreeWidget (this);
|
||||
mp_tree_widget->setRootIsDecorated (false);
|
||||
mp_tree_widget->setUniformRowHeights (true);
|
||||
ly->addWidget (mp_tree_widget);
|
||||
|
||||
mp_tree_widget->setColumnCount (int (m_cfg.size ()));
|
||||
|
|
@ -46,7 +50,7 @@ RecentConfigurationPage::init ()
|
|||
}
|
||||
mp_tree_widget->setHeaderLabels (column_labels);
|
||||
|
||||
update_list ();
|
||||
update_list (get_stored_values ());
|
||||
}
|
||||
|
||||
RecentConfigurationPage::~RecentConfigurationPage ()
|
||||
|
|
@ -54,9 +58,59 @@ RecentConfigurationPage::~RecentConfigurationPage ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
std::string RecentConfigurationPage::title () const
|
||||
{
|
||||
return tl::to_string (tr ("Recent"));
|
||||
}
|
||||
|
||||
int RecentConfigurationPage::order () const
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
std::list<std::vector<std::string> >
|
||||
RecentConfigurationPage::get_stored_values () const
|
||||
{
|
||||
std::string serialized_list = dispatcher ()->config_get (m_recent_cfg_name);
|
||||
|
||||
std::list<std::vector<std::string> > values;
|
||||
tl::Extractor ex (serialized_list.c_str ());
|
||||
while (! ex.at_end ()) {
|
||||
|
||||
values.push_back (std::vector<std::string> ());
|
||||
while (! ex.at_end () && ! ex.test (";")) {
|
||||
values.back ().push_back (std::string ());
|
||||
ex.read_word_or_quoted (values.back ().back ());
|
||||
ex.test (",");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
void
|
||||
RecentConfigurationPage::set_stored_values (const std::list<std::vector<std::string> > &values) const
|
||||
{
|
||||
std::string serialized_list;
|
||||
for (std::list<std::vector<std::string> >::const_iterator v = values.begin (); v != values.end (); ++v) {
|
||||
if (v != values.begin ()) {
|
||||
serialized_list += ";";
|
||||
}
|
||||
for (std::vector<std::string>::const_iterator s = v->begin (); s != v->end (); ++s) {
|
||||
serialized_list += tl::to_word_or_quoted_string (*s);
|
||||
serialized_list += ",";
|
||||
}
|
||||
}
|
||||
|
||||
dispatcher ()->config_set (m_recent_cfg_name, serialized_list);
|
||||
}
|
||||
|
||||
void
|
||||
render_to (QTreeWidgetItem *item, int column, const std::string &v, RecentConfigurationPage::ConfigurationRendering rendering)
|
||||
{
|
||||
// store original value
|
||||
item->setData (column, Qt::UserRole, tl::to_qstring (v));
|
||||
|
||||
// @@@ rendering
|
||||
item->setText (column, tl::to_qstring (v));
|
||||
|
|
@ -64,10 +118,10 @@ render_to (QTreeWidgetItem *item, int column, const std::string &v, RecentConfig
|
|||
}
|
||||
|
||||
void
|
||||
RecentConfigurationPage::update_list ()
|
||||
RecentConfigurationPage::update_list (const std::list<std::vector<std::string> > &stored_values)
|
||||
{
|
||||
int row = 0;
|
||||
for (std::list<std::vector<std::string> >::const_iterator v = m_stored_values.begin (); v != m_stored_values.end (); ++v, ++row) {
|
||||
for (std::list<std::vector<std::string> >::const_iterator v = stored_values.begin (); v != stored_values.end (); ++v, ++row) {
|
||||
|
||||
QTreeWidgetItem *item = 0;
|
||||
if (row < mp_tree_widget->topLevelItemCount ()) {
|
||||
|
|
@ -102,16 +156,24 @@ RecentConfigurationPage::commit_recent (lay::Dispatcher *root)
|
|||
values.push_back (root->config_get (c->cfg_name));
|
||||
}
|
||||
|
||||
for (std::list<std::vector<std::string> >::iterator v = m_stored_values.begin (); v != m_stored_values.end (); ++v) {
|
||||
std::list<std::vector<std::string> > stored_values = get_stored_values ();
|
||||
|
||||
for (std::list<std::vector<std::string> >::iterator v = stored_values.begin (); v != stored_values.end (); ++v) {
|
||||
if (*v == values) {
|
||||
m_stored_values.erase (v);
|
||||
stored_values.erase (v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_stored_values.push_front (values);
|
||||
stored_values.push_front (values);
|
||||
|
||||
update_list ();
|
||||
while (stored_values.size () > max_entries) {
|
||||
stored_values.erase (--stored_values.end ());
|
||||
}
|
||||
|
||||
set_stored_values (stored_values);
|
||||
|
||||
update_list (stored_values);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,29 +66,29 @@ public:
|
|||
};
|
||||
|
||||
template <class Iter>
|
||||
RecentConfigurationPage (lay::Dispatcher *dispatcher, int order, const std::string &title, Iter begin_cfg, Iter end_cfg)
|
||||
: EditorOptionsPage (dispatcher), m_title (title), m_order (order), m_cfg (begin_cfg, end_cfg)
|
||||
RecentConfigurationPage (lay::Dispatcher *dispatcher, const std::string &recent_cfg_name, Iter begin_cfg, Iter end_cfg)
|
||||
: EditorOptionsPage (dispatcher), m_recent_cfg_name (recent_cfg_name), m_cfg (begin_cfg, end_cfg)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
virtual ~RecentConfigurationPage ();
|
||||
|
||||
virtual std::string title () const { return m_title; }
|
||||
virtual int order () const { return m_order; }
|
||||
virtual std::string title () const;
|
||||
virtual int order () const;
|
||||
virtual void apply (lay::Dispatcher * /*root*/) { }
|
||||
virtual void setup (lay::Dispatcher * /*root*/) { }
|
||||
virtual void commit_recent (lay::Dispatcher *root);
|
||||
|
||||
private:
|
||||
std::string m_title;
|
||||
int m_order;
|
||||
std::string m_recent_cfg_name;
|
||||
std::list<ConfigurationDescriptor> m_cfg;
|
||||
QTreeWidget *mp_tree_widget;
|
||||
std::list<std::vector<std::string> > m_stored_values;
|
||||
|
||||
void init ();
|
||||
void update_list ();
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,45 +60,6 @@ ac_from_buttons (unsigned int buttons)
|
|||
|
||||
// -------------------------------------------------------------
|
||||
|
||||
std::string pcell_parameters_to_string (const std::map<std::string, tl::Variant> ¶meters)
|
||||
{
|
||||
std::string param;
|
||||
|
||||
param = "!"; // flags PCells
|
||||
for (std::map<std::string, tl::Variant>::const_iterator p = parameters.begin (); p != parameters.end (); ++p) {
|
||||
param += tl::to_word_or_quoted_string (p->first);
|
||||
param += ":";
|
||||
param += p->second.to_parsable_string ();
|
||||
param += ";";
|
||||
}
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
std::map<std::string, tl::Variant> pcell_parameters_from_string (const std::string &s)
|
||||
{
|
||||
tl::Extractor ex (s.c_str ());
|
||||
std::map<std::string, tl::Variant> pm;
|
||||
|
||||
ex.test ("!");
|
||||
|
||||
try {
|
||||
while (! ex.at_end ()) {
|
||||
std::string n;
|
||||
ex.read_word_or_quoted (n);
|
||||
ex.test (":");
|
||||
ex.read (pm.insert (std::make_pair (n, tl::Variant ())).first->second);
|
||||
ex.test (";");
|
||||
}
|
||||
} catch (...) {
|
||||
// ignore errors
|
||||
}
|
||||
|
||||
return pm;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
|
||||
Service::Service (db::Manager *manager, lay::LayoutView *view, db::ShapeIterator::flags_type flags)
|
||||
: lay::ViewService (view->view_object_widget ()),
|
||||
lay::Editable (view),
|
||||
|
|
|
|||
|
|
@ -1417,6 +1417,14 @@ InstService::do_mouse_transform (const db::DPoint &p, db::DFTrans trans)
|
|||
m_column_x = c.x ();
|
||||
m_column_y = c.y ();
|
||||
|
||||
dispatcher ()->config_set (cfg_edit_inst_angle, m_angle);
|
||||
dispatcher ()->config_set (cfg_edit_inst_mirror, m_mirror);
|
||||
dispatcher ()->config_set (cfg_edit_inst_row_x, m_row_x);
|
||||
dispatcher ()->config_set (cfg_edit_inst_row_y, m_row_y);
|
||||
dispatcher ()->config_set (cfg_edit_inst_column_x, m_column_x);
|
||||
dispatcher ()->config_set (cfg_edit_inst_column_y, m_column_y);
|
||||
dispatcher ()->config_end ();
|
||||
|
||||
// honour the new transformation
|
||||
do_mouse_move (p);
|
||||
}
|
||||
|
|
@ -1535,78 +1543,171 @@ InstService::configure (const std::string &name, const std::string &value)
|
|||
|
||||
if (name == cfg_edit_inst_pcell_parameters) {
|
||||
|
||||
m_pcell_parameters = pcell_parameters_from_string (value);
|
||||
m_is_pcell = ! value.empty ();
|
||||
std::map<std::string, tl::Variant> pcp = pcell_parameters_from_string (value);
|
||||
if (pcp != m_pcell_parameters) {
|
||||
|
||||
m_pcell_parameters = pcp;
|
||||
m_is_pcell = ! value.empty ();
|
||||
|
||||
m_needs_update = true;
|
||||
|
||||
}
|
||||
|
||||
m_needs_update = true;
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_place_origin) {
|
||||
tl::from_string (value, m_place_origin);
|
||||
m_needs_update = true;
|
||||
|
||||
bool f;
|
||||
tl::from_string (value, f);
|
||||
|
||||
if (f != m_place_origin) {
|
||||
m_place_origin = f;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_scale) {
|
||||
tl::from_string (value, m_scale);
|
||||
m_needs_update = true;
|
||||
|
||||
double s;
|
||||
tl::from_string (value, s);
|
||||
|
||||
if (fabs (s - m_scale) > 1e-10) {
|
||||
m_scale = s;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_angle) {
|
||||
tl::from_string (value, m_angle);
|
||||
m_needs_update = true;
|
||||
|
||||
double a;
|
||||
tl::from_string (value, a);
|
||||
|
||||
if (fabs (a - m_angle) > 1e-10) {
|
||||
m_angle = a;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_mirror) {
|
||||
tl::from_string (value, m_mirror);
|
||||
m_needs_update = true;
|
||||
|
||||
bool f;
|
||||
tl::from_string (value, f);
|
||||
|
||||
if (f != m_mirror) {
|
||||
m_mirror = f;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_array) {
|
||||
tl::from_string (value, m_array);
|
||||
m_needs_update = true;
|
||||
|
||||
bool f;
|
||||
tl::from_string (value, f);
|
||||
|
||||
if (f != m_array) {
|
||||
m_array = f;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_rows) {
|
||||
tl::from_string (value, m_rows);
|
||||
m_needs_update = true;
|
||||
|
||||
unsigned int v;
|
||||
tl::from_string (value, v);
|
||||
|
||||
if (v != m_rows) {
|
||||
m_rows = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_row_x) {
|
||||
tl::from_string (value, m_row_x);
|
||||
m_needs_update = true;
|
||||
|
||||
double v;
|
||||
tl::from_string (value, v);
|
||||
|
||||
if (! db::coord_traits<double>::equal (m_row_x, v)) {
|
||||
m_row_x = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_row_y) {
|
||||
tl::from_string (value, m_row_y);
|
||||
m_needs_update = true;
|
||||
|
||||
double v;
|
||||
tl::from_string (value, v);
|
||||
|
||||
if (! db::coord_traits<double>::equal (m_row_y, v)) {
|
||||
m_row_y = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_columns) {
|
||||
tl::from_string (value, m_columns);
|
||||
m_needs_update = true;
|
||||
|
||||
unsigned int v;
|
||||
tl::from_string (value, v);
|
||||
|
||||
if (v != m_columns) {
|
||||
m_columns = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_column_x) {
|
||||
tl::from_string (value, m_column_x);
|
||||
m_needs_update = true;
|
||||
|
||||
double v;
|
||||
tl::from_string (value, v);
|
||||
|
||||
if (! db::coord_traits<double>::equal (m_column_x, v)) {
|
||||
m_column_x = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
if (name == cfg_edit_inst_column_y) {
|
||||
tl::from_string (value, m_column_y);
|
||||
m_needs_update = true;
|
||||
|
||||
double v;
|
||||
tl::from_string (value, v);
|
||||
|
||||
if (! db::coord_traits<double>::equal (m_column_y, v)) {
|
||||
m_column_y = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
|
||||
return true; // taken
|
||||
|
||||
}
|
||||
|
||||
return edt::Service::configure (name, value);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,45 @@
|
|||
|
||||
namespace edt {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
|
||||
std::string pcell_parameters_to_string (const std::map<std::string, tl::Variant> ¶meters)
|
||||
{
|
||||
std::string param;
|
||||
|
||||
param = "!"; // flags PCells
|
||||
for (std::map<std::string, tl::Variant>::const_iterator p = parameters.begin (); p != parameters.end (); ++p) {
|
||||
param += tl::to_word_or_quoted_string (p->first);
|
||||
param += ":";
|
||||
param += p->second.to_parsable_string ();
|
||||
param += ";";
|
||||
}
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
std::map<std::string, tl::Variant> pcell_parameters_from_string (const std::string &s)
|
||||
{
|
||||
tl::Extractor ex (s.c_str ());
|
||||
std::map<std::string, tl::Variant> pm;
|
||||
|
||||
ex.test ("!");
|
||||
|
||||
try {
|
||||
while (! ex.at_end ()) {
|
||||
std::string n;
|
||||
ex.read_word_or_quoted (n);
|
||||
ex.test (":");
|
||||
ex.read (pm.insert (std::make_pair (n, tl::Variant ())).first->second);
|
||||
ex.test (";");
|
||||
}
|
||||
} catch (...) {
|
||||
// ignore errors
|
||||
}
|
||||
|
||||
return pm;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// SelectionIterator implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,16 @@ namespace edt {
|
|||
|
||||
class Service;
|
||||
|
||||
/**
|
||||
* @brief Serializes PCell parameters to a string
|
||||
*/
|
||||
std::string pcell_parameters_to_string (const std::map<std::string, tl::Variant> ¶meters);
|
||||
|
||||
/**
|
||||
* @brief Deerializes PCell parameters from a string
|
||||
*/
|
||||
std::map<std::string, tl::Variant> pcell_parameters_from_string (const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Fetch PCell parameters from a cell and merge the guiding shapes into them
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue