mirror of https://github.com/KLayout/klayout.git
Merge pull request #1825 from KLayout/wip
Some enhancements to "Descend" and "Ascend"
This commit is contained in:
commit
77782e4f1c
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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"))));
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
Loading…
Reference in New Issue