Merge branch 'master' into complex_drc_ops

This commit is contained in:
Matthias Koefferlein
2021-01-17 19:55:28 +01:00
21 changed files with 280 additions and 70 deletions
+54 -1
View File
@@ -23,6 +23,7 @@
#include "gsiDecl.h"
#include "gsiSignals.h"
#include "gsiEnums.h"
#include "rdb.h"
#include "layLayoutView.h"
#include "layDitherPattern.h"
@@ -978,11 +979,32 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
"selection. Calling this method is useful to ensure there are no potential interactions with the script's "
"functionality.\n"
) +
gsi::method ("clear_selection", &lay::LayoutView::clear_selection,
gsi::method ("clear_selection", (void (lay::LayoutView::*) ()) &lay::LayoutView::clear_selection,
"@brief Clears the selection of all objects (shapes, annotations, images ...)\n"
"\n"
"This method has been introduced in version 0.26.2\n"
) +
gsi::method ("select_all", (void (lay::LayoutView::*) ()) &lay::LayoutView::select,
"@brief Selects all objects from the view\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
gsi::method ("select_from", (void (lay::LayoutView::*) (const db::DPoint &, lay::Editable::SelectionMode)) &lay::LayoutView::select, gsi::arg ("point"), gsi::arg ("mode", lay::Editable::SelectionMode::Replace, "Replace"),
"@brief Selects the objects from a given point\n"
"\n"
"The mode indicates whether to add to the selection, replace the selection, remove from selection or invert the selected status of the objects "
"found around the given point.\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
gsi::method ("select_from", (void (lay::LayoutView::*) (const db::DBox &, lay::Editable::SelectionMode)) &lay::LayoutView::select, gsi::arg ("box"), gsi::arg ("mode", lay::Editable::SelectionMode::Replace, "Replace"),
"@brief Selects the objects from a given box\n"
"\n"
"The mode indicates whether to add to the selection, replace the selection, remove from selection or invert the selected status of the objects "
"found inside the given box.\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
gsi::method ("clear_transient_selection", &lay::LayoutView::clear_transient_selection,
"@brief Clears the transient selection (mouse-over hightlights) of all objects (shapes, annotations, images ...)\n"
"\n"
@@ -1001,6 +1023,16 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
"\n"
"This method has been introduced in version 0.26.2\n"
) +
gsi::method ("selection_size", (size_t (lay::LayoutView::*) ()) &lay::LayoutView::selection_size,
"@brief Returns the number of selected objects\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
gsi::method ("has_selection?", (bool (lay::LayoutView::*) ()) &lay::LayoutView::has_selection,
"@brief Indicates whether any objects are selected\n"
"\n"
"This method has been introduced in version 0.27\n"
) +
gsi::method ("stop", &lay::LayoutView::stop,
"@brief Stops redraw thread and close any browsers\n"
"This method usually does not need to be called explicitly. The redraw thread is stopped automatically."
@@ -1867,6 +1899,27 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
"This object controls these aspects of the view and controls the appearance of the data. "
);
gsi::EnumIn<lay::LayoutView, lay::Editable::SelectionMode> decl_layLayoutView_SelectionMode ("lay", "SelectionMode",
gsi::enum_const ("Add", lay::Editable::SelectionMode::Add,
"@brief Adds to any existing selection\n"
) +
gsi::enum_const ("Reset", lay::Editable::SelectionMode::Reset,
"@brief Removes from any existing selection\n"
) +
gsi::enum_const ("Replace", lay::Editable::SelectionMode::Replace,
"@brief Replaces the existing selection\n"
) +
gsi::enum_const ("Invert", lay::Editable::SelectionMode::Invert,
"@brief Adds to any existing selection, if it's not there yet or removes it from the selection if it's already selected\n"
),
"@brief Specifies how selected objects interact with already selected ones.\n"
"\n"
"This enum was introduced in version 0.27.\n"
);
// Inject the NetlistCrossReference::Status declarations into NetlistCrossReference:
gsi::ClassExt<lay::LayoutView> inject_SelectionMode_in_parent (decl_layLayoutView_SelectionMode.defs ());
static db::Layout *get_layout (const lay::CellViewRef *cv)
{
if ((*cv).operator-> ()) {
+56 -12
View File
@@ -92,7 +92,7 @@ Editables::del (db::Transaction *transaction)
{
std::auto_ptr<db::Transaction> trans_holder (transaction ? transaction : new db::Transaction (manager (), tl::to_string (QObject::tr ("Delete"))));
if (selection_size () > 0) {
if (has_selection ()) {
try {
@@ -118,7 +118,7 @@ Editables::del (db::Transaction *transaction)
void
Editables::cut ()
{
if (selection_size () > 0) {
if (has_selection ()) {
cancel_edits ();
@@ -136,7 +136,7 @@ Editables::cut ()
void
Editables::copy ()
{
if (selection_size () > 0) {
if (has_selection ()) {
db::Clipboard::instance ().clear ();
for (iterator e = begin (); e != end (); ++e) {
e->copy ();
@@ -170,7 +170,7 @@ Editables::transform (const db::DCplxTrans &tr, db::Transaction *transaction)
{
std::auto_ptr<db::Transaction> trans_holder (transaction ? transaction : new db::Transaction (manager (), tl::to_string (QObject::tr ("Transform"))));
if (selection_size () > 0) {
if (has_selection ()) {
try {
@@ -298,19 +298,33 @@ Editables::clear_previous_selection ()
void
Editables::clear_transient_selection ()
{
bool had_transient_selection = false;
for (iterator e = begin (); e != end (); ++e) {
if (e->has_transient_selection ()) {
had_transient_selection = true;
}
e->clear_transient_selection ();
}
// send a signal to the observers
signal_transient_selection_changed ();
if (had_transient_selection) {
signal_transient_selection_changed ();
}
}
void
Editables::transient_to_selection ()
{
bool had_transient_selection = false;
bool had_selection = false;
cancel_edits ();
for (iterator e = begin (); e != end (); ++e) {
if (e->has_selection ()) {
had_selection = true;
}
if (e->has_transient_selection ()) {
had_transient_selection = true;
}
e->select (db::DBox (), lay::Editable::Reset); // clear selection
e->clear_previous_selection ();
e->transient_to_selection ();
@@ -318,22 +332,41 @@ Editables::transient_to_selection ()
}
// send a signal to the observers
signal_transient_selection_changed ();
signal_selection_changed ();
if (had_transient_selection) {
signal_transient_selection_changed ();
}
if (had_selection || had_transient_selection) {
signal_selection_changed ();
}
}
void
Editables::clear_selection ()
{
cancel_edits ();
bool had_transient_selection = false;
bool had_selection = false;
for (iterator e = begin (); e != end (); ++e) {
if (e->has_selection ()) {
had_selection = true;
}
if (e->has_transient_selection ()) {
had_transient_selection = true;
}
e->select (db::DBox (), lay::Editable::Reset); // clear selection
e->clear_transient_selection ();
e->clear_previous_selection ();
}
// send a signal to the observers
signal_selection_changed ();
if (had_transient_selection) {
signal_transient_selection_changed ();
}
if (had_selection) {
signal_selection_changed ();
}
}
void
@@ -479,7 +512,7 @@ Editables::begin_move (const db::DPoint &p, lay::angle_constraint_type ac)
// sort the plugins found by the proximity
std::sort (plugins.begin (), plugins.end (), first_of_pair_cmp_f<double, iterator> ());
if (selection_size () > 0 && selection_catch_bbox ().contains (p)) {
if (has_selection () && selection_catch_bbox ().contains (p)) {
// if anything is selected and we are within the selection bbox,
// issue a move operation on all editables: first try a Partial mode begin_move
@@ -527,7 +560,7 @@ Editables::begin_move (const db::DPoint &p, lay::angle_constraint_type ac)
select (p, Editable::Replace);
// now we assume we have a selection - try to begin_move on this.
if (selection_size () > 0) {
if (has_selection ()) {
m_move_selection = true;
for (iterator e = begin (); e != end (); ++e) {
e->begin_move (Editable::Selected, p, ac);
@@ -601,7 +634,18 @@ Editables::selection_size ()
return c;
}
void
bool
Editables::has_selection ()
{
for (iterator e = begin (); e != end (); ++e) {
if (e->has_selection ()) {
return true;
}
}
return false;
}
void
Editables::edit_cancel ()
{
clear_previous_selection ();
@@ -627,7 +671,7 @@ Editables::cancel_edits ()
void
Editables::show_properties (QWidget *parent)
{
if (selection_size () == 0) {
if (! has_selection ()) {
// try to use the transient selection for the real one
transient_to_selection ();
}
+23 -5
View File
@@ -319,16 +319,29 @@ public:
}
/**
* @brief Tell how many objects are selected
*
* This method is used to determine if anything is selected - i.e.
* anything can be copied.
* @brief Indicates if any objects are selected
*/
virtual bool has_selection ()
{
return false;
}
/**
* @brief Indicates how many objects are selected
*/
virtual size_t selection_size ()
{
return 0;
}
/**
* @brief Indicates if any objects are selected in the transient selection
*/
virtual bool has_transient_selection ()
{
return false;
}
/**
* @brief Create a "properties page" object
*
@@ -528,12 +541,17 @@ public:
void end_move (const db::DPoint &p, lay::angle_constraint_type ac, db::Transaction *transaction = 0);
/**
* @brief Tell how many objects are selected.
* @brief Indicates how many objects are selected.
*
* This method will return the number of selected objects.
*/
size_t selection_size ();
/**
* @brief Indicates whether any object is selected.
*/
bool has_selection ();
/**
* @brief Cancel any pending operations
*/
+3 -3
View File
@@ -5246,7 +5246,7 @@ LayoutView::has_selection ()
} else if (mp_hierarchy_panel && mp_hierarchy_panel->has_focus ()) {
return mp_hierarchy_panel->has_selection ();
} else {
return lay::Editables::selection_size () > 0;
return lay::Editables::has_selection ();
}
}
@@ -5319,7 +5319,7 @@ LayoutView::copy ()
mp_control_panel->copy ();
} else {
if (lay::Editables::selection_size () == 0) {
if (! lay::Editables::has_selection ()) {
// try to use the transient selection for the real one
lay::Editables::transient_to_selection ();
}
@@ -5341,7 +5341,7 @@ LayoutView::cut ()
mp_control_panel->cut ();
} else {
if (lay::Editables::selection_size () == 0) {
if (! lay::Editables::has_selection ()) {
// try to use the transient selection for the real one
lay::Editables::transient_to_selection ();
}
+3 -3
View File
@@ -100,7 +100,7 @@ MoveService::key_event (unsigned int key, unsigned int /*buttons*/)
dx = 1.0;
}
if (! m_dragging && fabs (dx + dy) > 0.0 && mp_editables->selection_size () > 0) {
if (! m_dragging && fabs (dx + dy) > 0.0 && mp_editables->has_selection ()) {
// determine a shift distance which is 2, 5 or 10 times the grid and is more than 5 pixels
double dmin = double (5 /*pixels min shift*/) / widget ()->mouse_event_trans ().mag ();
@@ -250,13 +250,13 @@ MoveService::begin_move (db::Transaction *transaction, bool selected_after_move)
std::auto_ptr<db::Transaction> trans_holder (transaction);
bool drag_transient = ! selected_after_move;
if (mp_editables->selection_size () == 0) {
if (! mp_editables->has_selection ()) {
// try to use the transient selection for the real one
mp_editables->transient_to_selection ();
drag_transient = true;
}
if (mp_editables->selection_size () == 0) {
if (! mp_editables->has_selection ()) {
// still nothing selected
return false;
}