This commit is contained in:
Matthias Koefferlein 2025-08-16 21:44:41 +02:00
parent a4f3d9a33b
commit 6fdad4649a
7 changed files with 149 additions and 2 deletions

View File

@ -211,6 +211,8 @@ MainService::menu_activated (const std::string &symbol)
cm_make_array ();
} else if (symbol == "edt::sel_make_cell_variants") {
cm_make_cell_variants ();
} else if (symbol == "edt::via") {
cm_via ();
}
}
@ -2439,7 +2441,45 @@ MainService::cm_tap ()
#endif
}
void
void
MainService::cm_via ()
{
#if ! defined(HAVE_QT)
tl_assert (false); // see TODO
#endif
#if defined(HAVE_QT)
QWidget *view_widget = lay::widget_from_view (view ());
if (! view_widget) {
return;
}
#endif
if (! view ()->canvas ()->mouse_in_window ()) {
return;
}
edt::Service *es = dynamic_cast<edt::Service *> (view ()->canvas ()->active_service ());
if (es) {
es->via ();
} else {
#if 0 // @@@
db::ShapeIterator::flags_type (db::ShapeIterator::All - db::ShapeIterator::Texts), // do not consider texts - their bounding box may be too large
lay::ShapeFinder finder (true, view ()->is_editable () && m_top_level_sel, m_flags, &m_previous_selection);
// go through all visible layers of all cellviews
finder.find (view (), search_box);
// collect the founds from the finder
lay::ShapeFinder::iterator r = finder.begin ();
if (r != finder.end ()) {
#endif
}
}
void
MainService::cm_change_layer ()
{
tl_assert (view ()->is_editable ());

View File

@ -200,7 +200,12 @@ public:
*/
void cm_tap ();
/**
/**
* @brief Via operation
*/
void cm_via ();
/**
* @brief "paste" operation
*/
virtual void paste ();

View File

@ -379,6 +379,9 @@ public:
menu_entries.push_back (lay::menu_item ("edt::sel_area_perimeter", "area_perimeter", "edit_menu.selection_menu.end", tl::to_string (tr ("Area and Perimeter"))));
menu_entries.push_back (lay::menu_item ("edt::combine_mode", "combine_mode:edit_mode", "@toolbar.end_modes", tl::to_string (tr ("Combine{Select background combination mode}"))));
// Key binding only
menu_entries.push_back (lay::menu_item ("edt::via", "via:edit_mode", "@secrets.end", tl::to_string (tr ("Via")) + "(V)"));
}
bool configure (const std::string &name, const std::string &value)

View File

@ -1717,6 +1717,12 @@ Service::tap (const db::DPoint & /*initial*/)
// .. nothing here ..
}
void
Service::via ()
{
// .. nothing here ..
}
void
Service::geometry_changing ()
{

View File

@ -377,6 +377,11 @@ public:
*/
virtual void tap (const db::DPoint &initial);
/**
* @brief Implements the via feature
*/
virtual void via ();
/**
* @brief Delete the selected rulers
*

View File

@ -1443,6 +1443,93 @@ PathService::selection_applies (const lay::ObjectInstPath &sel) const
return !sel.is_cell_inst () && sel.shape ().is_path ();
}
void
PathService::via ()
{
#if ! defined(HAVE_QT)
tl_assert (false); // see TODO
#endif
// @@@
db::LayerProperties lp = layout ().get_properties (layer ());
// definitions of vias found
struct SelectedViaDefinition
{
SelectedViaDefinition ()
: lib (0), pcell (0)
{ }
SelectedViaDefinition (const db::Library *_lib, const db::PCellDeclaration *_pcell, const db::ViaType &_via_type)
: lib (_lib), pcell (_pcell), via_type (_via_type)
{ }
const db::Library *lib;
const db::PCellDeclaration *pcell;
db::ViaType via_type;
};
std::vector<SelectedViaDefinition> via_defs;
// Find vias with corresponding top an bottom layers
// @@@ TODO: move elsewhere
for (auto l = db::LibraryManager::instance ().begin (); l != db::LibraryManager::instance ().end (); ++l) {
const db::Library *lib = db::LibraryManager::instance ().lib (l->second);
for (auto pc = lib->layout ().begin_pcells (); pc != lib->layout ().end_pcells (); ++pc) {
const db::PCellDeclaration *pcell = lib->layout ().pcell_declaration (pc->second);
auto via_types = pcell->via_types ();
for (auto vt = via_types.begin (); vt != via_types.end (); ++vt) {
if ((vt->bottom.log_equal (lp) && vt->bottom_wired) || (vt->top.log_equal (lp) && vt->top_wired)) {
via_defs.push_back (SelectedViaDefinition (lib, pcell, *vt));
}
}
}
}
SelectedViaDefinition via_def;
if (via_defs.size () == 0) {
return;
} else if (via_defs.size () == 1) {
via_def = via_defs.front ();
} else if (via_defs.size () > 1) {
#if defined(HAVE_QT)
// TODO: what to do here in Qt-less case? Store results in configuration so they can be retrieved externally?
QWidget *view_widget = lay::widget_from_view (view ());
if (! view_widget) {
return;
}
std::unique_ptr<QMenu> menu (new QMenu (view_widget));
menu->show ();
db::DPoint mp_local = view ()->canvas ()->mouse_position ();
QPoint mp = view ()->canvas ()->widget ()->mapToGlobal (QPoint (mp_local.x (), mp_local.y ()));
for (auto i = via_defs.begin (); i != via_defs.end (); ++i) {
QAction *a = menu->addAction (tl::to_qstring (i->via_type.description.empty () ? i->via_type.name : i->via_type.description));
a->setData (int (i - via_defs.begin ()));
}
QAction *action = menu->exec (mp);
if (! action) {
return;
}
via_def = via_defs [action->data ().toInt ()];
#endif
}
tl::warn << "@@@1 " << via_def.via_type.name;
}
bool
PathService::configure (const std::string &name, const std::string &value)
{

View File

@ -236,6 +236,7 @@ public:
virtual void do_finish_edit ();
virtual void do_cancel_edit ();
virtual bool do_activated ();
virtual void via ();
virtual bool selection_applies (const lay::ObjectInstPath &sel) const;
protected: