Merge pull request #1825 from KLayout/wip

Some enhancements to "Descend" and "Ascend"
This commit is contained in:
Matthias Köfferlein 2024-08-13 08:06:24 +02:00 committed by GitHub
commit 77782e4f1c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 90 additions and 10 deletions

View File

@ -169,6 +169,8 @@ MainService::menu_activated (const std::string &symbol)
{
if (symbol == "edt::descend") {
cm_descend ();
} else if (symbol == "edt::descend_into") {
cm_descend_into ();
} else if (symbol == "edt::ascend") {
cm_ascend ();
} else if (symbol == "edt::sel_align") {
@ -303,8 +305,20 @@ private:
};
void
void
MainService::cm_descend ()
{
descend (false);
}
void
MainService::cm_descend_into ()
{
descend (true);
}
void
MainService::descend (bool into)
{
CommonInsts common_inst;
@ -315,6 +329,15 @@ MainService::cm_descend ()
}
}
if (! common_inst.anything ()) {
// try transient selection
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end () && common_inst.valid (); ++es) {
for (EditableSelectionIterator sel = (*es)->begin_transient_selection (); ! sel.at_end () && common_inst.valid (); ++sel) {
common_inst.add (*sel, 1);
}
}
}
// cannot descend - we are at the lowest level already
if (common_inst.empty ()) {
return;
@ -354,6 +377,9 @@ MainService::cm_descend ()
// this will clear the selection:
view ()->descend (common_inst.common_path (), common_inst.cv_index ());
if (into) {
view ()->select_cell_dispatch (view ()->cellview (common_inst.cv_index ()).combined_unspecific_path (), common_inst.cv_index ());
}
view ()->set_current_cell_path (common_inst.cv_index (), view ()->cellview (common_inst.cv_index ()).combined_unspecific_path ());
// set the new selections
@ -371,6 +397,7 @@ MainService::cm_ascend ()
std::vector<edt::Service *> edt_services = view ()->get_plugins <edt::Service> ();
bool any_selected = false;
std::vector< std::vector<lay::ObjectInstPath> > new_selections;
new_selections.reserve (edt_services.size ());
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
@ -382,6 +409,7 @@ MainService::cm_ascend ()
new_selections.back ().reserve (n);
for (EditableSelectionIterator i = (*es)->begin_selection (); ! i.at_end (); ++i) {
new_selections.back ().push_back (*i);
any_selected = true;
}
}
@ -394,14 +422,36 @@ MainService::cm_ascend ()
db::cell_index_type new_top = view ()->cellview (cv_index).cell_index ();
view ()->set_current_cell_path (cv_index, view ()->cellview (cv_index).combined_unspecific_path ());
// create and the new selections
unsigned int index = 0;
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es, ++index) {
for (std::vector<lay::ObjectInstPath>::iterator sel = new_selections [index].begin (); sel != new_selections [index].end (); ++sel) {
if (int (sel->cv_index ()) == cv_index) {
sel->insert_front (new_top, removed);
if (! any_selected) {
#if 0
// make the instance we just left the selected one
// (Note: this is a nice idea, but it kind of pins the path to the current cell.
// Specifically after enabling the transient selection for "descend", this is more
// annoying than useful)
edt::InstService *inst_service = view ()->get_plugin <edt::InstService> ();
unsigned int index = 0;
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es, ++index) {
if (*es == inst_service) {
new_selections [index].push_back (lay::ObjectInstPath ());
new_selections [index].back ().add_path (removed);
break;
}
}
#endif
} else {
// modify the selections by adding the new path element
unsigned int index = 0;
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es, ++index) {
for (std::vector<lay::ObjectInstPath>::iterator sel = new_selections [index].begin (); sel != new_selections [index].end (); ++sel) {
if (int (sel->cv_index ()) == cv_index) {
sel->insert_front (new_top, removed);
}
}
}
}
}

View File

@ -90,6 +90,11 @@ public:
*/
void cm_descend ();
/**
* @brief Descend to selection and make cell current top
*/
void cm_descend_into ();
/**
* @brief Ascend one level
*/
@ -239,6 +244,7 @@ private:
void boolean_op (int mode);
void check_no_guiding_shapes ();
void descend (bool make_new_top);
#if defined(HAVE_QT)
edt::RoundCornerOptionsDialog *round_corners_dialog ();
edt::AreaAndPerimeterDialog *area_and_perimeter_dialog ();

View File

@ -351,6 +351,7 @@ public:
menu_entries.push_back (lay::separator ("edt::hier_group", "zoom_menu.end"));
menu_entries.push_back (lay::menu_item ("edt::descend", "descend", "zoom_menu.end", tl::to_string (tr ("Descend")) + "(Ctrl+D)"));
menu_entries.push_back (lay::menu_item ("edt::descend_into", "descend_into", "zoom_menu.end", tl::to_string (tr ("Descend Into")) + "(D)"));
menu_entries.push_back (lay::menu_item ("edt::ascend", "ascend", "zoom_menu.end", tl::to_string (tr ("Ascend")) + "(Ctrl+A)"));
menu_entries.push_back (lay::menu_item ("edt::sel_make_array", "make_array:edit_mode", "edit_menu.selection_menu.end", tl::to_string (tr ("Make Array"))));

View File

@ -780,7 +780,7 @@ LayoutViewBase::configure (const std::string &name, const std::string &value)
int os = 1;
tl::from_string (value, os);
if (os != mp_canvas->oversampling ()) {
if (os != int (mp_canvas->oversampling ())) {
mp_canvas->set_oversampling (os);
resolution_changed_event ();
}
@ -5899,17 +5899,40 @@ LayoutViewBase::ascend (int index)
{
tl_assert (int (m_cellviews.size ()) > index && cellview_iter (index)->is_valid ());
lay::CellView &cv = *cellview_iter (index);
cellview_about_to_change_event (index);
lay::CellView::specific_cell_path_type spath (cellview_iter (index)->specific_path ());
lay::CellView::specific_cell_path_type spath (cv.specific_path ());
if (spath.empty ()) {
lay::CellView::unspecific_cell_path_type upath (cv.unspecific_path ());
if (upath.size () >= 2) {
db::cell_index_type last = upath.back ();
upath.pop_back ();
const db::Cell &new_cell = cv->layout ().cell (upath.back ());
auto i = new_cell.begin ();
while (! i.at_end () && i->cell_index () != last) {
++i;
}
if (! i.at_end ()) {
select_cell_dispatch (upath, index);
return db::InstElement (*i);
}
}
return db::InstElement ();
} else {
cancel ();
db::InstElement ret = spath.back ();
spath.pop_back ();
cellview_iter (index)->set_specific_path (spath);
cv.set_specific_path (spath);
store_state ();
redraw ();