WIP: some enhancements on recent options page, rotate with right mouse button now changes options too.

This commit is contained in:
Matthias Koefferlein 2020-08-16 09:51:04 +02:00
parent ee5cd9cb63
commit 399e4f4fc7
7 changed files with 257 additions and 81 deletions

View File

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

View File

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

View File

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

View File

@ -60,45 +60,6 @@ ac_from_buttons (unsigned int buttons)
// -------------------------------------------------------------
std::string pcell_parameters_to_string (const std::map<std::string, tl::Variant> &parameters)
{
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),

View File

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

View File

@ -35,6 +35,45 @@
namespace edt {
// -------------------------------------------------------------
std::string pcell_parameters_to_string (const std::map<std::string, tl::Variant> &parameters)
{
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

View File

@ -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> &parameters);
/**
* @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
*