Implement SCH_SELECTION_TOOL (but still with legacy semantics).
This commit is contained in:
parent
e885d739a4
commit
1a007c3e4b
|
@ -139,3 +139,16 @@ TOOL_ACTION ACTIONS::gridResetOrigin( "common.Control.gridResetOrigin",
|
|||
TOOL_ACTION ACTIONS::gridPreset( "common.Control.gridPreset",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" );
|
||||
|
||||
|
||||
// System-wide selection Events
|
||||
|
||||
///> Event sent after an item is selected.
|
||||
const TOOL_EVENT EVENTS::SelectedEvent( TC_MESSAGE, TA_ACTION, "common.Interactive.selected" );
|
||||
|
||||
///> Event sent after an item is unselected.
|
||||
const TOOL_EVENT EVENTS::UnselectedEvent( TC_MESSAGE, TA_ACTION, "common.Interactive.unselected" );
|
||||
|
||||
///> Event sent after selection is cleared.
|
||||
const TOOL_EVENT EVENTS::ClearedEvent( TC_MESSAGE, TA_ACTION, "common.Interactive.cleared" );
|
||||
|
||||
|
|
|
@ -164,7 +164,6 @@ set( EESCHEMA_SRCS
|
|||
generate_alias_info.cpp
|
||||
getpart.cpp
|
||||
hierarch.cpp
|
||||
tools/sch_editor_control.cpp
|
||||
hotkeys.cpp
|
||||
lib_arc.cpp
|
||||
lib_bezier.cpp
|
||||
|
@ -244,6 +243,8 @@ set( EESCHEMA_SRCS
|
|||
|
||||
tools/sch_actions.cpp
|
||||
tools/sch_drawing_tool.cpp
|
||||
tools/sch_edit_tool.cpp
|
||||
tools/sch_editor_control.cpp
|
||||
tools/sch_picker_tool.cpp
|
||||
tools/sch_selection_tool.cpp
|
||||
tools/selection.cpp
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
#include <kiface_i.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
|
||||
#define FIELD_PADDING 10 // arbitrarily chosen for aesthetics
|
||||
#define FIELD_PADDING_ALIGNED 18 // aligns 50 mil text to a 100 mil grid
|
||||
|
@ -683,6 +685,7 @@ const AUTOPLACER::SIDE AUTOPLACER::SIDE_RIGHT( 1, 0 );
|
|||
|
||||
void SCH_EDIT_FRAME::OnAutoplaceFields( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
|
||||
|
@ -692,9 +695,8 @@ void SCH_EDIT_FRAME::OnAutoplaceFields( wxCommandEvent& aEvent )
|
|||
if( aEvent.GetInt() == 0 )
|
||||
return;
|
||||
|
||||
EDA_HOTKEY_CLIENT_DATA& data = dynamic_cast<EDA_HOTKEY_CLIENT_DATA&>(
|
||||
*aEvent.GetClientObject() );
|
||||
item = LocateItem( data.GetPosition(), SCH_COLLECTOR::MovableItems, aEvent.GetInt() );
|
||||
auto& data = dynamic_cast<EDA_HOTKEY_CLIENT_DATA&>( *aEvent.GetClientObject() );
|
||||
item = selTool->SelectPoint( data.GetPosition(), SCH_COLLECTOR::MovableItems );
|
||||
screen->SetCurItem( NULL );
|
||||
|
||||
if( !item || item->GetEditFlags() )
|
||||
|
|
|
@ -23,224 +23,16 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* eeschema/controle.cpp
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <gr_basic.h>
|
||||
#include <sch_draw_panel.h>
|
||||
#include <eda_dde.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <msgpanel.h>
|
||||
#include <bitmaps.h>
|
||||
|
||||
#include <eeschema_id.h>
|
||||
#include <general.h>
|
||||
#include <hotkeys.h>
|
||||
#include <lib_edit_frame.h>
|
||||
#include <viewlib_frame.h>
|
||||
#include <lib_draw_item.h>
|
||||
#include <lib_pin.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_sheet_path.h>
|
||||
#include <sch_marker.h>
|
||||
#include <sch_component.h>
|
||||
#include <sch_view.h>
|
||||
|
||||
|
||||
SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
|
||||
int aHotKeyCommandId,
|
||||
bool* aClarificationMenuCancelled )
|
||||
{
|
||||
SCH_ITEM* item;
|
||||
LIB_PIN* Pin = NULL;
|
||||
SCH_COMPONENT* component = NULL;
|
||||
wxPoint gridPosition = GetNearestGridPosition( aPosition );
|
||||
|
||||
// Check the on grid position first. There is more likely to be multiple items on
|
||||
// grid than off grid.
|
||||
m_canvas->SetAbortRequest( false ); // be sure a old abort request in not pending
|
||||
item = LocateItem( gridPosition, aFilterList, aHotKeyCommandId );
|
||||
|
||||
// If the user aborted the clarification context menu, don't show it again at the
|
||||
// off grid position.
|
||||
if( !item && m_canvas->GetAbortRequest() )
|
||||
{
|
||||
if( aClarificationMenuCancelled )
|
||||
*aClarificationMenuCancelled = true;
|
||||
|
||||
m_canvas->SetAbortRequest( false );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( !item && (aPosition != gridPosition) )
|
||||
item = LocateItem( aPosition, aFilterList, aHotKeyCommandId );
|
||||
|
||||
if( !item )
|
||||
{
|
||||
if( aClarificationMenuCancelled )
|
||||
*aClarificationMenuCancelled = m_canvas->GetAbortRequest();
|
||||
|
||||
m_canvas->SetAbortRequest( false ); // Just in case the user aborted the context menu.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Cross probing to Pcbnew if a pin or a component is found
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_FIELD_T:
|
||||
case LIB_FIELD_T:
|
||||
component = (SCH_COMPONENT*) item->GetParent();
|
||||
SendMessageToPCBNEW( item, component );
|
||||
break;
|
||||
|
||||
case SCH_COMPONENT_T:
|
||||
component = (SCH_COMPONENT*) item;
|
||||
SendMessageToPCBNEW( item, component );
|
||||
break;
|
||||
|
||||
case LIB_PIN_T:
|
||||
Pin = (LIB_PIN*) item;
|
||||
component = (SCH_COMPONENT*) LocateItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
|
||||
break;
|
||||
|
||||
/* case SCH_SHEET_T: */
|
||||
/* // This may lag on larger projects */
|
||||
/* SendMessageToPCBNEW( item, nullptr ); */
|
||||
/* break; */
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
if( Pin )
|
||||
{
|
||||
// Force display pin information (the previous display could be a component info)
|
||||
MSG_PANEL_ITEMS items;
|
||||
|
||||
Pin->GetMsgPanelInfo( m_UserUnits, items, component );
|
||||
|
||||
SetMsgPanel( items );
|
||||
|
||||
// Cross probing:2 - pin found, and send a locate pin command to Pcbnew (highlight net)
|
||||
SendMessageToPCBNEW( Pin, component );
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
|
||||
int aHotKeyCommandId )
|
||||
{
|
||||
SCH_ITEM* item = NULL;
|
||||
|
||||
m_collectedItems.Collect( GetScreen()->GetDrawItems(), aFilterList, aPosition );
|
||||
|
||||
if( m_collectedItems.GetCount() == 0 )
|
||||
{
|
||||
ClearMsgPanel();
|
||||
}
|
||||
else if( m_collectedItems.GetCount() == 1 )
|
||||
{
|
||||
item = m_collectedItems[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// There are certain parent/child and enclosure combinations that can be handled
|
||||
// automatically. Since schematics are meant to be human-readable we don't have
|
||||
// all the various overlap and coverage issues that we do in Pcbnew.
|
||||
if( m_collectedItems.GetCount() == 2 )
|
||||
{
|
||||
SCH_ITEM* a = m_collectedItems[ 0 ];
|
||||
SCH_ITEM* b = m_collectedItems[ 1 ];
|
||||
|
||||
if( a->GetParent() == b )
|
||||
item = a;
|
||||
else if( a == b->GetParent() )
|
||||
item = b;
|
||||
else if( a->Type() == SCH_SHEET_T && b->Type() != SCH_SHEET_T )
|
||||
item = b;
|
||||
else if( b->Type() == SCH_SHEET_T && a->Type() != SCH_SHEET_T )
|
||||
item = a;
|
||||
}
|
||||
|
||||
// There are certain combinations of items that do not need clarification such as
|
||||
// a corner were two lines meet or all the items form a junction.
|
||||
if( aHotKeyCommandId )
|
||||
{
|
||||
switch( aHotKeyCommandId )
|
||||
{
|
||||
case HK_DRAG:
|
||||
if( m_collectedItems.IsCorner() || m_collectedItems.IsNode( false )
|
||||
|| m_collectedItems.IsDraggableJunction() )
|
||||
{
|
||||
item = m_collectedItems[0];
|
||||
}
|
||||
break;
|
||||
|
||||
case HK_MOVE_COMPONENT_OR_ITEM:
|
||||
if( m_collectedItems.GetCount() == 2 &&
|
||||
dynamic_cast< SCH_SHEET_PIN * >( m_collectedItems[0] ) &&
|
||||
dynamic_cast< SCH_SHEET * >( m_collectedItems[1] ) )
|
||||
{
|
||||
item = m_collectedItems[0];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if( item == NULL )
|
||||
{
|
||||
wxASSERT_MSG( m_collectedItems.GetCount() <= MAX_SELECT_ITEM_IDS,
|
||||
wxT( "Select item clarification context menu size limit exceeded." ) );
|
||||
|
||||
wxMenu selectMenu;
|
||||
|
||||
AddMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ), KiBitmap( info_xpm ) );
|
||||
selectMenu.AppendSeparator();
|
||||
|
||||
for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ )
|
||||
{
|
||||
wxString text = m_collectedItems[i]->GetSelectMenuText( m_UserUnits );
|
||||
BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage();
|
||||
AddMenuItem( &selectMenu, ID_SELECT_ITEM_START + i, text, KiBitmap( xpm ) );
|
||||
}
|
||||
|
||||
// Set to NULL in case the user aborts the clarification context menu.
|
||||
GetScreen()->SetCurItem( NULL );
|
||||
m_canvas->SetAbortRequest( true ); // Changed to false if an item is selected
|
||||
PopupMenu( &selectMenu );
|
||||
|
||||
if( !m_canvas->GetAbortRequest() )
|
||||
{
|
||||
m_canvas->MoveCursorToCrossHair();
|
||||
item = GetScreen()->GetCurItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GetScreen()->SetCurItem( item );
|
||||
|
||||
if( item )
|
||||
{
|
||||
MSG_PANEL_ITEMS items;
|
||||
item->GetMsgPanelInfo( m_UserUnits, items );
|
||||
SetMsgPanel( items );
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearMsgPanel();
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
|
||||
{
|
||||
// Filter out the 'fake' mouse motion after a keyboard movement
|
||||
|
|
|
@ -143,22 +143,29 @@ void SCH_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
|
|||
}
|
||||
|
||||
|
||||
std::string FormatProbeItem( EDA_ITEM* aItem, SCH_COMPONENT* aPart )
|
||||
std::string FormatProbeItem( EDA_ITEM* aItem, SCH_COMPONENT* aComp )
|
||||
{
|
||||
// This is a keyword followed by a quoted string.
|
||||
|
||||
// Cross probing to Pcbnew if a pin or a component is found
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case SCH_FIELD_T:
|
||||
case LIB_PIN_T:
|
||||
wxFAIL_MSG( "What are we doing with LIB_* items here?" );
|
||||
break;
|
||||
|
||||
case LIB_FIELD_T:
|
||||
if( aPart )
|
||||
return StrPrintf( "$PART: \"%s\"", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
|
||||
wxFAIL_MSG( "What are we doing with LIB_* items here?" );
|
||||
// fall through to SCH_FIELD_T:
|
||||
|
||||
case SCH_FIELD_T:
|
||||
if( aComp )
|
||||
return StrPrintf( "$PART: \"%s\"", TO_UTF8( aComp->GetField( REFERENCE )->GetText() ) );
|
||||
break;
|
||||
|
||||
case SCH_COMPONENT_T:
|
||||
aPart = (SCH_COMPONENT*) aItem;
|
||||
return StrPrintf( "$PART: \"%s\"", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
|
||||
aComp = (SCH_COMPONENT*) aItem;
|
||||
return StrPrintf( "$PART: \"%s\"", TO_UTF8( aComp->GetField( REFERENCE )->GetText() ) );
|
||||
|
||||
case SCH_SHEET_T:
|
||||
{
|
||||
|
@ -166,24 +173,23 @@ std::string FormatProbeItem( EDA_ITEM* aItem, SCH_COMPONENT* aPart )
|
|||
return StrPrintf( "$SHEET: \"%8.8lX\"", (unsigned long) sheet->GetTimeStamp() );
|
||||
}
|
||||
|
||||
case LIB_PIN_T:
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
if( !aPart )
|
||||
break;
|
||||
|
||||
LIB_PIN* pin = (LIB_PIN*) aItem;
|
||||
SCH_PIN* pin = (SCH_PIN*) aItem;
|
||||
aComp = pin->GetParentComponent();
|
||||
|
||||
if( !pin->GetNumber().IsEmpty() )
|
||||
{
|
||||
return StrPrintf( "$PIN: \"%s\" $PART: \"%s\"", TO_UTF8( pin->GetNumber() ),
|
||||
TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
|
||||
return StrPrintf( "$PIN: \"%s\" $PART: \"%s\"",
|
||||
TO_UTF8( pin->GetNumber() ),
|
||||
TO_UTF8( aComp->GetField( REFERENCE )->GetText() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return StrPrintf( "$PART: \"%s\"", TO_UTF8( aPart->GetField( REFERENCE )->GetText() ) );
|
||||
return StrPrintf( "$PART: \"%s\"",
|
||||
TO_UTF8( aComp->GetField( REFERENCE )->GetText() ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include <sch_sheet.h>
|
||||
|
||||
#include <dialogs/dialog_schematic_find.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
|
||||
// Remark: the hotkey message info is used as keyword in hotkey config files and
|
||||
// as comments in help windows, therefore translated only when displayed
|
||||
|
@ -610,7 +612,8 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
|||
|
||||
if( aItem == NULL )
|
||||
{
|
||||
aItem = LocateAndShowItem( aPosition, SCH_COLLECTOR::CopyableItems );
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
aItem = selTool->SelectPoint( aPosition, SCH_COLLECTOR::CopyableItems );
|
||||
|
||||
if( aItem == NULL )
|
||||
break;
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
* @param aIndex The index into the list.
|
||||
* @return LIB_ITEM* at \a aIndex or NULL.
|
||||
*/
|
||||
LIB_ITEM* operator[]( int aIndex ) const
|
||||
LIB_ITEM* operator[]( int aIndex ) const override
|
||||
{
|
||||
if( (unsigned)aIndex < (unsigned)GetCount() )
|
||||
return (LIB_ITEM*) m_List[ aIndex ];
|
||||
|
|
|
@ -34,10 +34,13 @@
|
|||
#include <sch_bitmap.h>
|
||||
#include <netlist_object.h>
|
||||
#include <sch_view.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
|
||||
void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
||||
{
|
||||
SCH_ITEM* item = GetScreen()->GetCurItem();
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
|
||||
if( GetToolId() == ID_NO_TOOL_SELECTED )
|
||||
{
|
||||
|
@ -76,7 +79,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
|||
}
|
||||
else
|
||||
{
|
||||
item = LocateAndShowItem( aPosition );
|
||||
item = selTool->SelectPoint( aPosition );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +99,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
|||
SCH_COMPONENT_T,
|
||||
SCH_SHEET_PIN_T,
|
||||
EOT };
|
||||
item = LocateAndShowItem( aPosition, wiresAndComponents );
|
||||
item = selTool->SelectPoint( aPosition, wiresAndComponents );
|
||||
|
||||
if( !item )
|
||||
break;
|
||||
|
@ -121,7 +124,7 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
|||
case ID_SIM_TUNE:
|
||||
{
|
||||
constexpr KICAD_T fieldsAndComponents[] = { SCH_COMPONENT_T, SCH_FIELD_T, EOT };
|
||||
item = LocateAndShowItem( aPosition, fieldsAndComponents );
|
||||
item = selTool->SelectPoint( aPosition, fieldsAndComponents );
|
||||
|
||||
if( !item )
|
||||
return;
|
||||
|
@ -159,13 +162,14 @@ void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
|
|||
void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition )
|
||||
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
EDA_ITEM* item = GetScreen()->GetCurItem();
|
||||
|
||||
switch( GetToolId() )
|
||||
{
|
||||
case ID_NO_TOOL_SELECTED:
|
||||
if( item == NULL || item->GetEditFlags() == 0 )
|
||||
item = LocateAndShowItem( aPosition, SCH_COLLECTOR::DoubleClickItems );
|
||||
item = selTool->SelectPoint( aPosition, SCH_COLLECTOR::DoubleClickItems );
|
||||
|
||||
if( item == NULL || item->GetEditFlags() != 0 )
|
||||
break;
|
||||
|
|
|
@ -54,7 +54,9 @@
|
|||
#include <sch_view.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_actions.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
|
||||
static void AddMenusForBlock( wxMenu* PopMenu, SCH_EDIT_FRAME* frame );
|
||||
static void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame );
|
||||
|
@ -77,6 +79,7 @@ static void AddMenusForBusEntry( wxMenu* aPopMenu, SCH_BUS_ENTRY_BASE * aBusEntr
|
|||
|
||||
bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_ITEM* item = GetScreen()->GetCurItem();
|
||||
bool blockActive = GetScreen()->IsBlockActive();
|
||||
wxString msg;
|
||||
|
@ -147,7 +150,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
|
|||
if( item == NULL || item->GetEditFlags() == 0 )
|
||||
{
|
||||
bool actionCancelled = false;
|
||||
item = LocateAndShowItem( aPosition, SCH_COLLECTOR::AllItemsButPins, 0, &actionCancelled );
|
||||
item = selTool->SelectPoint( aPosition, SCH_COLLECTOR::AllItemsButPins, &actionCancelled );
|
||||
|
||||
// If the clarify item selection context menu is aborted, don't show the context menu.
|
||||
if( item == NULL && actionCancelled )
|
||||
|
@ -744,6 +747,7 @@ void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame )
|
|||
|
||||
void AddMenusForBus( wxMenu* PopMenu, SCH_LINE* Bus, SCH_EDIT_FRAME* frame )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = frame->GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
wxPoint pos = frame->GetCrossHairPosition();
|
||||
wxString msg;
|
||||
|
||||
|
@ -773,8 +777,8 @@ void AddMenusForBus( wxMenu* PopMenu, SCH_LINE* Bus, SCH_EDIT_FRAME* frame )
|
|||
|
||||
// Have to pick up the pointer again because it may have been changed by SchematicCleanUp
|
||||
bool actionCancelled = false;
|
||||
Bus = dynamic_cast<SCH_LINE*>( frame->LocateAndShowItem( pos, SCH_COLLECTOR::AllItemsButPins,
|
||||
0, &actionCancelled ) );
|
||||
Bus = dynamic_cast<SCH_LINE*>( selTool->SelectPoint( pos, SCH_COLLECTOR::AllItemsButPins,
|
||||
&actionCancelled ) );
|
||||
wxASSERT( Bus );
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,11 @@ public:
|
|||
|
||||
KIGFX::SCH_RENDER_SETTINGS* GetRenderSettings();
|
||||
|
||||
/**
|
||||
* Allow some frames to show/hide hidden pins. The default impl shows all pins.
|
||||
*/
|
||||
virtual bool GetShowAllPins() const { return true; }
|
||||
|
||||
/**
|
||||
* switches currently used canvas ( Cairo / OpenGL).
|
||||
*/
|
||||
|
|
|
@ -51,7 +51,7 @@ const KICAD_T SCH_COLLECTOR::AllItems[] = {
|
|||
SCH_HIER_LABEL_T,
|
||||
SCH_FIELD_T,
|
||||
SCH_COMPONENT_T,
|
||||
LIB_PIN_T,
|
||||
SCH_PIN_T,
|
||||
SCH_SHEET_PIN_T,
|
||||
SCH_SHEET_T,
|
||||
EOT
|
||||
|
@ -238,43 +238,21 @@ const KICAD_T SCH_COLLECTOR::DoubleClickItems[] = {
|
|||
|
||||
SEARCH_RESULT SCH_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData )
|
||||
{
|
||||
if( aItem->Type() != LIB_PIN_T && !aItem->HitTest( m_RefPos ) )
|
||||
return SEARCH_CONTINUE;
|
||||
|
||||
// Pins have special hit testing requirements that are relative to their parent
|
||||
// SCH_COMPONENT item.
|
||||
if( aItem->Type() == LIB_PIN_T )
|
||||
{
|
||||
wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T,
|
||||
SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) );
|
||||
|
||||
// Pin hit testing is relative to the components position and orientation in the
|
||||
// schematic. The hit test position must be converted to library coordinates.
|
||||
SCH_COMPONENT* component = (SCH_COMPONENT*) aTestData;
|
||||
TRANSFORM transform = component->GetTransform().InverseTransform();
|
||||
wxPoint position = transform.TransformCoordinate( m_RefPos - component->GetPosition() );
|
||||
|
||||
position.y *= -1; // Y axis polarity in schematic is inverted from library.
|
||||
|
||||
if( !aItem->HitTest( position ) )
|
||||
return SEARCH_CONTINUE;
|
||||
}
|
||||
|
||||
if( aItem->HitTest( m_RefPos ) )
|
||||
Append( aItem );
|
||||
|
||||
return SEARCH_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
void SCH_COLLECTOR::Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[],
|
||||
const wxPoint& aPosition )
|
||||
void SCH_COLLECTOR::Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[], const wxPoint& aPos )
|
||||
{
|
||||
Empty(); // empty the collection just in case
|
||||
|
||||
SetScanTypes( aFilterList );
|
||||
|
||||
// remember where the snapshot was taken from and pass refPos to the Inspect() function.
|
||||
SetRefPos( aPosition );
|
||||
SetRefPos( aPos );
|
||||
|
||||
EDA_ITEM::IterateForward( aItem, m_inspector, NULL, m_ScanTypes );
|
||||
}
|
||||
|
@ -319,7 +297,7 @@ bool SCH_COLLECTOR::IsNode( bool aIncludePins ) const
|
|||
continue;
|
||||
}
|
||||
|
||||
if( type == LIB_PIN_T )
|
||||
if( type == SCH_PIN_T )
|
||||
{
|
||||
if( !aIncludePins )
|
||||
return false;
|
||||
|
@ -559,7 +537,7 @@ SEARCH_RESULT SCH_FIND_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData )
|
|||
|
||||
if( aItem->Matches( m_findReplaceData, m_currentSheetPath, &position ) )
|
||||
{
|
||||
if( aItem->Type() == LIB_PIN_T )
|
||||
if( aItem->Type() == SCH_PIN_T )
|
||||
{
|
||||
wxCHECK_MSG( aTestData && ( (EDA_ITEM*) aTestData )->Type() == SCH_COMPONENT_T,
|
||||
SEARCH_CONTINUE, wxT( "Cannot inspect invalid data. Bad programmer!" ) );
|
||||
|
|
|
@ -142,7 +142,7 @@ public:
|
|||
* @param aIndex The index into the list.
|
||||
* @return SCH_ITEM* at \a aIndex or NULL.
|
||||
*/
|
||||
SCH_ITEM* operator[]( int aIndex ) const
|
||||
SCH_ITEM* operator[]( int aIndex ) const override
|
||||
{
|
||||
if( (unsigned)aIndex < (unsigned)GetCount() )
|
||||
return (SCH_ITEM*) m_List[ aIndex ];
|
||||
|
@ -159,9 +159,9 @@ public:
|
|||
* @param aFilterList A list of #KICAD_T types with a terminating #EOT, that determines
|
||||
* what is to be collected and the priority order of the resulting
|
||||
* collection.
|
||||
* @param aPosition A wxPoint to use in hit-testing.
|
||||
* @param aPos A wxPoint to use in hit-testing.
|
||||
*/
|
||||
void Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[], const wxPoint& aPosition );
|
||||
void Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[], const wxPoint& aPos );
|
||||
|
||||
/**
|
||||
* Function IsCorner
|
||||
|
@ -289,7 +289,7 @@ public:
|
|||
}
|
||||
|
||||
SCH_ITEM* GetItem( int ndx ) const;
|
||||
SCH_ITEM* operator[]( int ndx ) const;
|
||||
SCH_ITEM* operator[]( int ndx ) const override;
|
||||
|
||||
void SetForceSearch( bool doSearch = true ) { m_forceSearch = doSearch; }
|
||||
|
||||
|
@ -405,8 +405,7 @@ class SCH_TYPE_COLLECTOR : public SCH_COLLECTOR
|
|||
public:
|
||||
/**
|
||||
* Function Inspect
|
||||
* is the examining function within the INSPECTOR which is passed to the
|
||||
* Iterate function.
|
||||
* is the examining function within the INSPECTOR which is passed to the Iterate function.
|
||||
*
|
||||
* @param testItem An EDA_ITEM to examine.
|
||||
* @param testData is not used in this class.
|
||||
|
@ -417,12 +416,11 @@ public:
|
|||
|
||||
/**
|
||||
* Function Collect
|
||||
* scans a BOARD_ITEM using this class's Inspector method, which does
|
||||
* the collection.
|
||||
* @param aBoard The BOARD_ITEM to scan.
|
||||
* scans a DLIST using this class's Inspector method, which does the collection.
|
||||
* @param aItem The head of a DLIST to scan.
|
||||
* @param aScanList The KICAD_Ts to gather up.
|
||||
*/
|
||||
void Collect( SCH_ITEM* aBoard, const KICAD_T aScanList[] );
|
||||
void Collect( SCH_ITEM* aItem, const KICAD_T aScanList[] );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1612,19 +1612,12 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR aInspector, void* aTestData,
|
|||
return SEARCH_QUIT;
|
||||
break;
|
||||
|
||||
case LIB_PIN_T:
|
||||
if( PART_SPTR part = m_part.lock() )
|
||||
case SCH_PIN_T:
|
||||
for( SCH_PIN& pin : m_pins )
|
||||
{
|
||||
LIB_PINS pins;
|
||||
|
||||
part->GetPins( pins, m_unit, m_convert );
|
||||
|
||||
for( size_t i = 0; i < pins.size(); i++ )
|
||||
{
|
||||
if( SEARCH_QUIT == aInspector( pins[ i ], (void*) this ) )
|
||||
if( SEARCH_QUIT == aInspector( &pin, (void*) this ) )
|
||||
return SEARCH_QUIT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1728,7 +1721,7 @@ bool SCH_COMPONENT::operator!=( const SCH_COMPONENT& aComponent ) const
|
|||
}
|
||||
|
||||
|
||||
SCH_ITEM& SCH_COMPONENT::operator=( const SCH_ITEM& aItem )
|
||||
SCH_COMPONENT& SCH_COMPONENT::operator=( const SCH_ITEM& aItem )
|
||||
{
|
||||
wxCHECK_MSG( Type() == aItem.Type(), *this,
|
||||
wxT( "Cannot assign object type " ) + aItem.GetClass() + wxT( " to type " ) +
|
||||
|
|
|
@ -606,7 +606,7 @@ public:
|
|||
bool operator==( const SCH_COMPONENT& aComponent) const;
|
||||
bool operator!=( const SCH_COMPONENT& aComponent) const;
|
||||
|
||||
SCH_ITEM& operator=( const SCH_ITEM& aItem );
|
||||
SCH_COMPONENT& operator=( const SCH_ITEM& aItem );
|
||||
|
||||
bool IsReplaceable() const override { return true; }
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include <view/view.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_actions.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
|
||||
#include <wx/display.h>
|
||||
#include <build_version.h>
|
||||
|
@ -1107,6 +1108,7 @@ void SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event )
|
|||
|
||||
void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_COMPONENT* component = NULL;
|
||||
|
||||
if( event.GetId() == ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP )
|
||||
|
@ -1127,7 +1129,7 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event )
|
|||
|
||||
// Set the locat filter, according to the edit command
|
||||
const KICAD_T* filterList = SCH_COLLECTOR::ComponentsOnly;
|
||||
item = LocateAndShowItem( data->GetPosition(), filterList, event.GetInt() );
|
||||
item = selTool->SelectPoint( data->GetPosition(), filterList );
|
||||
|
||||
// Exit if no item found at the current location or the item is already being edited.
|
||||
if( item == NULL || item->GetEditFlags() != 0 )
|
||||
|
|
|
@ -225,7 +225,7 @@ public:
|
|||
bool GetForceHVLines() const { return m_forceHVLines; }
|
||||
void SetForceHVLines( bool aForceHVdirection ) { m_forceHVLines = aForceHVdirection; }
|
||||
|
||||
bool GetShowAllPins() const { return m_showAllPins; }
|
||||
bool GetShowAllPins() const override { return m_showAllPins; }
|
||||
void SetShowAllPins( bool aEnable ) { m_showAllPins = aEnable; }
|
||||
|
||||
bool GetShowFootprintPreviews() const { return m_footprintPreview; }
|
||||
|
@ -383,48 +383,6 @@ public:
|
|||
*/
|
||||
void AddItemToScreen( SCH_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Check the schematic at \a aPosition in logical (drawing) units for a item
|
||||
* matching the types in \a aFilterList.
|
||||
* <p>
|
||||
* The search is first performed at the nearest grid position to \a aPosition. If no
|
||||
* item if found on grid, then \a aPosition is tested for any items. If the item found
|
||||
* can be cross probed, a message is send to Pcbnew and the selected item is highlighted
|
||||
* in PCB editor.
|
||||
* </p>
|
||||
*
|
||||
* @param aPosition The wxPoint on the schematic to search.
|
||||
* @param aFilterList A list of #KICAD_T types to to filter.
|
||||
* @param aHotKeyCommandId A hot key command ID for performing additional tests when
|
||||
* multiple items are found at \a aPosition.
|
||||
* @param aClarifySelectionMenuCancelled is a pointer to a bool to handle a cancel command
|
||||
* from user when the user cancels the locate menu disambiguation (selection between located items)
|
||||
* @return A SCH_ITEM pointer of the item found or NULL if no item found
|
||||
*/
|
||||
SCH_ITEM* LocateAndShowItem( const wxPoint& aPosition,
|
||||
const KICAD_T aFilterList[] = SCH_COLLECTOR::AllItems,
|
||||
int aHotKeyCommandId = 0,
|
||||
bool* aClarifySelectionMenuCancelled = nullptr );
|
||||
|
||||
/**
|
||||
* Check for items at \a aPosition matching the types in \a aFilterList.
|
||||
* <p>
|
||||
* If multiple items are located at \a aPosition, a context menu is displayed to clarify
|
||||
* which item the user intended to select. If the user aborts the context menu, NULL is
|
||||
* returned and the abort request flag will be set to true. Make sure to clear this flag
|
||||
* before attempting to display any other context menus.
|
||||
* </p>
|
||||
*
|
||||
* @param aPosition The wxPoint location where to search.
|
||||
* @param aFilterList A list of #KICAD_T types to to filter.
|
||||
* @param aHotKeyCommandId A hot key command ID for performing additional tests when
|
||||
* multiple items are found at \a aPosition.
|
||||
* @return The SCH_ITEM pointer of the item found or NULL if no item found.
|
||||
*/
|
||||
SCH_ITEM* LocateItem( const wxPoint& aPosition,
|
||||
const KICAD_T aFilterList[] = SCH_COLLECTOR::AllItems,
|
||||
int aHotKeyCommandId = 0 );
|
||||
|
||||
/**
|
||||
* Delete the item found under the cross hair. If multiple items are found at the
|
||||
* cross hair position, a context menu is displayed to clarify which item to delete.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-2019 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -171,6 +171,17 @@ public:
|
|||
wxPoint& GetStoredPos() { return m_storedPos; }
|
||||
void SetStoredPos( wxPoint aPos ) { m_storedPos = aPos; }
|
||||
|
||||
/**
|
||||
* Function IsLocked
|
||||
* @return bool - true if the object is locked, else false
|
||||
*/
|
||||
virtual bool IsLocked() const { return false; }
|
||||
|
||||
/**
|
||||
* Function SetLocked
|
||||
* modifies 'lock' status for of the item.
|
||||
*/
|
||||
virtual void SetLocked( bool aLocked ) {}
|
||||
|
||||
/**
|
||||
* Function GetLayer
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <simulation_cursors.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_actions.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
|
||||
void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||
{
|
||||
|
@ -364,6 +365,7 @@ void SCH_EDIT_FRAME::OnDuplicateItem( wxCommandEvent& event )
|
|||
|
||||
void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
|
||||
|
@ -381,8 +383,7 @@ void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent )
|
|||
|
||||
wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
|
||||
|
||||
item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::MovableItems,
|
||||
aEvent.GetInt() );
|
||||
item = selTool->SelectPoint( data->GetPosition(), SCH_COLLECTOR::MovableItems );
|
||||
|
||||
// Exit if no item found at the current location or the item is already being edited.
|
||||
if( item == NULL || item->GetEditFlags() != 0 )
|
||||
|
@ -526,8 +527,10 @@ void SCH_EDIT_FRAME::DeleteConnection( bool aFullConnection )
|
|||
|
||||
bool SCH_EDIT_FRAME::DeleteItemAtCrossHair()
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
SCH_ITEM* item = LocateItem( GetCrossHairPosition(), SCH_COLLECTOR::ParentItems );
|
||||
|
||||
SCH_ITEM* item = selTool->SelectPoint( GetCrossHairPosition(), SCH_COLLECTOR::ParentItems );
|
||||
|
||||
if( item )
|
||||
{
|
||||
|
@ -693,12 +696,13 @@ void SCH_EDIT_FRAME::PrepareMoveItem( SCH_ITEM* aItem )
|
|||
|
||||
void SCH_EDIT_FRAME::SelectAllFromSheet( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
|
||||
if( item != NULL )
|
||||
{
|
||||
item = LocateAndShowItem( item->GetPosition() );
|
||||
item = selTool->SelectPoint( item->GetPosition() );
|
||||
SendMessageToPCBNEW( item, NULL );
|
||||
}
|
||||
else
|
||||
|
@ -711,7 +715,7 @@ void SCH_EDIT_FRAME::SelectAllFromSheet( wxCommandEvent& aEvent )
|
|||
|
||||
wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
|
||||
|
||||
item = LocateAndShowItem( data->GetPosition() );
|
||||
item = selTool->SelectPoint( data->GetPosition() );
|
||||
SendMessageToPCBNEW( item, NULL );
|
||||
}
|
||||
}
|
||||
|
@ -719,6 +723,7 @@ void SCH_EDIT_FRAME::SelectAllFromSheet( wxCommandEvent& aEvent )
|
|||
|
||||
void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
BLOCK_SELECTOR& block = screen->m_BlockLocate;
|
||||
|
@ -752,8 +757,7 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
|
|||
|
||||
wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
|
||||
|
||||
item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::RotatableItems,
|
||||
aEvent.GetInt() );
|
||||
item = selTool->SelectPoint( data->GetPosition(), SCH_COLLECTOR::RotatableItems );
|
||||
|
||||
// Exit if no item found at the current location or the item is already being edited.
|
||||
if( item == NULL || item->GetEditFlags() != 0 )
|
||||
|
@ -852,6 +856,7 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
|
|||
|
||||
void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
|
||||
|
@ -894,11 +899,11 @@ void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent )
|
|||
break;
|
||||
}
|
||||
|
||||
item = LocateAndShowItem( data->GetPosition(), filterList, aEvent.GetInt() );
|
||||
item = selTool->SelectPoint( data->GetPosition(), filterList );
|
||||
|
||||
// If no item found, and if an auxiliary filter exists, try to use it
|
||||
if( !item && filterListAux )
|
||||
item = LocateAndShowItem( data->GetPosition(), filterListAux, aEvent.GetInt() );
|
||||
item = selTool->SelectPoint( data->GetPosition(), filterListAux );
|
||||
|
||||
// Exit if no item found at the current location or the item is already being edited.
|
||||
if( item == NULL || item->GetEditFlags() != 0 )
|
||||
|
@ -1014,6 +1019,7 @@ void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent )
|
|||
|
||||
void SCH_EDIT_FRAME::OnDragItem( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
|
||||
|
@ -1036,8 +1042,7 @@ void SCH_EDIT_FRAME::OnDragItem( wxCommandEvent& aEvent )
|
|||
|
||||
wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
|
||||
|
||||
item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::DraggableItems,
|
||||
aEvent.GetInt() );
|
||||
item = selTool->SelectPoint( data->GetPosition(), SCH_COLLECTOR::DraggableItems );
|
||||
|
||||
// Exit if no item found at the current location or the item is already being edited.
|
||||
if( item == NULL || item->GetEditFlags() != 0 )
|
||||
|
@ -1086,6 +1091,7 @@ void SCH_EDIT_FRAME::OnDragItem( wxCommandEvent& aEvent )
|
|||
|
||||
void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
SCH_ITEM* item = screen->GetCurItem();
|
||||
BLOCK_SELECTOR& block = screen->m_BlockLocate;
|
||||
|
@ -1149,8 +1155,7 @@ void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
|
|||
|
||||
wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
|
||||
|
||||
item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::OrientableItems,
|
||||
aEvent.GetInt() );
|
||||
item = selTool->SelectPoint( data->GetPosition(), SCH_COLLECTOR::OrientableItems );
|
||||
|
||||
// Exit if no item found at the current location or the item is already being edited.
|
||||
if( item == NULL || item->GetEditFlags() != 0 )
|
||||
|
@ -1231,8 +1236,9 @@ void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
|
|||
|
||||
void SCH_EDIT_FRAME::OnUnfoldBusHotkey( wxCommandEvent& aEvent )
|
||||
{
|
||||
auto data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
|
||||
auto item = GetScreen()->GetCurItem();
|
||||
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
|
||||
EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
|
||||
SCH_ITEM* item = GetScreen()->GetCurItem();
|
||||
|
||||
wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
|
||||
|
||||
|
@ -1242,8 +1248,7 @@ void SCH_EDIT_FRAME::OnUnfoldBusHotkey( wxCommandEvent& aEvent )
|
|||
if( aEvent.GetInt() == 0 )
|
||||
return;
|
||||
|
||||
item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::EditableItems,
|
||||
aEvent.GetInt() );
|
||||
item = selTool->SelectPoint( data->GetPosition(), SCH_COLLECTOR::EditableItems );
|
||||
|
||||
// Exit if no item found at the current location or the item is already being edited.
|
||||
if( item == NULL || item->GetEditFlags() != 0 )
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
#include <tools/sch_editor_control.h>
|
||||
#include <tools/sch_picker_tool.h>
|
||||
#include <tools/sch_drawing_tool.h>
|
||||
|
||||
#include <sch_actions.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
#include <tools/sch_actions.h>
|
||||
#include <tool/zoom_tool.h>
|
||||
|
||||
OPT<TOOL_EVENT> SCH_ACTIONS::TranslateLegacyId( int aId )
|
||||
|
@ -180,6 +180,7 @@ void SCH_ACTIONS::RegisterAllTools( TOOL_MANAGER* aToolManager )
|
|||
{
|
||||
aToolManager->RegisterTool( new COMMON_TOOLS );
|
||||
aToolManager->RegisterTool( new ZOOM_TOOL );
|
||||
aToolManager->RegisterTool( new SCH_SELECTION_TOOL );
|
||||
aToolManager->RegisterTool( new SCH_EDITOR_CONTROL );
|
||||
aToolManager->RegisterTool( new SCH_PICKER_TOOL );
|
||||
aToolManager->RegisterTool( new SCH_DRAWING_TOOL );
|
||||
|
|
|
@ -112,6 +112,10 @@ public:
|
|||
static TOOL_ACTION finishDrawing;
|
||||
|
||||
// Editing
|
||||
static TOOL_ACTION editActivate;
|
||||
static TOOL_ACTION move;
|
||||
static TOOL_ACTION duplicate;
|
||||
static TOOL_ACTION rotate;
|
||||
static TOOL_ACTION properties;
|
||||
static TOOL_ACTION addJunction;
|
||||
static TOOL_ACTION addLabel;
|
||||
|
@ -131,6 +135,7 @@ public:
|
|||
|
||||
// Net highlighting
|
||||
static TOOL_ACTION highlightNet;
|
||||
static TOOL_ACTION clearHighlight;
|
||||
static TOOL_ACTION highlightNetSelection;
|
||||
static TOOL_ACTION highlightNetCursor;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
|
||||
#include "sch_drawing_tool.h"
|
||||
#include "sch_selection_tool.h"
|
||||
#include <sch_actions.h>
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
|
@ -513,6 +514,7 @@ int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
|||
|
||||
int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
|
||||
{
|
||||
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||
VECTOR2I cursorPos = m_controls->GetCursorPosition();
|
||||
SCH_ITEM* item = nullptr;
|
||||
|
||||
|
@ -569,8 +571,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
|
|||
item = m_frame->CreateNewImage();
|
||||
break;
|
||||
case SCH_SHEET_PIN_T:
|
||||
item = m_frame->LocateAndShowItem( (wxPoint)cursorPos,
|
||||
SCH_COLLECTOR::SheetsAndSheetLabels );
|
||||
item = selTool->SelectPoint( cursorPos, SCH_COLLECTOR::SheetsAndSheetLabels );
|
||||
if( item )
|
||||
{
|
||||
if( m_frame->GetToolId() == ID_IMPORT_HLABEL_BUTT )
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "sch_edit_tool.h"
|
||||
#include <sch_actions.h>
|
||||
#include <hotkeys.h>
|
||||
#include <bitmaps.h>
|
||||
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::editActivate( "eeschema.InteractiveEdit",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Edit Activate" ), "", move_xpm, AF_ACTIVATE );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::move( "eeschema.InteractiveEdit.move",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_MOVE_COMPONENT_OR_ITEM ),
|
||||
_( "Move" ), _( "Moves the selected item(s)" ), move_xpm, AF_ACTIVATE );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::duplicate( "eeschema.InteractiveEdit.duplicate",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DUPLICATE_ITEM ),
|
||||
_( "Duplicate" ), _( "Duplicates the selected item(s)" ), duplicate_xpm );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::rotate( "eeschema.InteractiveEdit.rotate",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ROTATE ),
|
||||
_( "Rotate" ), _( "Rotates selected item(s)" ),
|
||||
rotate_ccw_xpm, AF_NONE );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::properties( "eeschema.InteractiveEdit.properties",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT ),
|
||||
_( "Properties..." ), _( "Displays item properties dialog" ), config_xpm );
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef KICAD_SCH_EDIT_TOOL_H
|
||||
#define KICAD_SCH_EDIT_TOOL_H
|
||||
|
||||
#include <tool/tool_interactive.h>
|
||||
|
||||
|
||||
class SCH_EDIT_TOOL : public TOOL_INTERACTIVE
|
||||
{
|
||||
};
|
||||
|
||||
#endif //KICAD_SCH_EDIT_TOOL_H
|
|
@ -34,8 +34,9 @@
|
|||
#include <tool/tool_manager.h>
|
||||
#include <tools/sch_actions.h>
|
||||
#include <tools/sch_picker_tool.h>
|
||||
#include <project.h>
|
||||
#include <tools/sch_editor_control.h>
|
||||
#include <tools/sch_selection_tool.h>
|
||||
#include <project.h>
|
||||
#include <hotkeys.h>
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
@ -45,6 +46,9 @@ TOOL_ACTION SCH_ACTIONS::refreshPreview( "eeschema.EditorControl.refreshPreview"
|
|||
TOOL_ACTION SCH_ACTIONS::highlightNet( "eeschema.EditorControl.highlightNet",
|
||||
AS_GLOBAL, 0, "", "" );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::clearHighlight( "eeschema.EditorControl.clearHighlight",
|
||||
AS_GLOBAL, 0, "", "" );
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::highlightNetSelection( "eeschema.EditorControl.highlightNetSelection",
|
||||
AS_GLOBAL, 0, "", "" );
|
||||
|
||||
|
@ -115,6 +119,59 @@ bool SCH_EDITOR_CONTROL::Init()
|
|||
}
|
||||
|
||||
|
||||
int SCH_EDITOR_CONTROL::CrossProbeSchToPcb( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Don't get in an infinite loop SCH -> PCB -> SCH -> PCB -> SCH -> ...
|
||||
if( m_probingSchToPcb )
|
||||
{
|
||||
m_probingSchToPcb = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool<SCH_SELECTION_TOOL>();
|
||||
const SELECTION& selection = selTool->GetSelection();
|
||||
|
||||
if( selection.Size() == 1 )
|
||||
{
|
||||
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
|
||||
SCH_COMPONENT* component;
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_FIELD_T:
|
||||
case LIB_FIELD_T:
|
||||
component = (SCH_COMPONENT*) item->GetParent();
|
||||
m_frame->SendMessageToPCBNEW( item, component );
|
||||
break;
|
||||
|
||||
case SCH_COMPONENT_T:
|
||||
component = (SCH_COMPONENT*) item;
|
||||
m_frame->SendMessageToPCBNEW( item, component );
|
||||
break;
|
||||
|
||||
case SCH_PIN_T:
|
||||
component = (SCH_COMPONENT*) item->GetParent();
|
||||
m_frame->SendMessageToPCBNEW( static_cast<SCH_PIN*>( item ), component );
|
||||
break;
|
||||
|
||||
#if 0 // This is too slow on larger projects
|
||||
case SCH_SHEET_T:
|
||||
SendMessageToPCBNEW( item, nullptr );
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// A magic cookie token for clearing the highlight
|
||||
static VECTOR2D CLEAR;
|
||||
|
||||
|
||||
// TODO(JE) Probably use netcode rather than connection name here eventually
|
||||
static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
||||
{
|
||||
|
@ -123,7 +180,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
|||
EDA_ITEMS nodeList;
|
||||
bool retVal = true;
|
||||
|
||||
if( editFrame->GetScreen()->GetNode( wxPoint( aPosition.x, aPosition.y ), nodeList ) )
|
||||
if( aPosition != CLEAR && editFrame->GetScreen()->GetNode( (wxPoint) aPosition, nodeList ) )
|
||||
{
|
||||
if( TestDuplicateSheetNames( false ) > 0 )
|
||||
{
|
||||
|
@ -156,7 +213,7 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
|
|||
int SCH_EDITOR_CONTROL::HighlightNet( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||
VECTOR2I gridPosition = controls->GetCursorPosition( true );
|
||||
VECTOR2D gridPosition = controls->GetCursorPosition( true );
|
||||
|
||||
highlightNet( m_toolMgr, gridPosition );
|
||||
|
||||
|
@ -164,6 +221,14 @@ int SCH_EDITOR_CONTROL::HighlightNet( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int SCH_EDITOR_CONTROL::ClearHighlight( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
highlightNet( m_toolMgr, CLEAR );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDITOR_CONTROL::HighlightNetSelection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCH_SCREEN* screen = g_CurrentSheet->LastScreen();
|
||||
|
@ -269,14 +334,15 @@ void SCH_EDITOR_CONTROL::setTransitions()
|
|||
Go( &SCH_EDITOR_CONTROL::UnlockSelected, SCH_ACTIONS::unlock.MakeEvent() );
|
||||
*/
|
||||
|
||||
Go( &SCH_EDITOR_CONTROL::CrossProbeSchToPcb, EVENTS::SelectedEvent );
|
||||
Go( &SCH_EDITOR_CONTROL::CrossProbeSchToPcb, EVENTS::UnselectedEvent );
|
||||
Go( &SCH_EDITOR_CONTROL::CrossProbeSchToPcb, EVENTS::ClearedEvent );
|
||||
/*
|
||||
Go( &SCH_EDITOR_CONTROL::CrossProbeSchToPcb, SELECTION_TOOL::SelectedEvent );
|
||||
Go( &SCH_EDITOR_CONTROL::CrossProbeSchToPcb, SELECTION_TOOL::UnselectedEvent );
|
||||
Go( &SCH_EDITOR_CONTROL::CrossProbeSchToPcb, SELECTION_TOOL::ClearedEvent );
|
||||
Go( &SCH_EDITOR_CONTROL::CrossProbePcbToSch, SCH_ACTIONS::crossProbeSchToPcb.MakeEvent() );
|
||||
*/
|
||||
|
||||
Go( &SCH_EDITOR_CONTROL::HighlightNet, SCH_ACTIONS::highlightNet.MakeEvent() );
|
||||
Go( &SCH_EDITOR_CONTROL::ClearHighlight, SCH_ACTIONS::clearHighlight.MakeEvent() );
|
||||
Go( &SCH_EDITOR_CONTROL::HighlightNetCursor, SCH_ACTIONS::highlightNetCursor.MakeEvent() );
|
||||
Go( &SCH_EDITOR_CONTROL::HighlightNetSelection, SCH_ACTIONS::highlightNetSelection.MakeEvent() );
|
||||
}
|
||||
|
|
|
@ -62,6 +62,9 @@ public:
|
|||
///> Highlights net under the cursor.
|
||||
int HighlightNet( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Removes any net highlighting
|
||||
int ClearHighlight( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Highlights frame's SelectedNetName.
|
||||
int HighlightNetSelection( const TOOL_EVENT& aEvent );
|
||||
|
||||
|
@ -73,8 +76,9 @@ private:
|
|||
///> Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
///> Pointer to the currently used edit frame.
|
||||
SCH_EDIT_FRAME* m_frame;
|
||||
SCH_EDIT_FRAME* m_frame; ///> Pointer to the currently used edit frame
|
||||
|
||||
bool m_probingSchToPcb; ///> Recursion guard when cross-probing to PCBNew
|
||||
|
||||
/// Menu model displayed by the tool.
|
||||
TOOL_MENU m_menu;
|
||||
|
|
|
@ -23,34 +23,706 @@
|
|||
|
||||
|
||||
#include <sch_actions.h>
|
||||
|
||||
#include <core/typeinfo.h>
|
||||
#include <sch_selection_tool.h>
|
||||
#include <sch_base_frame.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_component.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <view/view.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <view/view_group.h>
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <sch_actions.h>
|
||||
#include <sch_collectors.h>
|
||||
#include <painter.h>
|
||||
#include <eeschema_id.h>
|
||||
|
||||
// Selection tool actions
|
||||
TOOL_ACTION SCH_ACTIONS::selectionActivate( "eeschema.InteractiveSelection",
|
||||
AS_GLOBAL, 0,
|
||||
"", "", NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE ); // No description, not shown anywhere
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::selectionCursor( "eeschema.InteractiveSelection.Cursor",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::selectionMenu( "eeschema.InteractiveSelection.SelectionMenu",
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::selectItem( "eeschema.InteractiveSelection.SelectItem",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::selectItems( "eeschema.InteractiveSelection.SelectItems",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::unselectItem( "eeschema.InteractiveSelection.UnselectItem",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::unselectItems( "eeschema.InteractiveSelection.UnselectItems",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION SCH_ACTIONS::selectionClear( "eeschema.InteractiveSelection.Clear",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
|
||||
SCH_SELECTION_TOOL::SCH_SELECTION_TOOL() :
|
||||
TOOL_INTERACTIVE( "eeschema.InteractiveSelection" ),
|
||||
m_frame( NULL ),
|
||||
m_additive( false ),
|
||||
m_subtractive( false ),
|
||||
m_multiple( false ),
|
||||
m_skip_heuristics( false ),
|
||||
m_locked( true ),
|
||||
m_menu( *this )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SCH_SELECTION_TOOL::~SCH_SELECTION_TOOL()
|
||||
{
|
||||
getView()->Remove( &m_selection );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SELECTION_TOOL::Init()
|
||||
{
|
||||
auto frame = getEditFrame<SCH_BASE_FRAME>();
|
||||
|
||||
if( frame )
|
||||
m_menu.AddStandardSubMenus( *frame );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::Reset( RESET_REASON aReason )
|
||||
{
|
||||
m_frame = getEditFrame<SCH_BASE_FRAME>();
|
||||
m_locked = true;
|
||||
|
||||
if( aReason == TOOL_BASE::MODEL_RELOAD )
|
||||
{
|
||||
// Remove pointers to the selected items from containers without changing their
|
||||
// properties (as they are already deleted while a new sheet is loaded)
|
||||
m_selection.Clear();
|
||||
getView()->GetPainter()->GetSettings()->SetHighlight( false );
|
||||
}
|
||||
else
|
||||
// Restore previous properties of selected items and remove them from containers
|
||||
clearSelection();
|
||||
|
||||
// Reinsert the VIEW_GROUP, in case it was removed from the VIEW
|
||||
getView()->Remove( &m_selection );
|
||||
getView()->Add( &m_selection );
|
||||
}
|
||||
|
||||
|
||||
int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Main loop: keep receiving events
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
// Should selected items be added to the current selection or
|
||||
// become the new selection (discarding previously selected items)
|
||||
m_additive = evt->Modifier( MD_SHIFT );
|
||||
|
||||
// Should selected items be REMOVED from the current selection?
|
||||
// This will be ignored if the SHIFT modifier is pressed
|
||||
m_subtractive = !m_additive && evt->Modifier( MD_CTRL );
|
||||
|
||||
// Is the user requesting that the selection list include all possible
|
||||
// items without removing less likely selection candidates
|
||||
m_skip_heuristics = !!evt->Modifier( MD_ALT );
|
||||
|
||||
// Single click? Select single object
|
||||
if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
if( evt->Modifier( MD_CTRL ) && dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
|
||||
{
|
||||
m_toolMgr->RunAction( SCH_ACTIONS::highlightNet, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no modifier keys are pressed, clear the selection
|
||||
if( !m_additive )
|
||||
clearSelection();
|
||||
|
||||
SelectPoint( evt->Position());
|
||||
}
|
||||
}
|
||||
|
||||
// right click? if there is any object - show the context menu
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
bool selectionCancelled = false;
|
||||
|
||||
if( m_selection.Empty() )
|
||||
{
|
||||
SelectPoint( evt->Position(), SCH_COLLECTOR::AllItems, &selectionCancelled );
|
||||
m_selection.SetIsHover( true );
|
||||
}
|
||||
|
||||
if( !selectionCancelled )
|
||||
m_menu.ShowContextMenu( m_selection );
|
||||
}
|
||||
|
||||
// double click? Display the properties window
|
||||
else if( evt->IsDblClick( BUT_LEFT ) )
|
||||
{
|
||||
if( m_selection.Empty() )
|
||||
SelectPoint( evt->Position());
|
||||
|
||||
m_toolMgr->RunAction( SCH_ACTIONS::properties );
|
||||
}
|
||||
|
||||
// drag with LMB? Select multiple objects (or at least draw a selection box) or drag them
|
||||
else if( evt->IsDrag( BUT_LEFT ) )
|
||||
{
|
||||
if( m_additive || m_subtractive || m_selection.Empty() )
|
||||
{
|
||||
// JEY TODO: move block selection to SCH_SELECTION_TOOL
|
||||
//selectMultiple();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Check if dragging has started within any of selected items bounding box
|
||||
if( selectionContains( evt->Position() ) )
|
||||
{
|
||||
// Yes -> run the move tool and wait till it finishes
|
||||
m_toolMgr->InvokeTool( "eeschema.InteractiveEdit" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// No -> clear the selection list
|
||||
clearSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE )
|
||||
{
|
||||
clearSelection();
|
||||
|
||||
if( evt->IsCancel() && dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
|
||||
m_toolMgr->RunAction( SCH_ACTIONS::clearHighlight, true );
|
||||
}
|
||||
|
||||
else if( evt->Action() == TA_CONTEXT_MENU_CLOSED )
|
||||
{
|
||||
m_menu.CloseContextMenu( evt );
|
||||
}
|
||||
}
|
||||
|
||||
// This tool is supposed to be active forever
|
||||
assert( false );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SELECTION& SCH_SELECTION_TOOL::GetSelection()
|
||||
{
|
||||
return m_selection;
|
||||
}
|
||||
|
||||
|
||||
SCH_ITEM* SCH_SELECTION_TOOL::SelectPoint( const VECTOR2I& aWhere, const KICAD_T* aFilterList,
|
||||
bool* aSelectionCancelledFlag, bool aCheckLocked )
|
||||
{
|
||||
SCH_COLLECTOR collector;
|
||||
|
||||
collector.Collect( m_frame->GetScreen()->GetDrawItems(), aFilterList, (wxPoint) aWhere );
|
||||
|
||||
bool anyCollected = collector.GetCount() != 0;
|
||||
|
||||
// Remove unselectable items
|
||||
for( int i = collector.GetCount() - 1; i >= 0; --i )
|
||||
{
|
||||
if( !selectable( collector[ i ] ) )
|
||||
collector.Remove( i );
|
||||
|
||||
if( aCheckLocked && collector[ i ]->IsLocked() )
|
||||
collector.Remove( i );
|
||||
}
|
||||
|
||||
m_selection.ClearReferencePoint();
|
||||
|
||||
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
|
||||
if( collector.GetCount() > 1 && !m_skip_heuristics )
|
||||
{
|
||||
guessSelectionCandidates( collector, aWhere );
|
||||
}
|
||||
|
||||
// If still more than one item we're going to have to ask the user.
|
||||
if( collector.GetCount() > 1 )
|
||||
{
|
||||
if( !doSelectionMenu( &collector, _( "Clarify Selection" ) ) )
|
||||
{
|
||||
if( aSelectionCancelledFlag )
|
||||
*aSelectionCancelledFlag = true;
|
||||
|
||||
m_frame->GetScreen()->SetCurItem( nullptr );
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if( collector.GetCount() == 1 )
|
||||
{
|
||||
SCH_ITEM* item = collector[ 0 ];
|
||||
|
||||
toggleSelection( item );
|
||||
|
||||
MSG_PANEL_ITEMS msgItems;
|
||||
item->GetMsgPanelInfo( m_frame->GetUserUnits(), msgItems );
|
||||
m_frame->SetMsgPanel( msgItems );
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
if( !m_additive && anyCollected )
|
||||
clearSelection();
|
||||
|
||||
m_frame->ClearMsgPanel();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::guessSelectionCandidates( SCH_COLLECTOR& collector,
|
||||
const VECTOR2I& aWhere )
|
||||
{
|
||||
// There are certain parent/child and enclosure combinations that can be handled
|
||||
// automatically. Since schematics are meant to be human-readable we don't have
|
||||
// all the various overlap and coverage issues that we do in Pcbnew.
|
||||
if( collector.GetCount() == 2 )
|
||||
{
|
||||
SCH_ITEM* a = collector[ 0 ];
|
||||
SCH_ITEM* b = collector[ 1 ];
|
||||
|
||||
if( a->GetParent() == b )
|
||||
collector.Remove( b );
|
||||
else if( a == b->GetParent() )
|
||||
collector.Remove( a );
|
||||
else if( a->Type() == SCH_SHEET_T && b->Type() != SCH_SHEET_T )
|
||||
collector.Remove( a );
|
||||
else if( b->Type() == SCH_SHEET_T && a->Type() != SCH_SHEET_T )
|
||||
collector.Remove( b );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SELECTION_TOOL::selectCursor( const KICAD_T aFilterList[], bool aForceSelect )
|
||||
{
|
||||
if( aForceSelect || m_selection.Empty() )
|
||||
{
|
||||
VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
|
||||
|
||||
clearSelection();
|
||||
SelectPoint( cursorPos, aFilterList );
|
||||
}
|
||||
|
||||
return !m_selection.Empty();
|
||||
}
|
||||
|
||||
|
||||
int SCH_SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
std::vector<SCH_ITEM*>* items = aEvent.Parameter<std::vector<SCH_ITEM*>*>();
|
||||
|
||||
if( items )
|
||||
{
|
||||
// Perform individual selection of each item before processing the event.
|
||||
for( auto item : *items )
|
||||
select( item );
|
||||
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Check if there is an item to be selected
|
||||
SCH_ITEM* item = aEvent.Parameter<SCH_ITEM*>();
|
||||
|
||||
if( item )
|
||||
{
|
||||
select( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
std::vector<SCH_ITEM*>* items = aEvent.Parameter<std::vector<SCH_ITEM*>*>();
|
||||
|
||||
if( items )
|
||||
{
|
||||
// Perform individual unselection of each item before processing the event
|
||||
for( auto item : *items )
|
||||
unselect( item );
|
||||
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Check if there is an item to be selected
|
||||
SCH_ITEM* item = aEvent.Parameter<SCH_ITEM*>();
|
||||
|
||||
if( item )
|
||||
{
|
||||
unselect( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
clearSelection();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCH_COLLECTOR* collector = aEvent.Parameter<SCH_COLLECTOR*>();
|
||||
doSelectionMenu( collector, wxEmptyString );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SELECTION_TOOL::doSelectionMenu( SCH_COLLECTOR* aCollector, const wxString& aTitle )
|
||||
{
|
||||
SCH_ITEM* current = nullptr;
|
||||
CONTEXT_MENU menu;
|
||||
|
||||
int limit = std::min( MAX_SELECT_ITEM_IDS, aCollector->GetCount() );
|
||||
|
||||
for( int i = 0; i < limit; ++i )
|
||||
{
|
||||
wxString text;
|
||||
SCH_ITEM* item = ( *aCollector )[i];
|
||||
text = item->GetSelectMenuText( m_frame->GetUserUnits() );
|
||||
|
||||
wxString menuText = wxString::Format("&%d. %s", i + 1, text );
|
||||
menu.Add( menuText, i + 1, item->GetMenuImage() );
|
||||
}
|
||||
|
||||
if( aTitle.Length() )
|
||||
menu.SetTitle( aTitle );
|
||||
|
||||
menu.SetIcon( info_xpm );
|
||||
menu.DisplayTitle( true );
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
if( evt->Action() == TA_CONTEXT_MENU_UPDATE )
|
||||
{
|
||||
if( current )
|
||||
unhighlight( current, BRIGHTENED );
|
||||
|
||||
int id = *evt->GetCommandId();
|
||||
|
||||
// User has pointed an item, so show it in a different way
|
||||
if( id > 0 && id <= limit )
|
||||
{
|
||||
current = ( *aCollector )[id - 1];
|
||||
highlight( current, BRIGHTENED );
|
||||
}
|
||||
else
|
||||
{
|
||||
current = NULL;
|
||||
}
|
||||
}
|
||||
else if( evt->Action() == TA_CONTEXT_MENU_CHOICE )
|
||||
{
|
||||
if( current )
|
||||
unhighlight( current, BRIGHTENED );
|
||||
|
||||
OPT<int> id = evt->GetCommandId();
|
||||
|
||||
// User has selected an item, so this one will be returned
|
||||
if( id && ( *id > 0 ) )
|
||||
current = ( *aCollector )[*id - 1];
|
||||
else
|
||||
current = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( current )
|
||||
{
|
||||
unhighlight( current, BRIGHTENED );
|
||||
|
||||
toggleSelection( current );
|
||||
|
||||
aCollector->Empty();
|
||||
aCollector->Append( current );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SELECTION_TOOL::selectable( const SCH_ITEM* aItem, bool checkVisibilityOnly ) const
|
||||
{
|
||||
// NOTE: in the future this is where eeschema layer/itemtype visibility will be handled
|
||||
|
||||
switch( aItem->Type() )
|
||||
{
|
||||
case SCH_PIN_T:
|
||||
if( !static_cast<const SCH_PIN*>( aItem )->IsVisible() && !m_frame->GetShowAllPins() )
|
||||
return false;
|
||||
break;
|
||||
|
||||
case LIB_PART_T: // In libedit we do not want to select the symbol itself.
|
||||
return false;
|
||||
|
||||
case SCH_MARKER_T: // Always selectable
|
||||
return true;
|
||||
|
||||
default: // Suppress warnings
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::clearSelection()
|
||||
{
|
||||
if( m_selection.Empty() )
|
||||
return;
|
||||
|
||||
while( m_selection.GetSize() )
|
||||
unhighlight( static_cast<SCH_ITEM*>( m_selection.Front() ), SELECTED, &m_selection );
|
||||
|
||||
getView()->Update( &m_selection );
|
||||
|
||||
m_selection.SetIsHover( false );
|
||||
m_selection.ClearReferencePoint();
|
||||
|
||||
if( m_frame )
|
||||
m_frame->GetScreen()->SetCurItem( nullptr );
|
||||
|
||||
m_locked = true;
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( EVENTS::ClearedEvent );
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::toggleSelection( SCH_ITEM* aItem, bool aForce )
|
||||
{
|
||||
if( aItem->IsSelected() )
|
||||
{
|
||||
unselect( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !m_additive )
|
||||
clearSelection();
|
||||
|
||||
// Prevent selection of invisible or inactive items
|
||||
if( aForce || selectable( aItem ) )
|
||||
{
|
||||
select( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_frame )
|
||||
m_frame->GetGalCanvas()->ForceRefresh();
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::select( SCH_ITEM* aItem )
|
||||
{
|
||||
if( aItem->IsSelected() )
|
||||
return;
|
||||
|
||||
highlight( aItem, SELECTED, &m_selection );
|
||||
getView()->Update( &m_selection );
|
||||
|
||||
if( m_frame )
|
||||
{
|
||||
if( m_selection.Size() == 1 )
|
||||
{
|
||||
// Set as the current item, so the information about selection is displayed
|
||||
m_frame->GetScreen()->SetCurItem( aItem );
|
||||
}
|
||||
else if( m_selection.Size() == 2 ) // Check only for 2, so it will not be
|
||||
{ // called for every next selected item
|
||||
// If multiple items are selected, do not show the information about the selected item
|
||||
m_frame->GetScreen()->SetCurItem( nullptr );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::unselect( SCH_ITEM* aItem )
|
||||
{
|
||||
unhighlight( aItem, SELECTED, &m_selection );
|
||||
getView()->Update( &m_selection );
|
||||
|
||||
if( m_frame && m_frame->GetScreen()->GetCurItem() == aItem )
|
||||
m_frame->GetScreen()->SetCurItem( nullptr );
|
||||
|
||||
if( m_selection.Empty() )
|
||||
m_locked = true;
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::highlight( SCH_ITEM* aItem, int aMode, SELECTION* aGroup )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
aItem->SetSelected();
|
||||
else if( aMode == BRIGHTENED )
|
||||
aItem->SetBrightened();
|
||||
|
||||
if( aGroup )
|
||||
aGroup->Add( aItem );
|
||||
|
||||
// Highlight pins and fields. (All the other component children are currently only
|
||||
// represented in the LIB_PART.)
|
||||
if( aItem->Type() == SCH_COMPONENT_T )
|
||||
{
|
||||
SCH_PINS pins = static_cast<SCH_COMPONENT*>( aItem )->GetPins();
|
||||
|
||||
for( SCH_PIN& pin : pins )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
pin.SetSelected();
|
||||
else if( aMode == BRIGHTENED )
|
||||
pin.SetBrightened();
|
||||
}
|
||||
|
||||
std::vector<SCH_FIELD*> fields;
|
||||
static_cast<SCH_COMPONENT*>( aItem )->GetFields( fields, false );
|
||||
|
||||
for( auto field : fields )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
field->SetSelected();
|
||||
else if( aMode == BRIGHTENED )
|
||||
field->SetBrightened();
|
||||
|
||||
// JEY TODO: do these need hiding from view and adding to aGroup?
|
||||
}
|
||||
}
|
||||
|
||||
// JEY TODO: Sheets and sheet pins?
|
||||
|
||||
// Many selections are very temporal and updating the display each time just
|
||||
// creates noise.
|
||||
if( aMode == BRIGHTENED )
|
||||
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::unhighlight( SCH_ITEM* aItem, int aMode, SELECTION* aGroup )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
aItem->ClearSelected();
|
||||
else if( aMode == BRIGHTENED )
|
||||
aItem->ClearBrightened();
|
||||
|
||||
if( aGroup )
|
||||
aGroup->Remove( aItem );
|
||||
|
||||
// Unhighlight pins and fields. (All the other component children are currently only
|
||||
// represented in the LIB_PART.)
|
||||
if( aItem->Type() == SCH_COMPONENT_T )
|
||||
{
|
||||
SCH_PINS pins = static_cast<SCH_COMPONENT*>( aItem )->GetPins();
|
||||
|
||||
for( SCH_PIN& pin : pins )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
pin.ClearSelected();
|
||||
else if( aMode == BRIGHTENED )
|
||||
pin.ClearBrightened();
|
||||
}
|
||||
|
||||
std::vector<SCH_FIELD*> fields;
|
||||
static_cast<SCH_COMPONENT*>( aItem )->GetFields( fields, false );
|
||||
|
||||
for( auto field : fields )
|
||||
{
|
||||
if( aMode == SELECTED )
|
||||
field->ClearSelected();
|
||||
else if( aMode == BRIGHTENED )
|
||||
field->ClearBrightened();
|
||||
|
||||
// JEY TODO: do these need showing and updating?
|
||||
}
|
||||
}
|
||||
|
||||
// JEY TODO: Sheets and sheet pins?
|
||||
|
||||
// Many selections are very temporal and updating the display each time just
|
||||
// creates noise.
|
||||
if( aMode == BRIGHTENED )
|
||||
getView()->MarkTargetDirty( KIGFX::TARGET_OVERLAY );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
|
||||
{
|
||||
const unsigned GRIP_MARGIN = 20;
|
||||
VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
|
||||
|
||||
// Check if the point is located within any of the currently selected items bounding boxes
|
||||
for( auto item : m_selection )
|
||||
{
|
||||
BOX2I itemBox = item->ViewBBox();
|
||||
itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
|
||||
|
||||
if( itemBox.Contains( aPoint ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SCH_SELECTION_TOOL::setTransitions()
|
||||
{
|
||||
Go( &SCH_SELECTION_TOOL::Main, SCH_ACTIONS::selectionActivate.MakeEvent() );
|
||||
Go( &SCH_SELECTION_TOOL::ClearSelection, SCH_ACTIONS::selectionClear.MakeEvent() );
|
||||
Go( &SCH_SELECTION_TOOL::SelectItem, SCH_ACTIONS::selectItem.MakeEvent() );
|
||||
Go( &SCH_SELECTION_TOOL::SelectItems, SCH_ACTIONS::selectItems.MakeEvent() );
|
||||
Go( &SCH_SELECTION_TOOL::UnselectItem, SCH_ACTIONS::unselectItem.MakeEvent() );
|
||||
Go( &SCH_SELECTION_TOOL::UnselectItems, SCH_ACTIONS::unselectItems.MakeEvent() );
|
||||
Go( &SCH_SELECTION_TOOL::SelectionMenu, SCH_ACTIONS::selectionMenu.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef KICAD_SCH_SELECTION_TOOL_H
|
||||
#define KICAD_SCH_SELECTION_TOOL_H
|
||||
|
||||
#include <tool/tool_interactive.h>
|
||||
#include <tool/context_menu.h>
|
||||
#include <tool/selection.h>
|
||||
#include <tool/tool_menu.h>
|
||||
#include <sch_collectors.h>
|
||||
|
||||
class SCH_BASE_FRAME;
|
||||
class SCH_ITEM;
|
||||
class SCH_COLLECTOR;
|
||||
|
||||
namespace KIGFX
|
||||
{
|
||||
class GAL;
|
||||
}
|
||||
|
||||
|
||||
class SCH_SELECTION_TOOL : public TOOL_INTERACTIVE
|
||||
{
|
||||
public:
|
||||
SCH_SELECTION_TOOL();
|
||||
~SCH_SELECTION_TOOL();
|
||||
|
||||
/// @copydoc TOOL_BASE::Init()
|
||||
bool Init() override;
|
||||
|
||||
/// @copydoc TOOL_BASE::Reset()
|
||||
void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
/**
|
||||
* Function Main()
|
||||
*
|
||||
* The main loop.
|
||||
*/
|
||||
int Main( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function GetSelection()
|
||||
*
|
||||
* Returns the set of currently selected items.
|
||||
*/
|
||||
SELECTION& GetSelection();
|
||||
|
||||
/**
|
||||
* Function selectPoint()
|
||||
* Selects an item pointed by the parameter aWhere. If there is more than one item at that
|
||||
* place, there is a menu displayed that allows one to choose the item.
|
||||
*
|
||||
* @param aWhere is the place where the item should be selected.
|
||||
* @param aSelectionCancelledFlag allows the function to inform its caller that a selection
|
||||
* was cancelled (for instance, by clicking outside of the disambiguation menu).
|
||||
* @param aCheckLocked indicates if locked items should be excluded
|
||||
*/
|
||||
SCH_ITEM* SelectPoint( const VECTOR2I& aWhere,
|
||||
const KICAD_T* aFilterList = SCH_COLLECTOR::AllItems,
|
||||
bool* aSelectionCancelledFlag = NULL, bool aCheckLocked = false );
|
||||
|
||||
///> Item selection event handler.
|
||||
int SelectItem( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Multiple item selection event handler
|
||||
int SelectItems( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Item unselection event handler.
|
||||
int UnselectItem( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Multiple item unselection event handler
|
||||
int UnselectItems( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Clear current selection event handler.
|
||||
int ClearSelection( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function SelectionMenu()
|
||||
* Allows the selection of a single item from a list of items via a popup menu. The
|
||||
* list is passed as aEvent's parameter.
|
||||
*/
|
||||
int SelectionMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
private:
|
||||
/**
|
||||
* Function selectCursor()
|
||||
* Selects an item under the cursor unless there is something already selected or aForceSelect
|
||||
* is true.
|
||||
* @param aForceSelect forces to select an item even if there is an item already selected.
|
||||
* @param aClientFilter allows the client to perform tool- or action-specific filtering.
|
||||
* @return true if eventually there is an item selected, false otherwise.
|
||||
*/
|
||||
bool selectCursor( const KICAD_T aFilterList[], bool aForceSelect = false );
|
||||
|
||||
/**
|
||||
* Apply heuristics to try and determine a single object when multiple are found under the
|
||||
* cursor.
|
||||
*/
|
||||
void guessSelectionCandidates( SCH_COLLECTOR& collector, const VECTOR2I& aWhere );
|
||||
|
||||
/**
|
||||
* Allows the selection of a single item from a list via pop-up menu. The items are
|
||||
* highlighted on the canvas when hovered in the menu. The collector is trimmed to
|
||||
* the picked item.
|
||||
* @param aTitle (optional) Allows the menu to be titled (ie: "Clarify Selection").
|
||||
* @return true if an item was picked
|
||||
*/
|
||||
bool doSelectionMenu( SCH_COLLECTOR* aItems, const wxString& aTitle );
|
||||
|
||||
/**
|
||||
* Function clearSelection()
|
||||
* Clears the current selection.
|
||||
*/
|
||||
void clearSelection();
|
||||
|
||||
/**
|
||||
* Function toggleSelection()
|
||||
* Changes selection status of a given item.
|
||||
*
|
||||
* @param aItem is the item to have selection status changed.
|
||||
* @param aForce causes the toggle to happen without checking selectability
|
||||
*/
|
||||
void toggleSelection( SCH_ITEM* aItem, bool aForce = false );
|
||||
|
||||
/**
|
||||
* Function selectable()
|
||||
* Checks conditions for an item to be selected.
|
||||
*
|
||||
* @return True if the item fulfills conditions to be selected.
|
||||
*/
|
||||
bool selectable( const SCH_ITEM* aItem, bool checkVisibilityOnly = false ) const;
|
||||
|
||||
/**
|
||||
* Function select()
|
||||
* Takes necessary action mark an item as selected.
|
||||
*
|
||||
* @param aItem is an item to be selected.
|
||||
*/
|
||||
void select( SCH_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Function unselect()
|
||||
* Takes necessary action mark an item as unselected.
|
||||
*
|
||||
* @param aItem is an item to be unselected.
|
||||
*/
|
||||
void unselect( SCH_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Function highlight()
|
||||
* Highlights the item visually.
|
||||
* @param aItem is an item to be be highlighted.
|
||||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to add the item to in the BRIGHTENED mode.
|
||||
*/
|
||||
void highlight( SCH_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr );
|
||||
|
||||
/**
|
||||
* Function unhighlight()
|
||||
* Unhighlights the item visually.
|
||||
* @param aItem is an item to be be highlighted.
|
||||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
* @param aGroup is the group to remove the item from.
|
||||
*/
|
||||
void unhighlight( SCH_ITEM* aItem, int aHighlightMode, SELECTION* aGroup = nullptr );
|
||||
|
||||
/**
|
||||
* Function selectionContains()
|
||||
* Checks if the given point is placed within any of selected items' bounding box.
|
||||
*
|
||||
* @return True if the given point is contained in any of selected items' bouding box.
|
||||
*/
|
||||
bool selectionContains( const VECTOR2I& aPoint ) const;
|
||||
|
||||
///> Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
private:
|
||||
SCH_BASE_FRAME* m_frame; // Pointer to the parent frame
|
||||
SELECTION m_selection; // Current state of selection
|
||||
|
||||
bool m_additive; // Items should be added to selection (instead of replacing)
|
||||
bool m_subtractive; // Items should be removed from selection
|
||||
bool m_multiple; // Multiple selection mode is active
|
||||
bool m_skip_heuristics; // Heuristics are not allowed when choosing item under cursor
|
||||
bool m_locked; // Other tools are not allowed to modify locked items
|
||||
|
||||
TOOL_MENU m_menu;
|
||||
};
|
||||
|
||||
#endif //KICAD_SCH_SELECTION_TOOL_H
|
|
@ -92,7 +92,7 @@ public:
|
|||
* @param ndx The index into the list.
|
||||
* @return EDA_ITEM* - or something derived from it, or NULL.
|
||||
*/
|
||||
EDA_ITEM* operator[]( int ndx ) const
|
||||
EDA_ITEM* operator[]( int ndx ) const override
|
||||
{
|
||||
if( (unsigned)ndx < (unsigned)GetCount() )
|
||||
return (EDA_ITEM*) m_List[ ndx ];
|
||||
|
|
|
@ -267,7 +267,7 @@ void GERBVIEW_SELECTION_TOOL::toggleSelection( EDA_ITEM* aItem )
|
|||
unselect( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -280,7 +280,7 @@ void GERBVIEW_SELECTION_TOOL::toggleSelection( EDA_ITEM* aItem )
|
|||
select( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,7 +455,7 @@ bool GERBVIEW_SELECTION_TOOL::selectMultiple()
|
|||
|
||||
// Inform other potentially interested tools
|
||||
if( !m_selection.Empty() )
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
|
||||
break; // Stop waiting for events
|
||||
}
|
||||
|
@ -516,7 +516,7 @@ int GERBVIEW_SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent )
|
|||
select( item );
|
||||
}
|
||||
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -533,7 +533,7 @@ int GERBVIEW_SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
|
|||
select( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -553,7 +553,7 @@ int GERBVIEW_SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent )
|
|||
unselect( item );
|
||||
}
|
||||
|
||||
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -570,7 +570,7 @@ int GERBVIEW_SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
|
|||
unselect( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -590,7 +590,7 @@ void GERBVIEW_SELECTION_TOOL::clearSelection()
|
|||
m_frame->SetCurItem( NULL );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( ClearedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::ClearedEvent );
|
||||
}
|
||||
|
||||
|
||||
|
@ -950,9 +950,3 @@ const KIGFX::VIEW_GROUP::ITEMS SELECTION::updateDrawList() const
|
|||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const TOOL_EVENT GERBVIEW_SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.selected" );
|
||||
const TOOL_EVENT GERBVIEW_SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.unselected" );
|
||||
const TOOL_EVENT GERBVIEW_SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "gerbview.InteractiveSelection.cleared" );
|
||||
|
|
|
@ -98,15 +98,6 @@ public:
|
|||
///> Launches a tool to measure between points
|
||||
int MeasureTool( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Event sent after an item is selected.
|
||||
static const TOOL_EVENT SelectedEvent;
|
||||
|
||||
///> Event sent after an item is unselected.
|
||||
static const TOOL_EVENT UnselectedEvent;
|
||||
|
||||
///> Event sent after selection is cleared.
|
||||
static const TOOL_EVENT ClearedEvent;
|
||||
|
||||
///> Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ public:
|
|||
* @param aIndex The index into the list.
|
||||
* @return EDA_ITEM* - or something derived from it, or NULL.
|
||||
*/
|
||||
EDA_ITEM* operator[]( int aIndex ) const
|
||||
virtual EDA_ITEM* operator[]( int aIndex ) const
|
||||
{
|
||||
if( (unsigned)aIndex < (unsigned)GetCount() ) // (unsigned) excludes aIndex<0 also
|
||||
return m_List[ aIndex ];
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2016 CERN
|
||||
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -108,4 +108,20 @@ public:
|
|||
enum class REMOVE_FLAGS { NORMAL = 0x00, ALT = 0x01, CUT = 0x02 };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Class EVENTS
|
||||
*
|
||||
* Gathers all the events that are shared by tools.
|
||||
*/
|
||||
class EVENTS
|
||||
{
|
||||
public:
|
||||
const static TOOL_EVENT SelectedEvent;
|
||||
const static TOOL_EVENT UnselectedEvent;
|
||||
const static TOOL_EVENT ClearedEvent;
|
||||
};
|
||||
|
||||
#endif // __ACTIONS_H
|
||||
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ public:
|
|||
return (BOARD_ITEM*) &myItems[aIndex];
|
||||
}
|
||||
|
||||
BOARD_ITEM* operator[]( int aIndex ) const
|
||||
BOARD_ITEM* operator[]( int aIndex ) const override
|
||||
{
|
||||
return At( aIndex );
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2004-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -22,10 +22,6 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file collectors.h
|
||||
*/
|
||||
|
||||
#ifndef COLLECTORS_H
|
||||
#define COLLECTORS_H
|
||||
|
||||
|
@ -38,10 +34,9 @@
|
|||
#include <collector.h>
|
||||
#include <layers_id_colors_and_visibility.h> // LAYER_COUNT, layer defs
|
||||
#include <view/view.h>
|
||||
#include <class_board_item.h>
|
||||
|
||||
|
||||
class BOARD_ITEM;
|
||||
|
||||
|
||||
/**
|
||||
* An abstract base class whose derivatives may be passed to a GENERAL_COLLECTOR,
|
||||
|
@ -223,7 +218,7 @@ public:
|
|||
* @param ndx The index into the list.
|
||||
* @return BOARD_ITEM* - or something derived from it, or NULL.
|
||||
*/
|
||||
BOARD_ITEM* operator[]( int ndx ) const
|
||||
BOARD_ITEM* operator[]( int ndx ) const override
|
||||
{
|
||||
if( (unsigned)ndx < (unsigned)GetCount() )
|
||||
return (BOARD_ITEM*) m_List[ ndx ];
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
#include <cstdint>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include <functional>
|
||||
#include "pcb_editor_control.h"
|
||||
#include "pcb_actions.h"
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/tool_event_utils.h>
|
||||
#include <wx/progdlg.h>
|
||||
|
||||
#include "edit_tool.h"
|
||||
|
@ -57,12 +58,8 @@
|
|||
#include <view/view_controls.h>
|
||||
#include <origin_viewitem.h>
|
||||
#include <profile.h>
|
||||
|
||||
#include <widgets/progress_reporter.h>
|
||||
|
||||
#include <tools/tool_event_utils.h>
|
||||
|
||||
#include <functional>
|
||||
using namespace std::placeholders;
|
||||
|
||||
|
||||
|
@ -836,6 +833,7 @@ int PCB_EDITOR_CONTROL::ZoneDuplicate( const TOOL_EVENT& aEvent )
|
|||
|
||||
int PCB_EDITOR_CONTROL::CrossProbePcbToSch( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// Don't get in an infinite loop PCB -> SCH -> PCB -> SCH -> ...
|
||||
if( m_probingSchToPcb )
|
||||
{
|
||||
m_probingSchToPcb = false;
|
||||
|
@ -1287,9 +1285,9 @@ void PCB_EDITOR_CONTROL::setTransitions()
|
|||
Go( &PCB_EDITOR_CONTROL::ToggleLockSelected, PCB_ACTIONS::toggleLock.MakeEvent() );
|
||||
Go( &PCB_EDITOR_CONTROL::LockSelected, PCB_ACTIONS::lock.MakeEvent() );
|
||||
Go( &PCB_EDITOR_CONTROL::UnlockSelected, PCB_ACTIONS::unlock.MakeEvent() );
|
||||
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, SELECTION_TOOL::SelectedEvent );
|
||||
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, SELECTION_TOOL::UnselectedEvent );
|
||||
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, SELECTION_TOOL::ClearedEvent );
|
||||
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::SelectedEvent );
|
||||
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::UnselectedEvent );
|
||||
Go( &PCB_EDITOR_CONTROL::CrossProbePcbToSch, EVENTS::ClearedEvent );
|
||||
Go( &PCB_EDITOR_CONTROL::CrossProbeSchToPcb, PCB_ACTIONS::crossProbeSchToPcb.MakeEvent() );
|
||||
Go( &PCB_EDITOR_CONTROL::DrillOrigin, PCB_ACTIONS::drillOrigin.MakeEvent() );
|
||||
Go( &PCB_EDITOR_CONTROL::HighlightNet, PCB_ACTIONS::highlightNet.MakeEvent() );
|
||||
|
|
|
@ -135,17 +135,11 @@ private:
|
|||
/// Menu model displayed by the tool.
|
||||
TOOL_MENU m_menu;
|
||||
|
||||
///> Place & drill origin marker.
|
||||
std::unique_ptr<KIGFX::ORIGIN_VIEWITEM> m_placeOrigin;
|
||||
std::unique_ptr<KIGFX::ORIGIN_VIEWITEM> m_placeOrigin; ///> Place & drill origin marker
|
||||
|
||||
///> Flag to ignore a single crossprobe message from eeschema.
|
||||
bool m_probingSchToPcb;
|
||||
|
||||
///> Flag to indicate whether the current selection ratsnest is slow to calculate.
|
||||
bool m_slowRatsnest;
|
||||
|
||||
///> Timer that start ratsnest calculation when it is slow to compute.
|
||||
wxTimer m_ratsnestTimer;
|
||||
bool m_probingSchToPcb; ///> Recursion guard when cross-probing to EESchema
|
||||
bool m_slowRatsnest; ///> Indicates current selection ratsnest will be slow to calculate
|
||||
wxTimer m_ratsnestTimer; ///> Timer to initiate lazy ratsnest calculation (ie: when slow)
|
||||
|
||||
///> How to modify a property for selected items.
|
||||
enum MODIFY_MODE { ON, OFF, TOGGLE };
|
||||
|
|
|
@ -899,7 +899,7 @@ int PCBNEW_CONTROL::placeBoardItems( std::vector<BOARD_ITEM*>& aItems, bool aIsN
|
|||
|
||||
selection.SetReferencePoint( VECTOR2I( 0, 0 ) );
|
||||
|
||||
m_toolMgr->ProcessEvent( SELECTION_TOOL::SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::move, true );
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -345,9 +345,9 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
|||
controls->SetSnapping( !evt->Modifier( MD_ALT ) );
|
||||
|
||||
if( !m_editPoints ||
|
||||
evt->Matches( m_selectionTool->ClearedEvent ) ||
|
||||
evt->Matches( m_selectionTool->UnselectedEvent ) ||
|
||||
evt->Matches( m_selectionTool->SelectedEvent ) )
|
||||
evt->Matches( EVENTS::ClearedEvent ) ||
|
||||
evt->Matches( EVENTS::UnselectedEvent ) ||
|
||||
evt->Matches( EVENTS::SelectedEvent ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -905,8 +905,8 @@ void POINT_EDITOR::setTransitions()
|
|||
Go( &POINT_EDITOR::addCorner, PCB_ACTIONS::pointEditorAddCorner.MakeEvent() );
|
||||
Go( &POINT_EDITOR::removeCorner, PCB_ACTIONS::pointEditorRemoveCorner.MakeEvent() );
|
||||
Go( &POINT_EDITOR::modifiedSelection, PCB_ACTIONS::selectionModified.MakeEvent() );
|
||||
Go( &POINT_EDITOR::OnSelectionChange, SELECTION_TOOL::SelectedEvent );
|
||||
Go( &POINT_EDITOR::OnSelectionChange, SELECTION_TOOL::UnselectedEvent );
|
||||
Go( &POINT_EDITOR::OnSelectionChange, EVENTS::SelectedEvent );
|
||||
Go( &POINT_EDITOR::OnSelectionChange, EVENTS::UnselectedEvent );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,44 +65,40 @@ using namespace std::placeholders;
|
|||
|
||||
// Selection tool actions
|
||||
TOOL_ACTION PCB_ACTIONS::selectionActivate( "pcbnew.InteractiveSelection",
|
||||
AS_GLOBAL, 0,
|
||||
"", "", NULL, AF_ACTIVATE ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE ); // No description, not shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectionCursor( "pcbnew.InteractiveSelection.Cursor",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectItem( "pcbnew.InteractiveSelection.SelectItem",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectItems( "pcbnew.InteractiveSelection.SelectItems",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::unselectItem( "pcbnew.InteractiveSelection.UnselectItem",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::unselectItems( "pcbnew.InteractiveSelection.UnselectItems",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectionClear( "pcbnew.InteractiveSelection.Clear",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectionMenu( "pcbnew.InteractiveSelection.SelectionMenu",
|
||||
AS_GLOBAL, 0,
|
||||
"", "" ); // No description, it is not supposed to be shown anywhere
|
||||
AS_GLOBAL, 0, "", "" ); // No description, it is not supposed to be shown anywhere
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectConnection( "pcbnew.InteractiveSelection.SelectConnection",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SEL_TRIVIAL_CONNECTION ),
|
||||
_( "Single Track" ), _( "Selects all track segments & vias between two junctions." ), add_tracks_xpm );
|
||||
_( "Single Track" ),
|
||||
_( "Selects all track segments & vias between two junctions." ),
|
||||
add_tracks_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectCopper( "pcbnew.InteractiveSelection.SelectCopper",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_SEL_COPPER_CONNECTION ),
|
||||
_( "Connected Tracks" ), _( "Selects all connected tracks & vias." ), net_highlight_xpm );
|
||||
_( "Connected Tracks" ),
|
||||
_( "Selects all connected tracks & vias." ),
|
||||
net_highlight_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::expandSelectedConnection( "pcbnew.InteractiveSelection.ExpandConnection",
|
||||
AS_GLOBAL, 0,
|
||||
|
@ -111,20 +107,27 @@ TOOL_ACTION PCB_ACTIONS::expandSelectedConnection( "pcbnew.InteractiveSelection.
|
|||
|
||||
TOOL_ACTION PCB_ACTIONS::selectNet( "pcbnew.InteractiveSelection.SelectNet",
|
||||
AS_GLOBAL, 0,
|
||||
_( "All Tracks in Net" ), _( "Selects all tracks & vias belonging to the same net." ), mode_track_xpm );
|
||||
_( "All Tracks in Net" ),
|
||||
_( "Selects all tracks & vias belonging to the same net." ),
|
||||
mode_track_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectOnSheetFromEeschema( "pcbnew.InteractiveSelection.SelectOnSheet",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Sheet" ), _( "Selects all modules and tracks in the schematic sheet" ), select_same_sheet_xpm );
|
||||
_( "Sheet" ),
|
||||
_( "Selects all modules and tracks in the schematic sheet" ),
|
||||
select_same_sheet_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::selectSameSheet( "pcbnew.InteractiveSelection.SelectSameSheet",
|
||||
AS_GLOBAL, 0,
|
||||
_( "Items in Same Hierarchical Sheet" ),
|
||||
_( "Selects all modules and tracks in the same schematic sheet" ), select_same_sheet_xpm );
|
||||
_( "Selects all modules and tracks in the same schematic sheet" ),
|
||||
select_same_sheet_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::find( "pcbnew.InteractiveSelection.Find",
|
||||
AS_GLOBAL, 0, //TOOL_ACTION::LegacyHotKey( HK_FIND_ITEM ), // handled by wxWidgets
|
||||
_( "Find Item..." ),_( "Searches the document for an item" ), find_xpm );
|
||||
_( "Find Item..." ),
|
||||
_( "Searches the document for an item" ),
|
||||
find_xpm );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::findMove( "pcbnew.InteractiveSelection.FindMove",
|
||||
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_GET_AND_MOVE_FOOTPRINT ),
|
||||
|
@ -466,7 +469,7 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem, bool aForce )
|
|||
unselect( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -479,7 +482,7 @@ void SELECTION_TOOL::toggleSelection( BOARD_ITEM* aItem, bool aForce )
|
|||
select( aItem );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -542,60 +545,47 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
|
|||
if( aClientFilter )
|
||||
aClientFilter( aWhere, collector );
|
||||
|
||||
if( collector.GetCount() == 0 )
|
||||
{
|
||||
if( !m_additive && anyCollected )
|
||||
{
|
||||
clearSelection();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if( collector.GetCount() == 1 )
|
||||
{
|
||||
toggleSelection( collector[0] );
|
||||
return true;
|
||||
}
|
||||
|
||||
// Apply some ugly heuristics to avoid disambiguation menus whenever possible
|
||||
if( !m_skip_heuristics )
|
||||
if( collector.GetCount() > 1 && !m_skip_heuristics )
|
||||
{
|
||||
guessSelectionCandidates( collector, aWhere );
|
||||
}
|
||||
|
||||
if( collector.GetCount() == 1 )
|
||||
// If still more than one item we're going to have to ask the user.
|
||||
if( collector.GetCount() > 1 )
|
||||
{
|
||||
toggleSelection( collector[0] );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Still more than one item. We're going to have to ask the user.
|
||||
if( aOnDrag )
|
||||
{
|
||||
Wait( TOOL_EVENT( TC_ANY, TA_MOUSE_UP, BUT_LEFT ) );
|
||||
}
|
||||
|
||||
BOARD_ITEM* item = doSelectionMenu( &collector, _( "Clarify Selection" ) );
|
||||
|
||||
if( item )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if( !doSelectionMenu( &collector, _( "Clarify Selection" ) ) )
|
||||
{
|
||||
if( aSelectionCancelledFlag )
|
||||
*aSelectionCancelledFlag = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( collector.GetCount() == 1 )
|
||||
{
|
||||
BOARD_ITEM* item = collector[ 0 ];
|
||||
|
||||
toggleSelection( item );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( !m_additive && anyCollected )
|
||||
clearSelection();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool SELECTION_TOOL::selectCursor( bool aSelectAlways, CLIENT_SELECTION_FILTER aClientFilter )
|
||||
bool SELECTION_TOOL::selectCursor( bool aForceSelect, CLIENT_SELECTION_FILTER aClientFilter )
|
||||
{
|
||||
if( aSelectAlways || m_selection.Empty() )
|
||||
if( aForceSelect || m_selection.Empty() )
|
||||
{
|
||||
clearSelection();
|
||||
selectPoint( getViewControls()->GetCursorPosition( false ), false, NULL, aClientFilter );
|
||||
|
@ -710,7 +700,7 @@ bool SELECTION_TOOL::selectMultiple()
|
|||
|
||||
// Inform other potentially interested tools
|
||||
if( !m_selection.Empty() )
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
|
||||
break; // Stop waiting for events
|
||||
}
|
||||
|
@ -819,14 +809,11 @@ int SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( items )
|
||||
{
|
||||
// Perform individual selection of each item
|
||||
// before processing the event.
|
||||
// Perform individual selection of each item before processing the event.
|
||||
for( auto item : *items )
|
||||
{
|
||||
select( item );
|
||||
}
|
||||
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -843,7 +830,7 @@ int SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
|
|||
select( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -856,14 +843,11 @@ int SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( items )
|
||||
{
|
||||
// Perform individual unselection of each item
|
||||
// before processing the event
|
||||
// Perform individual unselection of each item before processing the event
|
||||
for( auto item : *items )
|
||||
{
|
||||
unselect( item );
|
||||
}
|
||||
|
||||
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -880,7 +864,7 @@ int SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
|
|||
unselect( item );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( UnselectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -935,7 +919,7 @@ int SELECTION_TOOL::expandSelectedConnection( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Inform other potentially interested tools
|
||||
if( m_selection.Size() > 0 )
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -987,7 +971,7 @@ int SELECTION_TOOL::selectCopper( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Inform other potentially interested tools
|
||||
if( m_selection.Size() > 0 )
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1056,7 +1040,7 @@ int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Inform other potentially interested tools
|
||||
if( m_selection.Size() > 0 )
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1201,7 +1185,7 @@ int SELECTION_TOOL::selectOnSheetFromEeschema( const TOOL_EVENT& aEvent )
|
|||
zoomFitSelection();
|
||||
|
||||
if( m_selection.Size() > 0 )
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1235,7 +1219,7 @@ int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Inform other potentially interested tools
|
||||
if( m_selection.Size() > 0 )
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1251,7 +1235,7 @@ void SELECTION_TOOL::findCallback( BOARD_ITEM* aItem )
|
|||
getView()->SetCenter( aItem->GetPosition() );
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( SelectedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
m_frame->GetGalCanvas()->ForceRefresh();
|
||||
|
@ -1430,14 +1414,12 @@ void SELECTION_TOOL::clearSelection()
|
|||
m_selection.ClearReferencePoint();
|
||||
|
||||
if( m_frame )
|
||||
{
|
||||
m_frame->SetCurItem( NULL );
|
||||
}
|
||||
|
||||
m_locked = true;
|
||||
|
||||
// Inform other potentially interested tools
|
||||
m_toolMgr->ProcessEvent( ClearedEvent );
|
||||
m_toolMgr->ProcessEvent( EVENTS::ClearedEvent );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::hideLocalRatsnest, true );
|
||||
}
|
||||
|
||||
|
@ -1451,10 +1433,9 @@ int SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
BOARD_ITEM* SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector,
|
||||
const wxString& aTitle )
|
||||
bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxString& aTitle )
|
||||
{
|
||||
BOARD_ITEM* current = NULL;
|
||||
BOARD_ITEM* current = nullptr;
|
||||
SELECTION highlightGroup;
|
||||
CONTEXT_MENU menu;
|
||||
|
||||
|
@ -1475,6 +1456,7 @@ BOARD_ITEM* SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector,
|
|||
|
||||
if( aTitle.Length() )
|
||||
menu.SetTitle( aTitle );
|
||||
|
||||
menu.SetIcon( info_xpm );
|
||||
menu.DisplayTitle( true );
|
||||
SetContextMenu( &menu, CMENU_NOW );
|
||||
|
@ -1518,9 +1500,14 @@ BOARD_ITEM* SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector,
|
|||
getView()->Remove( &highlightGroup );
|
||||
|
||||
if( current )
|
||||
{
|
||||
toggleSelection( current );
|
||||
aCollector->Empty();
|
||||
aCollector->Append( current );
|
||||
return true;
|
||||
}
|
||||
|
||||
return current;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1849,8 +1836,8 @@ void SELECTION_TOOL::highlight( BOARD_ITEM* aItem, int aMode, SELECTION& aGroup
|
|||
|
||||
aGroup.Add( aItem );
|
||||
|
||||
// Modules are treated in a special way - when they are selected, we have to
|
||||
// unselect all the parts that make the module, not the module itself
|
||||
// Modules are treated in a special way - when they are highlighted, we have to
|
||||
// highlight all the parts that make the module, not the module itself
|
||||
if( aItem->Type() == PCB_MODULE_T )
|
||||
{
|
||||
static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
|
||||
|
@ -1886,8 +1873,8 @@ void SELECTION_TOOL::unhighlight( BOARD_ITEM* aItem, int aMode, SELECTION& aGrou
|
|||
view()->Hide( aItem, false );
|
||||
view()->Update( aItem );
|
||||
|
||||
// Modules are treated in a special way - when they are selected, we have to
|
||||
// unselect all the parts that make the module, not the module itself
|
||||
// Modules are treated in a special way - when they are highlighted, we have to
|
||||
// highlight all the parts that make the module, not the module itself
|
||||
if( aItem->Type() == PCB_MODULE_T )
|
||||
{
|
||||
static_cast<MODULE*>( aItem )->RunOnChildren( [&] ( BOARD_ITEM* item )
|
||||
|
@ -2301,6 +2288,3 @@ int SELECTION_TOOL::updateSelection( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
const TOOL_EVENT SELECTION_TOOL::SelectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.selected" );
|
||||
const TOOL_EVENT SELECTION_TOOL::UnselectedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.unselected" );
|
||||
const TOOL_EVENT SELECTION_TOOL::ClearedEvent( TC_MESSAGE, TA_ACTION, "pcbnew.InteractiveSelection.cleared" );
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2013-2017 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
* Copyright (C) 2017 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||
* Copyright (C) 2017-2019 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -132,15 +132,6 @@ public:
|
|||
*/
|
||||
int SelectionMenu( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Event sent after an item is selected.
|
||||
static const TOOL_EVENT SelectedEvent;
|
||||
|
||||
///> Event sent after an item is unselected.
|
||||
static const TOOL_EVENT UnselectedEvent;
|
||||
|
||||
///> Event sent after selection is cleared.
|
||||
static const TOOL_EVENT ClearedEvent;
|
||||
|
||||
///> Sets up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
|
@ -168,11 +159,11 @@ private:
|
|||
* Function selectCursor()
|
||||
* Selects an item under the cursor unless there is something already selected or aSelectAlways
|
||||
* is true.
|
||||
* @param aSelectAlways forces to select an item even if there is an item already selected.
|
||||
* @param aForceSelect forces to select an item even if there is an item already selected.
|
||||
* @param aClientFilter allows the client to perform tool- or action-specific filtering.
|
||||
* @return true if eventually there is an item selected, false otherwise.
|
||||
*/
|
||||
bool selectCursor( bool aSelectAlways = false,
|
||||
bool selectCursor( bool aForceSelect = false,
|
||||
CLIENT_SELECTION_FILTER aClientFilter = NULL );
|
||||
|
||||
/**
|
||||
|
@ -186,10 +177,12 @@ private:
|
|||
|
||||
/**
|
||||
* Allows the selection of a single item from a list via pop-up menu. The items are
|
||||
* highlighted on the canvas when hovered in the menu.
|
||||
* highlighted on the canvas when hovered in the menu. The collector is trimmed to
|
||||
* the picked item.
|
||||
* @param aTitle (optional) Allows the menu to be titled (ie: "Clarify Selection").
|
||||
* @return true if an item was picked
|
||||
*/
|
||||
BOARD_ITEM* doSelectionMenu( GENERAL_COLLECTOR* aItems, const wxString& aTitle );
|
||||
bool doSelectionMenu( GENERAL_COLLECTOR* aItems, const wxString& aTitle );
|
||||
|
||||
///> Selects a trivial connection (between two junctions) of items in selection
|
||||
int selectConnection( const TOOL_EVENT& aEvent );
|
||||
|
@ -295,7 +288,7 @@ private:
|
|||
void unselect( BOARD_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Function selectVisually()
|
||||
* Function highlight()
|
||||
* Highlights the item visually.
|
||||
* @param aItem is an item to be be highlighted.
|
||||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
|
@ -304,7 +297,7 @@ private:
|
|||
void highlight( BOARD_ITEM* aItem, int aHighlightMode, SELECTION& aGroup );
|
||||
|
||||
/**
|
||||
* Function unselectVisually()
|
||||
* Function unhighlight()
|
||||
* Unhighlights the item visually.
|
||||
* @param aItem is an item to be be highlighted.
|
||||
* @param aHighlightMode should be either SELECTED or BRIGHTENED
|
||||
|
@ -336,28 +329,16 @@ private:
|
|||
|
||||
const GENERAL_COLLECTORS_GUIDE getCollectorsGuide() const;
|
||||
|
||||
/// Pointer to the parent frame.
|
||||
PCB_BASE_FRAME* m_frame;
|
||||
private:
|
||||
PCB_BASE_FRAME* m_frame; // Pointer to the parent frame
|
||||
SELECTION m_selection; // Current state of selection
|
||||
|
||||
/// Current state of selection.
|
||||
SELECTION m_selection;
|
||||
bool m_additive; // Items should be added to selection (instead of replacing)
|
||||
bool m_subtractive; // Items should be removed from selection
|
||||
bool m_multiple; // Multiple selection mode is active
|
||||
bool m_skip_heuristics; // Heuristics are not allowed when choosing item under cursor
|
||||
bool m_locked; // Other tools are not allowed to modify locked items
|
||||
|
||||
/// Flag saying if items should be added to the current selection or rather replace it.
|
||||
bool m_additive;
|
||||
|
||||
/// Flag saying if items should be removed from the current selection
|
||||
bool m_subtractive;
|
||||
|
||||
/// Flag saying if multiple selection mode is active.
|
||||
bool m_multiple;
|
||||
|
||||
/// Flag saying that heuristics should be skipped while choosing selection
|
||||
bool m_skip_heuristics;
|
||||
|
||||
/// Can other tools modify locked items.
|
||||
bool m_locked;
|
||||
|
||||
/// Menu model displayed by the tool.
|
||||
TOOL_MENU m_menu;
|
||||
|
||||
/// Private state (opaque pointer/compilation firewall)
|
||||
|
|
Loading…
Reference in New Issue