mirror of https://github.com/KLayout/klayout.git
Merge pull request #696 from KLayout/more-elaborate-layout_view-selections
More elaborate handling of selection changed events in LayoutView (av…
This commit is contained in:
commit
78672b1175
|
|
@ -1642,7 +1642,7 @@ Service::reduce_rulers (int num)
|
|||
void
|
||||
Service::cut ()
|
||||
{
|
||||
if (selection_size () > 0) {
|
||||
if (has_selection ()) {
|
||||
|
||||
// copy & delete the selected rulers
|
||||
copy_selected ();
|
||||
|
|
@ -1701,7 +1701,7 @@ Service::paste ()
|
|||
void
|
||||
Service::del ()
|
||||
{
|
||||
if (selection_size () > 0) {
|
||||
if (has_selection ()) {
|
||||
|
||||
// delete the selected rulers
|
||||
del_selected ();
|
||||
|
|
@ -1727,12 +1727,24 @@ Service::del_selected ()
|
|||
mp_view->annotation_shapes ().erase_positions (positions.begin (), positions.end ());
|
||||
}
|
||||
|
||||
size_t
|
||||
bool
|
||||
Service::has_selection ()
|
||||
{
|
||||
return ! m_selected.empty ();
|
||||
}
|
||||
|
||||
size_t
|
||||
Service::selection_size ()
|
||||
{
|
||||
return m_selected.size ();
|
||||
}
|
||||
|
||||
bool
|
||||
Service::has_transient_selection ()
|
||||
{
|
||||
return mp_transient_ruler != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Service::select (obj_iterator obj, lay::Editable::SelectionMode mode)
|
||||
{
|
||||
|
|
@ -1934,7 +1946,7 @@ Service::transient_select (const db::DPoint &pos)
|
|||
mp_transient_ruler = new ant::View (this, robj, true /*selected*/);
|
||||
}
|
||||
|
||||
if (any_selected && editables ()->selection_size () == 0) {
|
||||
if (any_selected && ! editables ()->has_selection ()) {
|
||||
display_status (true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -256,11 +256,21 @@ public:
|
|||
virtual void paste ();
|
||||
|
||||
/**
|
||||
* @brief Tell the number of selected objects
|
||||
* @brief Indicates whether there are selection objects
|
||||
*/
|
||||
virtual bool has_selection ();
|
||||
|
||||
/**
|
||||
* @brief Indicates how many objects are selected
|
||||
*/
|
||||
virtual size_t selection_size ();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Indicates whether there are selection objects in transient mode
|
||||
*/
|
||||
virtual bool has_transient_selection ();
|
||||
|
||||
/**
|
||||
* @brief point selection proximity predicate
|
||||
*/
|
||||
virtual double click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mode);
|
||||
|
|
|
|||
|
|
@ -1117,7 +1117,7 @@ static bool has_annotation_selection (const lay::LayoutView *view)
|
|||
{
|
||||
std::vector<ant::Service *> ant_services = view->get_plugins <ant::Service> ();
|
||||
for (std::vector<ant::Service *>::const_iterator s = ant_services.begin (); s != ant_services.end (); ++s) {
|
||||
if ((*s)->selection_size () > 0) {
|
||||
if ((*s)->has_selection ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ gsi::EnumIn<db::LoadLayoutOptions, db::CellConflictResolution> decl_dbCommonRead
|
|||
gsi::enum_const ("RenameCell", db::RenameCell,
|
||||
"@brief The new cell will be renamed to become unique\n"
|
||||
),
|
||||
"@brief This enum specifies how cell conflicts are handled if a layout read into another layout and a cell name conflict arises. "
|
||||
"@brief This enum specifies how cell conflicts are handled if a layout read into another layout and a cell name conflict arises.\n"
|
||||
"Until version 0.26.8 and before, the mode was always 'AddToCell'. On reading, a cell was 'reopened' when encountering a cell name "
|
||||
"which already existed. This mode is still the default. The other modes are made available to support other ways of merging layouts.\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -2032,13 +2032,26 @@ PartialService::mouse_release_event (const db::DPoint &p, unsigned int buttons,
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
bool
|
||||
PartialService::has_selection ()
|
||||
{
|
||||
return ! m_selection.empty ();
|
||||
}
|
||||
|
||||
size_t
|
||||
PartialService::selection_size ()
|
||||
{
|
||||
return m_selection.size ();
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
PartialService::has_transient_selection ()
|
||||
{
|
||||
// there is no specific transient selection for the partial editor
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
PartialService::del ()
|
||||
{
|
||||
// stop dragging
|
||||
|
|
|
|||
|
|
@ -240,10 +240,20 @@ public:
|
|||
virtual double catch_distance ();
|
||||
|
||||
/**
|
||||
* @brief Returns the number of selected objects
|
||||
* @brief Indicates whether objects are selected
|
||||
*/
|
||||
virtual bool has_selection ();
|
||||
|
||||
/**
|
||||
* @brief Indicates how many objects are selected
|
||||
*/
|
||||
virtual size_t selection_size ();
|
||||
|
||||
/**
|
||||
* @brief Indicates whether objects are selected in transient mode
|
||||
*/
|
||||
virtual bool has_transient_selection ();
|
||||
|
||||
/**
|
||||
* @brief Implement the "select" method at least to clear the selection
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ Service::highlight (unsigned int n)
|
|||
void
|
||||
Service::cut ()
|
||||
{
|
||||
if (selection_size () > 0 && view ()->is_editable ()) {
|
||||
if (has_selection () && view ()->is_editable ()) {
|
||||
// copy & delete the selected objects
|
||||
copy_selected ();
|
||||
del_selected ();
|
||||
|
|
@ -834,7 +834,7 @@ Service::edit_cancel ()
|
|||
void
|
||||
Service::del ()
|
||||
{
|
||||
if (selection_size () > 0 && view ()->is_editable ()) {
|
||||
if (has_selection () && view ()->is_editable ()) {
|
||||
// delete the selected objects
|
||||
del_selected ();
|
||||
}
|
||||
|
|
@ -871,14 +871,19 @@ Service::del_selected ()
|
|||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
bool
|
||||
Service::has_selection ()
|
||||
{
|
||||
return ! m_selection.empty ();
|
||||
}
|
||||
|
||||
size_t
|
||||
Service::selection_size ()
|
||||
{
|
||||
return m_selection.size ();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
bool
|
||||
Service::has_transient_selection ()
|
||||
{
|
||||
return ! m_transient_selection.empty ();
|
||||
|
|
@ -1016,7 +1021,7 @@ Service::transient_select (const db::DPoint &pos)
|
|||
|
||||
}
|
||||
|
||||
if (editables ()->selection_size () == 0) {
|
||||
if (! editables ()->has_selection ()) {
|
||||
display_status (true);
|
||||
}
|
||||
|
||||
|
|
@ -1055,7 +1060,7 @@ Service::transient_select (const db::DPoint &pos)
|
|||
|
||||
mp_transient_marker = marker;
|
||||
|
||||
if (editables ()->selection_size () == 0) {
|
||||
if (! editables ()->has_selection ()) {
|
||||
display_status (true);
|
||||
}
|
||||
|
||||
|
|
@ -1410,7 +1415,7 @@ Service::move_markers (const db::DTrans &t)
|
|||
if (m_move_trans != t) {
|
||||
|
||||
// display current move vector
|
||||
if (selection_size () > 0) {
|
||||
if (has_selection ()) {
|
||||
std::string pos = std::string ("dx: ") + tl::micron_to_string (t.disp ().x ()) + " dy: " + tl::micron_to_string (t.disp ().y ());
|
||||
if (t.rot () != 0) {
|
||||
pos += std::string (" ") + ((const db::DFTrans &) t).to_string ();
|
||||
|
|
|
|||
|
|
@ -159,12 +159,17 @@ public:
|
|||
virtual void end_move (const db::DPoint &p, lay::angle_constraint_type ac);
|
||||
|
||||
/**
|
||||
* @brief Tell the number of selected objects
|
||||
* @brief Indicates whether objects are selected
|
||||
*/
|
||||
virtual bool has_selection ();
|
||||
|
||||
/**
|
||||
* @brief Indicates how many objects are selected
|
||||
*/
|
||||
virtual size_t selection_size ();
|
||||
|
||||
/**
|
||||
* @brief Tell if anything is selected in the transient selection
|
||||
* @brief Indicates whether objects are selected in transient mode
|
||||
*/
|
||||
virtual bool has_transient_selection ();
|
||||
|
||||
|
|
|
|||
|
|
@ -525,7 +525,7 @@ static bool has_object_selection (const lay::LayoutView *view)
|
|||
{
|
||||
std::vector<edt::Service *> edt_services = view->get_plugins <edt::Service> ();
|
||||
for (std::vector<edt::Service *>::const_iterator s = edt_services.begin (); s != edt_services.end (); ++s) {
|
||||
if ((*s)->selection_size () > 0) {
|
||||
if ((*s)->has_selection ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1336,7 +1336,7 @@ static bool has_image_selection (const lay::LayoutView *view)
|
|||
{
|
||||
std::vector<img::Service *> img = view->get_plugins <img::Service> ();
|
||||
for (std::vector<img::Service *>::const_iterator s = img.begin (); s != img.end (); ++s) {
|
||||
if ((*s)->selection_size () > 0) {
|
||||
if ((*s)->has_selection ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1006,7 +1006,7 @@ Service::edit_cancel ()
|
|||
void
|
||||
Service::cut ()
|
||||
{
|
||||
if (selection_size () > 0) {
|
||||
if (has_selection ()) {
|
||||
|
||||
// copy & delete the selected images
|
||||
copy_selected ();
|
||||
|
|
@ -1052,7 +1052,7 @@ Service::paste ()
|
|||
void
|
||||
Service::del ()
|
||||
{
|
||||
if (selection_size () > 0) {
|
||||
if (has_selection ()) {
|
||||
|
||||
// delete the selected images
|
||||
del_selected ();
|
||||
|
|
@ -1078,12 +1078,24 @@ Service::del_selected ()
|
|||
mp_view->annotation_shapes ().erase_positions (positions.begin (), positions.end ());
|
||||
}
|
||||
|
||||
size_t
|
||||
bool
|
||||
Service::has_selection ()
|
||||
{
|
||||
return ! m_selected.empty ();
|
||||
}
|
||||
|
||||
size_t
|
||||
Service::selection_size ()
|
||||
{
|
||||
return m_selected.size ();
|
||||
}
|
||||
|
||||
bool
|
||||
Service::has_transient_selection ()
|
||||
{
|
||||
return mp_transient_view != 0;
|
||||
}
|
||||
|
||||
void
|
||||
Service::clear_previous_selection ()
|
||||
{
|
||||
|
|
@ -1193,7 +1205,7 @@ Service::transient_select (const db::DPoint &pos)
|
|||
|
||||
// if in move mode (which also receives transient_select requests) the move will take the selection,
|
||||
// hence only highlight the transient selection if it's part of the current selection.
|
||||
if (view ()->selection_size () > 0 && view ()->is_move_mode () && m_selected.find (imin) == m_selected.end ()) {
|
||||
if (view ()->has_selection () && view ()->is_move_mode () && m_selected.find (imin) == m_selected.end ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1208,7 +1220,7 @@ Service::transient_select (const db::DPoint &pos)
|
|||
|
||||
}
|
||||
|
||||
if (any_selected && editables ()->selection_size () == 0) {
|
||||
if (any_selected && ! editables ()->has_selection ()) {
|
||||
display_status (true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -275,11 +275,21 @@ public:
|
|||
virtual void paste ();
|
||||
|
||||
/**
|
||||
* @brief Tell the number of selected objects
|
||||
* @brief Indicates if any objects are selected
|
||||
*/
|
||||
virtual bool has_selection ();
|
||||
|
||||
/**
|
||||
* @brief Indicates how many objects are selected
|
||||
*/
|
||||
virtual size_t selection_size ();
|
||||
|
||||
/**
|
||||
/**
|
||||
* @brief Indicates if any objects are selected in transient mode
|
||||
*/
|
||||
virtual bool has_transient_selection ();
|
||||
|
||||
/**
|
||||
* @brief point selection proximity predicate
|
||||
*/
|
||||
virtual double click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mode);
|
||||
|
|
|
|||
|
|
@ -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-> ()) {
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,6 +180,25 @@ class LAYLayoutView_TestClass < TestBase
|
|||
|
||||
assert_equal(cv1.index, 0)
|
||||
|
||||
assert_equal(view.has_selection?, false)
|
||||
assert_equal(view.selection_size, 0)
|
||||
|
||||
view.select_from(RBA::DBox::new(-1.0, -1.0, 1.0, 1.0))
|
||||
assert_equal(selection_changed, 1)
|
||||
assert_equal(view.selection_size, 4)
|
||||
assert_equal(view.has_selection?, true)
|
||||
|
||||
view.select_from(RBA::DPoint::new(0, 0), RBA::LayoutView::Invert)
|
||||
assert_equal(selection_changed, 2)
|
||||
assert_equal(view.selection_size, 3)
|
||||
assert_equal(view.has_selection?, true)
|
||||
|
||||
view.clear_selection
|
||||
assert_equal(selection_changed, 3)
|
||||
assert_equal(view.has_selection?, false)
|
||||
assert_equal(view.selection_size, 0)
|
||||
selection_changed = 0
|
||||
|
||||
cv2 = mw.load_layout(ENV["TESTSRC"] + "/testdata/gds/t10.gds", 2)
|
||||
assert_equal(RBA::CellView::active.index, 1)
|
||||
assert_equal(cv2.index, 1)
|
||||
|
|
@ -196,8 +215,7 @@ class LAYLayoutView_TestClass < TestBase
|
|||
assert_equal(layer_list_deleted, 0)
|
||||
assert_equal(current_layer_list_changed, 0)
|
||||
assert_equal(cell_visibility_changed, 0)
|
||||
# TODO: spontaneous event: does it hurt?
|
||||
assert_equal(selection_changed, 1)
|
||||
assert_equal(selection_changed, 0)
|
||||
|
||||
view.pan_up
|
||||
assert_equal(viewport_changed, 2)
|
||||
|
|
@ -234,8 +252,7 @@ class LAYLayoutView_TestClass < TestBase
|
|||
assert_equal(layer_list_deleted, 0)
|
||||
assert_equal(current_layer_list_changed, 0)
|
||||
assert_equal(cell_visibility_changed, 0)
|
||||
# TODO: spontaneous event: does it hurt?
|
||||
assert_equal(selection_changed, 1)
|
||||
assert_equal(selection_changed, 0)
|
||||
|
||||
cv2.path = [ cv2.layout.cell("RINGO").cell_index, cv2.layout.cell("INV2").cell_index, cv2.layout.cell("TRANS").cell_index ]
|
||||
assert_equal(cv2.cell_name, "TRANS")
|
||||
|
|
@ -252,8 +269,7 @@ class LAYLayoutView_TestClass < TestBase
|
|||
assert_equal(layer_list_deleted, 0)
|
||||
assert_equal(current_layer_list_changed, 0)
|
||||
assert_equal(cell_visibility_changed, 0)
|
||||
# TODO: spontaneous event: does it hurt?
|
||||
assert_equal(selection_changed, 2)
|
||||
assert_equal(selection_changed, 0)
|
||||
|
||||
cv2.path = [ cv2.layout.cell("RINGO").cell_index, cv2.layout.cell("INV2").cell_index ]
|
||||
assert_equal(cv2.cell_name, "INV2")
|
||||
|
|
@ -270,8 +286,7 @@ class LAYLayoutView_TestClass < TestBase
|
|||
assert_equal(layer_list_deleted, 0)
|
||||
assert_equal(current_layer_list_changed, 0)
|
||||
assert_equal(cell_visibility_changed, 0)
|
||||
# TODO: spontaneous event: does it hurt?
|
||||
assert_equal(selection_changed, 3)
|
||||
assert_equal(selection_changed, 0)
|
||||
|
||||
sp = []
|
||||
cv2.cell.each_inst { |i| sp << RBA::InstElement::new(i); break }
|
||||
|
|
@ -291,8 +306,7 @@ class LAYLayoutView_TestClass < TestBase
|
|||
assert_equal(layer_list_deleted, 0)
|
||||
assert_equal(current_layer_list_changed, 0)
|
||||
assert_equal(cell_visibility_changed, 0)
|
||||
# TODO: spontaneous event: does it hurt?
|
||||
assert_equal(selection_changed, 4)
|
||||
assert_equal(selection_changed, 0)
|
||||
|
||||
cv2.ascend
|
||||
|
||||
|
|
@ -310,8 +324,7 @@ class LAYLayoutView_TestClass < TestBase
|
|||
assert_equal(layer_list_deleted, 0)
|
||||
assert_equal(current_layer_list_changed, 0)
|
||||
assert_equal(cell_visibility_changed, 0)
|
||||
# TODO: spontaneous event: does it hurt?
|
||||
assert_equal(selection_changed, 5)
|
||||
assert_equal(selection_changed, 0)
|
||||
|
||||
assert_equal(view.cellviews, 2)
|
||||
|
||||
|
|
@ -332,8 +345,7 @@ class LAYLayoutView_TestClass < TestBase
|
|||
assert_equal(layer_list_deleted, 0)
|
||||
assert_equal(current_layer_list_changed, 0)
|
||||
assert_equal(cell_visibility_changed, 0)
|
||||
# TODO: spontaneous event: does it hurt?
|
||||
assert_equal(selection_changed, 6)
|
||||
assert_equal(selection_changed, 0)
|
||||
|
||||
active_cellview_changed = 0
|
||||
cellviews_changed = 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue