kicad/eeschema/locate.cpp

936 lines
30 KiB
C++
Raw Normal View History

2007-09-02 15:49:11 +00:00
/******************************************************/
/* Routines de localisation d'un element d'un schema. */
/******************************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "confirm.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "trigo.h"
#include "macros.h"
#include "class_drawpickedstruct.h"
#include "class_marker_sch.h"
#include "protos.h"
/* Routines Locales */
static SCH_ITEM* LastSnappedStruct = NULL;
static int PickedBoxMinX, PickedBoxMinY, PickedBoxMaxX, PickedBoxMaxY;
static bool IsBox1InBox2( int StartX1, int StartY1, int EndX1, int EndY1,
2007-09-02 15:49:11 +00:00
int StartX2, int StartY2, int EndX2, int EndY2 );
2009-01-02 13:19:34 +00:00
static bool SnapPoint2( const wxPoint& aPosRef, int SearchMask,
SCH_ITEM* DrawList, DrawPickedStruct* DontSnapList, double aScaleFactor );
/*********************************************************************/
2008-03-20 01:50:21 +00:00
SCH_COMPONENT* LocateSmallestComponent( SCH_SCREEN* Screen )
/*********************************************************************/
2007-09-02 15:49:11 +00:00
/* Search the smaller (considering its area) component under the mouse cursor or the pcb cursor
2007-09-02 15:49:11 +00:00
* If more than 1 component is found, a pointer to the smaller component is returned
*/
{
SCH_COMPONENT* component = NULL, * lastcomponent = NULL;
SCH_ITEM* DrawList;
EDA_Rect BoundaryBox;
float sizeref = 0, sizecurr;
2007-09-02 15:49:11 +00:00
DrawList = Screen->EEDrawList;
while( DrawList )
{
if( ( SnapPoint2( Screen->m_MousePosition, LIBITEM,
DrawList, NULL, Screen->GetZoom() ) ) == FALSE )
2007-09-02 15:49:11 +00:00
{
if( ( SnapPoint2( Screen->m_Curseur, LIBITEM,
DrawList, NULL, Screen->GetScalingFactor() ) ) == FALSE )
2007-09-02 15:49:11 +00:00
break;
}
component = (SCH_COMPONENT*) LastSnappedStruct;
DrawList = component->Next();
if( lastcomponent == NULL ) // First time a component is located
2007-09-02 15:49:11 +00:00
{
lastcomponent = component;
BoundaryBox = lastcomponent->GetBoundaryBox();
2007-09-02 15:49:11 +00:00
sizeref = ABS( (float) BoundaryBox.GetWidth() * BoundaryBox.GetHeight() );
}
else
{
BoundaryBox = component->GetBoundaryBox();
2007-09-02 15:49:11 +00:00
sizecurr = ABS( (float) BoundaryBox.GetWidth() * BoundaryBox.GetHeight() );
if( sizeref > sizecurr ) // a smallest component is found
{
sizeref = sizecurr;
lastcomponent = component;
2007-09-02 15:49:11 +00:00
}
}
}
return lastcomponent;
}
/********************************************************************************/
SCH_ITEM* PickStruct( const wxPoint& refpos, BASE_SCREEN* screen, int SearchMask )
/******************************************************************************/
/* Search an item at pos refpos
* SearchMask = (bitwise OR):
2007-09-02 15:49:11 +00:00
* LIBITEM
* WIREITEM
* BUSITEM
* RACCORDITEM
* JUNCTIONITEM
* DRAWITEM
* TEXTITEM
* LABELITEM
* SHEETITEM
* MARKERITEM
* NOCONNECTITEM
* SEARCH_PINITEM
* SHEETLABELITEM
* FIELDCMPITEM
2008-03-20 01:50:21 +00:00
*
2007-09-02 15:49:11 +00:00
* if EXCLUDE_WIRE_BUS_ENDPOINTS is set, in wire ou bus search and locate,
* start and end points are not included in search
* if WIRE_BUS_ENDPOINTS_ONLY is set, in wire ou bus search and locate,
* only start and end points are included in search
2008-03-20 01:50:21 +00:00
*
*
2007-09-02 15:49:11 +00:00
* Return:
* pointer on item found or NULL
2008-03-20 01:50:21 +00:00
*
2007-09-02 15:49:11 +00:00
*/
{
bool Snapped;
2009-01-02 13:19:34 +00:00
if( screen == NULL || screen->EEDrawList == NULL )
2008-03-20 01:50:21 +00:00
return NULL;
2007-09-02 15:49:11 +00:00
if( ( Snapped = SnapPoint2( refpos, SearchMask,
screen->EEDrawList, NULL, screen->GetScalingFactor() ) ) != FALSE )
2007-09-02 15:49:11 +00:00
{
return LastSnappedStruct;
}
return NULL;
}
2007-09-02 15:49:11 +00:00
/***********************************************************************/
SCH_ITEM* PickStruct( EDA_Rect& block, BASE_SCREEN* screen, int SearchMask )
/************************************************************************/
2007-09-02 15:49:11 +00:00
/* Search items in block
* Return:
* pointeur sur liste de pointeurs de structures si Plusieurs
* structures selectionnees.
* pointeur sur la structure si 1 seule
*
2007-09-02 15:49:11 +00:00
*/
{
int x, y, OrigX, OrigY;
2007-09-02 15:49:11 +00:00
DrawPickedStruct* PickedList = NULL, * PickedItem;
SCH_ITEM* DrawStruct;
2007-09-02 15:49:11 +00:00
OrigX = block.GetX();
OrigY = block.GetY();
x = block.GetRight();
y = block.GetBottom();
2007-09-02 15:49:11 +00:00
if( x < OrigX )
EXCHG( x, OrigX );
if( y < OrigY )
EXCHG( y, OrigY );
2008-03-20 01:50:21 +00:00
SCH_ITEM* DrawList = screen->EEDrawList;
if( screen==NULL || DrawList == NULL )
return NULL;
2008-03-20 01:50:21 +00:00
for( DrawStruct = DrawList; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
2007-09-02 15:49:11 +00:00
{
if( DrawStructInBox( OrigX, OrigY, x, y, DrawStruct ) )
{
/* Put this structure in the picked list: */
PickedItem = new DrawPickedStruct( DrawStruct );
PickedItem->SetNext( PickedList );
2007-09-02 15:49:11 +00:00
PickedList = PickedItem;
}
}
if( PickedList && PickedList->Next() == NULL )
2007-09-02 15:49:11 +00:00
{
/* Only one item was picked - convert to scalar form (no list): */
PickedItem = PickedList;
PickedList = (DrawPickedStruct*) PickedList->m_PickedStruct;
SAFE_DELETE( PickedItem );
2007-09-02 15:49:11 +00:00
}
if( PickedList != NULL )
{
PickedBoxMinX = OrigX; PickedBoxMinY = OrigY;
PickedBoxMaxX = x; PickedBoxMaxY = y;
}
return (SCH_ITEM*) PickedList;
}
2007-09-02 15:49:11 +00:00
/*****************************************************************************
* Routine to search all objects for the closest point to a given point, in *
* drawing space, and snap it to that points if closer than SnapDistance. *
* Note we use L1 norm as distance measure, as it is the fastest. *
* This routine updates LastSnappedStruct to the last object used in to snap *
* a point. This variable is global to this module only (see above). *
* If DontSnapList is not NULL, structes in this list are skipped. *
* The routine returns TRUE if point was snapped. *
*****************************************************************************/
2009-01-02 13:19:34 +00:00
bool SnapPoint2( const wxPoint& aPosRef, int SearchMask,
SCH_ITEM* DrawList, DrawPickedStruct* DontSnapList, double aScaleFactor )
{
2007-09-02 15:49:11 +00:00
DrawPickedStruct* DontSnap;
for( ; DrawList != NULL; DrawList = DrawList->Next() )
2007-09-02 15:49:11 +00:00
{
/* Make sure this structure is NOT in the dont snap list: */
DontSnap = DontSnapList;
for( ; DontSnap != NULL; DontSnap = DontSnap->Next() )
2007-09-02 15:49:11 +00:00
if( DontSnap->m_PickedStruct == DrawList )
break;
if( DontSnap )
if( DontSnap->m_PickedStruct == DrawList )
continue;
2009-06-13 17:06:07 +00:00
int hitminDist = MAX( g_DrawDefaultLineThickness, 3 ) ;
2007-09-02 15:49:11 +00:00
switch( DrawList->Type() )
{
case DRAW_POLYLINE_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawPolylineStruct*) DrawList )
if( !( SearchMask & (DRAWITEM | WIREITEM | BUSITEM) ) )
break;
2008-03-20 01:50:21 +00:00
for( unsigned i = 0; i < STRUCT->GetCornerCount() - 1; i++ )
2007-09-02 15:49:11 +00:00
{
2009-06-13 17:06:07 +00:00
if( TestSegmentHit( aPosRef, STRUCT->m_PolyPoints[i],
STRUCT->m_PolyPoints[i + 1], hitminDist ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
}
2007-09-02 15:49:11 +00:00
break;
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (EDA_DrawLineStruct*) DrawList )
if( !( SearchMask & (DRAWITEM | WIREITEM | BUSITEM) ) )
break;
2009-06-13 17:06:07 +00:00
if( TestSegmentHit( aPosRef, STRUCT->m_Start, STRUCT->m_End, 0 ) )
2007-09-02 15:49:11 +00:00
{
if( ( (SearchMask & DRAWITEM) && (STRUCT->GetLayer() == LAYER_NOTES) )
|| ( (SearchMask & WIREITEM) && (STRUCT->GetLayer() == LAYER_WIRE) )
|| ( (SearchMask & BUSITEM) && (STRUCT->GetLayer() == LAYER_BUS) )
2007-09-02 15:49:11 +00:00
)
{
if( SearchMask & EXCLUDE_WIRE_BUS_ENDPOINTS )
{
2009-01-02 13:19:34 +00:00
if( aPosRef == STRUCT->m_Start || aPosRef == STRUCT->m_End )
2007-09-02 15:49:11 +00:00
break;
}
if( SearchMask & WIRE_BUS_ENDPOINTS_ONLY )
{
2009-01-02 13:19:34 +00:00
if( !STRUCT->IsOneEndPointAt( aPosRef ) )
2007-09-02 15:49:11 +00:00
break;
}
LastSnappedStruct = DrawList;
return TRUE;
}
}
break;
case DRAW_BUSENTRY_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawBusEntryStruct*) DrawList )
if( !( SearchMask & (RACCORDITEM) ) )
break;
2009-06-13 17:06:07 +00:00
if( TestSegmentHit( aPosRef, STRUCT->m_Pos, STRUCT->m_End(), hitminDist ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
break;
case DRAW_JUNCTION_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawJunctionStruct*) DrawList )
if( !(SearchMask & JUNCTIONITEM) )
break;
if( STRUCT->HitTest( aPosRef ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawNoConnectStruct*) DrawList )
if( !(SearchMask & NOCONNECTITEM) )
break;
if( STRUCT->HitTest( aPosRef ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
break;
case DRAW_MARKER_STRUCT_TYPE:
{
2007-09-02 15:49:11 +00:00
#undef STRUCT
#define STRUCT ( (MARKER_SCH*) DrawList )
2007-09-02 15:49:11 +00:00
if( !(SearchMask & MARKERITEM) )
break;
if( STRUCT->HitTest(aPosRef) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
break;
}
2007-09-02 15:49:11 +00:00
2008-03-20 01:50:21 +00:00
case TYPE_SCH_TEXT:
2007-09-02 15:49:11 +00:00
#undef STRUCT
2008-03-20 01:50:21 +00:00
#define STRUCT ( (SCH_TEXT*) DrawList )
if( !( SearchMask & TEXTITEM) )
2007-09-02 15:49:11 +00:00
break;
if( STRUCT->HitTest( aPosRef ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
break;
case TYPE_SCH_LABEL:
2008-03-20 01:50:21 +00:00
case TYPE_SCH_GLOBALLABEL:
case TYPE_SCH_HIERLABEL:
#undef STRUCT
#define STRUCT ( (SCH_TEXT*) DrawList ) // SCH_TEXT is the base class of these labels
if( !(SearchMask & LABELITEM) )
break;
if( STRUCT->HitTest( aPosRef ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
break;
2008-03-20 01:50:21 +00:00
case TYPE_SCH_COMPONENT:
2007-09-02 15:49:11 +00:00
if( !( SearchMask & (LIBITEM | FIELDCMPITEM) ) )
break;
if( SearchMask & FIELDCMPITEM )
{
SCH_COMPONENT* DrawLibItem = (SCH_COMPONENT*) DrawList;
2009-01-02 17:07:50 +00:00
for( int i = REFERENCE; i < DrawLibItem->GetFieldCount(); i++ )
2007-09-02 15:49:11 +00:00
{
SCH_CMP_FIELD* field = DrawLibItem->GetField( i );
if( field->m_Attributs & TEXT_NO_VISIBLE )
2007-09-02 15:49:11 +00:00
continue;
if( field->IsVoid() )
2007-09-02 15:49:11 +00:00
continue;
EDA_Rect BoundaryBox = field->GetBoundaryBox();
2009-01-02 13:19:34 +00:00
if( BoundaryBox.Inside( aPosRef ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = field;
2007-09-02 15:49:11 +00:00
return TRUE;
}
}
}
else
{
#undef STRUCT
2008-03-20 01:50:21 +00:00
#define STRUCT ( (SCH_COMPONENT*) DrawList )
2007-09-02 15:49:11 +00:00
EDA_Rect BoundaryBox = STRUCT->GetBoundaryBox();
2009-01-02 13:19:34 +00:00
if( BoundaryBox.Inside( aPosRef ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
}
break;
case DRAW_SHEET_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawSheetStruct*) DrawList )
if( !(SearchMask & SHEETITEM) )
break;
if( STRUCT->HitTest( aPosRef ) )
2007-09-02 15:49:11 +00:00
{
LastSnappedStruct = DrawList;
return TRUE;
}
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
break;
default:
{
wxString msg;
msg.Printf( wxT( "SnapPoint2() error: unexpected strct type %d (" ), DrawList->Type() );
msg << DrawList->GetClass() << wxT( ")" );
2007-09-02 15:49:11 +00:00
DisplayError( NULL, msg );
break;
}
}
}
return FALSE;
}
/*****************************************************************************
* Routine to test if an object has non empty intersection with the box *
* defined by x1/y1 and x2/y2 (x1 < x2, y1 < y2), and return TRUE if so. This *
* routine is used to pick all points in a given box. *
*****************************************************************************/
2009-01-02 17:07:50 +00:00
bool DrawStructInBox( int x1, int y1, int x2, int y2, SCH_ITEM* DrawStruct )
{
2009-01-02 17:07:50 +00:00
int xt1, yt1, xt2, yt2;
2007-09-02 15:49:11 +00:00
int dx, dy;
wxString msg;
switch( DrawStruct->Type() )
{
case DRAW_POLYLINE_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawPolylineStruct*) DrawStruct )
for( unsigned i = 0; i < STRUCT->GetCornerCount(); i++ )
2007-09-02 15:49:11 +00:00
{
2009-01-02 17:07:50 +00:00
if( STRUCT->m_PolyPoints[i].x >= x1 && STRUCT->m_PolyPoints[i].x <= x2
&& STRUCT->m_PolyPoints[i].y >= y1 && STRUCT->m_PolyPoints[i].y <=y2 )
2007-09-02 15:49:11 +00:00
return TRUE;
}
break;
case DRAW_SEGMENT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (EDA_DrawLineStruct*) DrawStruct )
if( STRUCT->m_Start.x >= x1 && STRUCT->m_Start.x <= x2
&& STRUCT->m_Start.y >= y1 && STRUCT->m_Start.y <=y2 )
return TRUE;
if( (STRUCT->m_End.x >= x1) && (STRUCT->m_End.x <= x2)
&& (STRUCT->m_End.y >= y1) && (STRUCT->m_End.y <=y2) )
return TRUE;
break;
case DRAW_BUSENTRY_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawBusEntryStruct*) DrawStruct )
if( STRUCT->m_Pos.x >= x1 && STRUCT->m_Pos.x <= x2
&& STRUCT->m_Pos.y >= y1 && STRUCT->m_Pos.y <=y2 )
return TRUE;
if( (STRUCT->m_End().x >= x1) && ( STRUCT->m_End().x <= x2)
&& ( STRUCT->m_End().y >= y1) && ( STRUCT->m_End().y <=y2) )
return TRUE;
break;
case DRAW_JUNCTION_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawJunctionStruct*) DrawStruct )
if( (STRUCT->m_Pos.x >= x1) && (STRUCT->m_Pos.x <= x2)
&& (STRUCT->m_Pos.y >= y1) && (STRUCT->m_Pos.y <= y2) )
return TRUE;
break;
case DRAW_NOCONNECT_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawNoConnectStruct*) DrawStruct )
if( (STRUCT->m_Pos.x >= x1) && (STRUCT->m_Pos.x <= x2)
&& (STRUCT->m_Pos.y >= y1) && (STRUCT->m_Pos.y <= y2) )
return TRUE;
break;
case DRAW_MARKER_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (MARKER_SCH*) DrawStruct )
2007-09-02 15:49:11 +00:00
if( (STRUCT->m_Pos.x >= x1) && (STRUCT->m_Pos.x <= x2)
&& (STRUCT->m_Pos.y >= y1) && (STRUCT->m_Pos.y <= y2) )
return TRUE;
break;
2008-03-20 01:50:21 +00:00
case TYPE_SCH_LABEL:
case TYPE_SCH_TEXT:
2007-09-02 15:49:11 +00:00
#undef STRUCT
2008-03-20 01:50:21 +00:00
#define STRUCT ( (SCH_TEXT*) DrawStruct )
2007-09-02 15:49:11 +00:00
dx = STRUCT->m_Size.x * STRUCT->GetLength();
dy = STRUCT->m_Size.y;
xt1 = xt2 = STRUCT->m_Pos.x;
yt1 = yt2 = STRUCT->m_Pos.y;
switch( STRUCT->m_Orient )
{
case 0: /* HORIZONTAL Left justified */
2007-09-02 15:49:11 +00:00
xt2 += dx; yt2 -= dy;
break;
case 1: /* VERTICAL UP */
xt2 -= dy; yt2 -= dx;
break;
case 2: /* horizontal Right justified */
xt2 -= dx; yt2 -= dy;
2007-09-02 15:49:11 +00:00
break;
case 3: /* vertical DOWN */
xt2 -= dy; yt2 += dx;
2007-09-02 15:49:11 +00:00
break;
}
if( IsBox1InBox2( xt1, yt1, xt2, yt2, x1, y1, x2, y2 ) )
return TRUE;
break;
2008-03-20 01:50:21 +00:00
case TYPE_SCH_HIERLABEL:
case TYPE_SCH_GLOBALLABEL:
2007-09-02 15:49:11 +00:00
#undef STRUCT
2008-03-20 01:50:21 +00:00
#define STRUCT ( (SCH_LABEL*) DrawStruct )
2007-09-02 15:49:11 +00:00
dx = STRUCT->m_Size.x * ( STRUCT->GetLength() + 1); /* longueur totale */
dy = STRUCT->m_Size.y / 2; /* Demi hauteur */
xt1 = xt2 = STRUCT->m_Pos.x;
yt1 = yt2 = STRUCT->m_Pos.y;
switch( STRUCT->m_Orient )
{
case 0: /* HORIZONTAL */
xt2 -= dx; yt2 += dy; yt1 -= dy;
break;
case 1: /* VERTICAL UP */
xt1 -= dy; xt2 += dy; yt2 += dx;
break;
case 2: /* horizontal inverse */
xt2 += dx; yt2 += dy; yt1 -= dy;
break;
case 3: /* vertical DOWN */
xt1 -= dy; xt2 += dy; yt2 -= dx;
break;
}
if( IsBox1InBox2( xt1, yt1, xt2, yt2, x1, y1, x2, y2 ) )
return TRUE;
break;
2008-03-20 01:50:21 +00:00
case TYPE_SCH_COMPONENT:
2007-09-02 15:49:11 +00:00
{
#undef STRUCT
2008-03-20 01:50:21 +00:00
#define STRUCT ( (SCH_COMPONENT*) DrawStruct )
2007-09-02 15:49:11 +00:00
EDA_Rect BoundaryBox = STRUCT->GetBoundaryBox();
xt1 = BoundaryBox.GetX();
yt1 = BoundaryBox.GetY();
xt2 = BoundaryBox.GetRight();
yt2 = BoundaryBox.GetBottom();
if( IsBox1InBox2( xt1, yt1, xt2, yt2, x1, y1, x2, y2 ) )
return TRUE;
break;
}
case DRAW_SHEET_STRUCT_TYPE:
#undef STRUCT
#define STRUCT ( (DrawSheetStruct*) DrawStruct )
/* Recalcul des coordonnees de l'encadrement du composant */
xt1 = STRUCT->m_Pos.x;
yt1 = STRUCT->m_Pos.y;
xt2 = STRUCT->m_Pos.x + STRUCT->m_Size.x;
yt2 = STRUCT->m_Pos.y + STRUCT->m_Size.y;
if( IsBox1InBox2( xt1, yt1, xt2, yt2, x1, y1, x2, y2 ) )
return TRUE;
break;
2008-04-15 19:38:19 +00:00
case DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE:
2007-09-02 15:49:11 +00:00
break;
case DRAW_PICK_ITEM_STRUCT_TYPE:
break;
default:
msg.Printf(
wxT( "DrawStructInBox() Err: unexpected StructType %d (" ),
DrawStruct->Type() );
msg << DrawStruct->GetClass() << wxT( ")" );
2007-09-02 15:49:11 +00:00
DisplayError( NULL, msg );
break;
}
return FALSE;
}
2007-09-02 15:49:11 +00:00
/****************************************************************************/
static bool IsBox1InBox2( int StartX1, int StartY1, int EndX1, int EndY1,
2007-09-02 15:49:11 +00:00
int StartX2, int StartY2, int EndX2, int EndY2 )
/****************************************************************************/
2007-09-02 15:49:11 +00:00
/* Routine detectant que le rectangle 1 (Box1) et le rectangle 2 (Box2) se
* recouvrent.
* Retourne TRUE ou FALSE.
2008-03-20 01:50:21 +00:00
*
2007-09-02 15:49:11 +00:00
* On Considere ici qu'il y a recouvrement si l'un au moins des coins
* d'un 'Box' est compris dans l'autre
*/
{
2007-09-02 15:49:11 +00:00
int cX, cY;
2007-09-02 15:49:11 +00:00
if( StartX1 > EndX1 )
EXCHG( StartX1, EndX1 );
if( StartX2 > EndX2 )
EXCHG( StartX2, EndX2 );
if( StartY1 > EndY1 )
EXCHG( StartY1, EndY1 );
if( StartY2 > EndY2 )
EXCHG( StartY2, EndY2 );
2007-09-02 15:49:11 +00:00
/* Tst des 4 coins du rectangle 1 */
cX = StartX1; cY = StartY1; /* 1er coin */
if( (cX >= StartX2) && (cX <= EndX2) && (cY >= StartY2) && (cY <= EndY2) )
return TRUE;
2007-09-02 15:49:11 +00:00
cX = EndX1; cY = StartY1; /* 2er coin */
if( (cX >= StartX2) && (cX <= EndX2) && (cY >= StartY2) && (cY <= EndY2) )
return TRUE;
2007-09-02 15:49:11 +00:00
cX = EndX1; cY = EndY1; /* 3eme coin */
if( (cX >= StartX2) && (cX <= EndX2) && (cY >= StartY2) && (cY <= EndY2) )
return TRUE;
2007-09-02 15:49:11 +00:00
cX = StartX1; cY = EndY1; /* 4eme coin */
if( (cX >= StartX2) && (cX <= EndX2) && (cY >= StartY2) && (cY <= EndY2) )
return TRUE;
2007-09-02 15:49:11 +00:00
/* Tst des 4 coins du rectangle 2 */
cX = StartX2; cY = StartY2; /* 1er coin */
if( (cX >= StartX1) && (cX <= EndX1) && (cY >= StartY1) && (cY <= EndY1) )
return TRUE;
2007-09-02 15:49:11 +00:00
cX = EndX2; cY = StartY2; /* 2er coin */
if( (cX >= StartX1) && (cX <= EndX1) && (cY >= StartY1) && (cY <= EndY1) )
return TRUE;
2007-09-02 15:49:11 +00:00
cX = EndX2; cY = EndY2; /* 3er coin */
if( (cX >= StartX1) && (cX <= EndX1) && (cY >= StartY1) && (cY <= EndY1) )
return TRUE;
2007-09-02 15:49:11 +00:00
cX = StartX2; cY = EndY2; /* 4er coin */
if( (cX >= StartX1) && (cX <= EndX1) && (cY >= StartY1) && (cY <= EndY1) )
return TRUE;
2007-09-02 15:49:11 +00:00
return FALSE;
}
2007-09-02 15:49:11 +00:00
/*********************************************************************************/
LibEDA_BaseStruct* LocateDrawItem( SCH_SCREEN* Screen,
2009-01-02 13:19:34 +00:00
const wxPoint& aRefPoint,
2007-09-02 15:49:11 +00:00
EDA_LibComponentStruct* LibEntry,
int Unit,
int Convert,
int masque )
/*********************************************************************************/
2007-09-02 15:49:11 +00:00
2009-01-02 17:07:50 +00:00
/* Locates a body item( not pins )
* Unit = part number (if Unit = 0, all parts are considered)
* Convert = convert value for shape (si Convert = 0, all shapes are considered)
* remember the Y axis is from bottom to top in library entries for graphic items.
2007-09-02 15:49:11 +00:00
*/
{
2007-09-02 15:49:11 +00:00
LibEDA_BaseStruct* DrawItem;
if( LibEntry == NULL )
return NULL;
if( LibEntry->Type != ROOT )
{
DisplayError( NULL, wxT( "Error in LocateDrawItem: Entry is ALIAS" ) );
return NULL;
}
DrawItem = LibEntry->m_Drawings;
for( ; DrawItem != NULL; DrawItem = DrawItem->Next() )
{
if( Unit && DrawItem->m_Unit && (Unit != DrawItem->m_Unit) )
continue;
if( Convert && DrawItem->m_Convert && (Convert != DrawItem->m_Convert) )
continue;
switch( DrawItem->Type() )
{
case COMPONENT_ARC_DRAW_TYPE:
if( (masque & LOCATE_COMPONENT_ARC_DRAW_TYPE) == 0 )
break;
2009-06-13 17:06:07 +00:00
if( DrawItem->HitTest( aRefPoint ) )
2007-09-02 15:49:11 +00:00
return DrawItem;
break;
2007-09-02 15:49:11 +00:00
case COMPONENT_CIRCLE_DRAW_TYPE:
if( (masque & LOCATE_COMPONENT_CIRCLE_DRAW_TYPE) == 0 )
break;
2009-06-13 17:06:07 +00:00
if( DrawItem->HitTest( aRefPoint ) )
2007-09-02 15:49:11 +00:00
return DrawItem;
break;
2007-09-02 15:49:11 +00:00
2009-06-13 17:06:07 +00:00
case COMPONENT_RECT_DRAW_TYPE: // Locate a rect if the mouse cursor is on a side of this rectangle
2007-09-02 15:49:11 +00:00
if( (masque & LOCATE_COMPONENT_RECT_DRAW_TYPE) == 0 )
break;
2009-06-13 17:06:07 +00:00
if( DrawItem->HitTest( aRefPoint ) )
2007-09-02 15:49:11 +00:00
return DrawItem;
2009-06-13 17:06:07 +00:00
break;
2007-09-02 15:49:11 +00:00
case COMPONENT_POLYLINE_DRAW_TYPE:
if( (masque & LOCATE_COMPONENT_POLYLINE_DRAW_TYPE) == 0 )
break;
2009-06-13 17:06:07 +00:00
if( DrawItem->HitTest( aRefPoint ) )
return DrawItem;
break;
2007-09-02 15:49:11 +00:00
2009-06-25 20:45:27 +00:00
case COMPONENT_BEZIER_DRAW_TYPE:
if( (masque & LOCATE_COMPONENT_POLYLINE_DRAW_TYPE) == 0 )
break;
if( DrawItem->HitTest( aRefPoint ) )
return DrawItem;
break;
2007-09-02 15:49:11 +00:00
case COMPONENT_LINE_DRAW_TYPE:
if( (masque & LOCATE_COMPONENT_LINE_DRAW_TYPE) == 0 )
break;
2009-06-13 17:06:07 +00:00
if( DrawItem->HitTest( aRefPoint ) )
2007-09-02 15:49:11 +00:00
return DrawItem;
break;
2007-09-02 15:49:11 +00:00
case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
if( (masque & LOCATE_COMPONENT_GRAPHIC_TEXT_DRAW_TYPE) == 0 )
break;
2009-06-13 17:06:07 +00:00
if( DrawItem->HitTest( aRefPoint ) )
return DrawItem;
break;
2007-09-02 15:49:11 +00:00
default:
;
}
}
return NULL;
}
/*******************************************************************/
LibDrawPin* LocatePinByNumber( const wxString& ePin_Number,
SCH_COMPONENT* eComponent )
/*******************************************************************/
/** Find a PIN in a component
* @param pin_number = pin number (string)
* @param pin_number = pin number (string)
* @return a pointer on the pin, or NULL if not found
*/
{
LibEDA_BaseStruct* DrawItem;
2008-03-20 01:50:21 +00:00
EDA_LibComponentStruct* Entry;
LibDrawPin* Pin;
2008-03-20 01:50:21 +00:00
int Unit, Convert;
Entry = FindLibPart( eComponent->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
if( Entry == NULL )
return NULL;
if( Entry->Type != ROOT )
{
DisplayError( NULL, wxT( "LocatePinByNumber() error: Entry is ALIAS" ) );
return NULL;
}
Unit = eComponent->m_Multi;
2008-03-20 01:50:21 +00:00
Convert = eComponent->m_Convert;
DrawItem = Entry->m_Drawings;
for( ; DrawItem != NULL; DrawItem = DrawItem->Next() )
{
if( DrawItem->Type() == COMPONENT_PIN_DRAW_TYPE ) /* Pin Trouvee */
{
Pin = (LibDrawPin*) DrawItem;
if( Unit && DrawItem->m_Unit && (DrawItem->m_Unit != Unit) )
continue;
if( Convert && DrawItem->m_Convert && (DrawItem->m_Convert != Convert) )
continue;
2008-03-20 01:50:21 +00:00
wxString pNumber;
Pin->ReturnPinStringNum( pNumber );
if( ePin_Number == pNumber )
2008-03-20 01:50:21 +00:00
return Pin;
}
}
return NULL;
}
/*******************************************************************/
2007-09-02 15:49:11 +00:00
LibEDA_BaseStruct* LocatePin( const wxPoint& RefPos,
EDA_LibComponentStruct* Entry,
2008-03-20 01:50:21 +00:00
int Unit, int convert, SCH_COMPONENT* DrawLibItem )
/*******************************************************************/
2007-09-02 15:49:11 +00:00
/* Routine de localisation d'une PIN de la PartLib pointee par Entry
2007-09-02 15:49:11 +00:00
* retourne un pointeur sur la pin, ou NULL si pas trouve
* Si Unit = 0, le numero d'unite n'est pas teste
* Si convert = 0, le numero convert n'est pas teste
*/
{
2007-09-02 15:49:11 +00:00
if( Entry == NULL )
return NULL;
if( Entry->Type != ROOT )
{
DisplayError( NULL, wxT( "LocatePin() error: Entry is ALIAS" ) );
return NULL;
}
2009-06-13 17:06:07 +00:00
LibEDA_BaseStruct* DrawItem = Entry->m_Drawings;
2007-09-02 15:49:11 +00:00
for( ; DrawItem != NULL; DrawItem = DrawItem->Next() )
{
if( DrawItem->Type() == COMPONENT_PIN_DRAW_TYPE ) /* Pin Trouvee */
{
2009-06-13 17:06:07 +00:00
LibDrawPin* Pin = (LibDrawPin*) DrawItem;
2007-09-02 15:49:11 +00:00
if( Unit && DrawItem->m_Unit && (DrawItem->m_Unit != Unit) )
continue;
if( convert && DrawItem->m_Convert && (DrawItem->m_Convert != convert) )
continue;
if( DrawLibItem == NULL )
{
2009-06-13 17:06:07 +00:00
if ( Pin->HitTest( RefPos ) )
return DrawItem;
2007-09-02 15:49:11 +00:00
}
2009-06-13 17:06:07 +00:00
2007-09-02 15:49:11 +00:00
else
{
2009-06-13 17:06:07 +00:00
int mindist = Pin->m_Width ? Pin->m_Width / 2 : g_DrawDefaultLineThickness / 2;
2007-09-02 15:49:11 +00:00
2009-06-13 17:06:07 +00:00
// Have a minimal tolerance for hit test
if( mindist < 3 )
mindist = 3; // = 3 mils
if ( Pin->HitTest( RefPos - DrawLibItem->m_Pos, mindist, DrawLibItem->m_Transform ) )
return DrawItem;
}
2007-09-02 15:49:11 +00:00
}
}
return NULL;
}
2007-09-02 15:49:11 +00:00
/***********************************************************************************/
2008-04-15 19:38:19 +00:00
Hierarchical_PIN_Sheet_Struct* LocateSheetLabel( DrawSheetStruct* Sheet, const wxPoint& pos )
/***********************************************************************************/
{
2007-09-02 15:49:11 +00:00
int size, dy, minx, maxx;
2008-04-15 19:38:19 +00:00
Hierarchical_PIN_Sheet_Struct* SheetLabel;
2007-09-02 15:49:11 +00:00
SheetLabel = Sheet->m_Label;
2008-04-15 19:38:19 +00:00
while( (SheetLabel) && (SheetLabel->Type()==DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE) )
2007-09-02 15:49:11 +00:00
{
size = ( SheetLabel->GetLength() + 1 ) * SheetLabel->m_Size.x;
if( SheetLabel->m_Edge )
size = -size;
minx = SheetLabel->m_Pos.x; maxx = SheetLabel->m_Pos.x + size;
if( maxx < minx )
EXCHG( maxx, minx );
dy = SheetLabel->m_Size.x / 2;
if( (ABS( pos.y - SheetLabel->m_Pos.y ) <= dy )
&& (pos.x <= maxx)
&& (pos.x >= minx) )
return SheetLabel;
SheetLabel = SheetLabel->Next();
2007-09-02 15:49:11 +00:00
}
return NULL;
}
2007-09-02 15:49:11 +00:00
/**************************************************************************/
LibDrawPin* LocateAnyPin( SCH_ITEM* DrawList, const wxPoint& RefPos,
2008-03-20 01:50:21 +00:00
SCH_COMPONENT** libpart )
/**************************************************************************/
{
SCH_ITEM* DrawStruct;
2007-09-02 15:49:11 +00:00
EDA_LibComponentStruct* Entry;
2008-03-20 01:50:21 +00:00
SCH_COMPONENT* LibItem = NULL;
2007-09-02 15:49:11 +00:00
LibDrawPin* Pin = NULL;
for( DrawStruct = DrawList; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
2007-09-02 15:49:11 +00:00
{
2008-03-20 01:50:21 +00:00
if( DrawStruct->Type() != TYPE_SCH_COMPONENT )
2007-09-02 15:49:11 +00:00
continue;
2008-03-20 01:50:21 +00:00
LibItem = (SCH_COMPONENT*) DrawStruct;
2007-09-02 15:49:11 +00:00
Entry = FindLibPart( LibItem->m_ChipName.GetData(), wxEmptyString, FIND_ROOT );
if( Entry == NULL )
continue;
Pin = (LibDrawPin*) LocatePin( RefPos, Entry, LibItem->m_Multi,
LibItem->m_Convert, LibItem );
2007-09-02 15:49:11 +00:00
if( Pin )
break;
}
if( libpart )
*libpart = LibItem;
return Pin;
}
2007-09-02 15:49:11 +00:00
/***************************************************************/
Hierarchical_PIN_Sheet_Struct* LocateAnyPinSheet( const wxPoint& RefPos,
SCH_ITEM* DrawList )
/***************************************************************/
{
SCH_ITEM* DrawStruct;
2008-04-15 19:38:19 +00:00
Hierarchical_PIN_Sheet_Struct* PinSheet = NULL;
2007-09-02 15:49:11 +00:00
for( DrawStruct = DrawList; DrawStruct != NULL; DrawStruct = DrawStruct->Next() )
2007-09-02 15:49:11 +00:00
{
if( DrawStruct->Type() != DRAW_SHEET_STRUCT_TYPE )
continue;
PinSheet = LocateSheetLabel( (DrawSheetStruct*) DrawStruct,
RefPos );
2007-09-02 15:49:11 +00:00
if( PinSheet )
break;
}
return PinSheet;
}