Commit 6719900e authored by dickelbeck's avatar dickelbeck

searching and beautification

parent f8f38438
......@@ -5,6 +5,18 @@ Please add newer entries at the top, list the date and your name with
email address.
2007-Aug-07 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+ pcbnew & common
* More searching work. Made HitTest() virtual. Factored out a HitTest()
function for both class_module and class_pad from existing code.
* Embellished the Show() function for several of the classes. Could be the
basis of a possible future XML export, but with the native format being
ascii already, this is of questionable value as an export.
* Discovered a long time existing bug in class_module hit-testing.
Still need to understand it. It could just be an improperly formatted module.
2007-Aug-06 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+ pcbnew & common
......
......@@ -191,6 +191,20 @@ wxString EDA_BaseStruct::ReturnClassName() const
#if defined(DEBUG)
// A function that should have been in wxWidgets
std::ostream& operator<<( std::ostream& out, wxSize& size )
{
out << " width=\"" << size.GetWidth() << "\" height=\"" << size.GetHeight() << "\"";
return out;
}
// A function that should have been in wxWidgets
std::ostream& operator<<( std::ostream& out, wxPoint& pt )
{
out << " x=\"" << pt.x << "\" y=\"" << pt.y << "\"";
return out;
}
/**
* Function Show
......
......@@ -8,6 +8,8 @@
#if defined(DEBUG)
#include <iostream> // needed for Show()
extern std::ostream& operator<<( std::ostream& out, wxSize& size );
extern std::ostream& operator<<( std::ostream& out, wxPoint& pt );
#endif
......@@ -177,6 +179,18 @@ public:
const wxPoint& offset,
int draw_mode,
int Color = -1 );
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
virtual bool HitTest( const wxPoint& refPos )
{
return false; // derived classes should override this function
}
#if defined(DEBUG)
......@@ -330,10 +344,10 @@ public:
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param posref A wxPoint to test
* @param ref_pos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& posref );
bool HitTest( const wxPoint& ref_pos );
int Len_Size( void ); // Return the text lenght in internal units
};
......@@ -381,9 +395,11 @@ public:
};
/* class to handle component boundary box.
* This class is similar to wxRect, but some wxRect functions are very curious,
* so I prefer this suitable class
/**
* Class EDA_Rect
* handles the component boundary box.
* This class is similar to wxRect, but some wxRect functions are very curious,
* so I prefer this suitable class
*/
class EDA_Rect
{
......
......@@ -174,16 +174,17 @@ public:
wxPoint m_Curseur; /* Screen cursor coordinate (on grid) in user units. */
wxPoint m_MousePosition; /* Mouse cursor coordinate (off grid) in user units. */
wxPoint m_MousePositionInPixels; /* Mouse cursor coordinate (off grid) in pixels. */
wxPoint m_O_Curseur; /* Relative Screen cursor coordinate (on grid) in user units.
* (coordinates from last reset position)*/
wxPoint m_O_Curseur; /* Relative Screen cursor coordinate (on grid) in user units.
* (coordinates from last reset position)*/
wxPoint m_ScrollbarPos; // Position effective des Curseurs de scroll
wxSize m_ScrollbarNumber;/* Valeur effective des Nombres de Scrool
* c.a.d taille en unites de scroll de la surface totale affichable */
wxSize m_ScrollbarNumber; /* Valeur effective des Nombres de Scrool
* c.a.d taille en unites de scroll de la surface totale affichable */
wxPoint m_StartVisu; // Coord absolues du 1er pixel visualis�a l'ecran (en nombre de pixels)
wxSize m_SizeVisu; /* taille en pixels de l'ecran (fenetre de visu
* Utile pour recadrer les affichages lors de la
* navigation dans la hierarchie */
bool m_Center; // TRUE: coord algebriques, FALSE: coord >= 0
wxSize m_SizeVisu; /* taille en pixels de l'ecran (fenetre de visu
* Utile pour recadrer les affichages lors de la
* navigation dans la hierarchie */
bool m_Center; // TRUE: coord algebriques, FALSE: coord >= 0
bool m_FirstRedraw;
/* Gestion des editions */
......@@ -273,9 +274,22 @@ public:
void SetFirstGrid( void ); /* ajuste la grille au mini*/
void SetLastGrid( void ); /* ajuste la grille au max */
/**
* Function RefPos
* returns the reference position, coming from either the mouse position or the
* the cursor position.
* @param useMouse If true, return mouse posistion, else cursor's.
* @return wxPoint - The reference point, either the mouse position or
* the cursor position.
*/
wxPoint RefPos( bool useMouse )
{
return useMouse ? m_MousePosition : m_Curseur;
}
#if defined (DEBUG)
/**
* Function GetClass
* returns the class name.
......@@ -285,7 +299,6 @@ public:
{
return wxT( "BASE_SCREEN" );
}
#endif
};
......
......@@ -66,16 +66,15 @@
#define ECO1_LAYER 0x04000000
#define ECO2_LAYER 0x08000000
#define EDGE_LAYER 0x10000000
#define intS_LAYER 0xE0000000 /* 4 bits MSB = autres flags */
// extra bits 0xE0000000
/* masques generaux : */
#define ALL_LAYERS 0x1FFFFFFF
#define ALL_NO_CU_LAYERS 0x1FFF0000
#define ALL_CU_LAYERS 0x0000FFFF
#define INTERNAL_LAYERS 0x00007FFE /* Bits layers internes */
#define EXTERNAL_LAYERS 0x00008001
/* Flags pour les couches cuivres */
#define LAYER_is_PLAN 0x80000000
/* Flags pour les couches cuivres */
/* numero des couches particulieres */
#define LAYER_CUIVRE_N 0
#define CUIVRE_N 0
......@@ -96,6 +95,7 @@
#define LAYER_CMP_N 15
#define CMP_N 15
#define NB_COPPER_LAYERS (CMP_N + 1)
#define FIRST_NO_COPPER_LAYER 16
#define ADHESIVE_N_CU 16
#define ADHESIVE_N_CMP 17
......@@ -112,6 +112,7 @@
#define EDGE_N 28
#define LAST_NO_COPPER_LAYER 28
#define NB_LAYERS (EDGE_N + 1)
#define LAYER_COUNT 32
/* Forme des segments (pistes, contours ..) ( parametre .shape ) */
......@@ -257,12 +258,13 @@ public:
/**
* Function FindModuleOrPad
* searches for either a module or a pad, giving precedence to pads.
* Function FindPadOrModule
* searches for either a pad or module, giving precedence to pads.
* @param refPos The wxPoint to hit-test.
* @param typeloc
* @return EDA_BaseStruct* - if a direct hit, else NULL.
*/
EDA_BaseStruct* FindModuleOrPad( const wxPoint& refPos );
EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer, int typeloc );
#endif
};
......@@ -375,9 +377,10 @@ public:
int DisplayModText;
bool DisplayPcbTrackFill; /* FALSE = sketch , TRUE = filled */
bool DisplayTrackIsol;
int m_DisplayViaMode; /* 0 do not show via hole,
* 1 show via hole for non default value
* 2 show all via hole */
* 1 show via hole for non default value
* 2 show all via hole */
bool DisplayPolarCood;
bool DisplayZones;
......
MAKEGTK = $(MAKE) -f makefile.gtk
KICAD_SUBDIRS = common 3d-viewer eeschema eeschema/plugins pcbnew cvpcb kicad gerbview
KICAD_SUBDIRS = common 3d-viewer pcbnew eeschema eeschema/plugins cvpcb kicad gerbview
KICAD_SUBDIRS_BIN = eeschema eeschema/plugins pcbnew cvpcb kicad gerbview
KICAD_SUBDIRS_RES = internat modules template library
KICAD_SUBDIRS_HELP = help
......
......@@ -289,58 +289,75 @@ void BOARD::Show( int nestLevel, std::ostream& os )
}
class ModuleOrPad : public INSPECTOR
// see pcbstruct.h
EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer, int typeloc )
{
public:
EDA_BaseStruct* found;
ModuleOrPad() :
found(0)
{
}
SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData )
class PadOrModule : public INSPECTOR
{
const wxPoint* refPos = (const wxPoint*) testData;
if( testItem->m_StructType == TYPEMODULE )
public:
EDA_BaseStruct* found;
int layer;
int typeloc;
PadOrModule( int alayer, int atypeloc ) :
found(0),
layer(alayer),
typeloc(atypeloc) {}
SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData )
{
/* not finished
if( testItem->HitTest( &refPos ) )
const wxPoint* refPos = (const wxPoint*) testData;
if( testItem->m_StructType == TYPEMODULE )
{
found = testItem;
return SEARCH_QUIT;
int mlayer = ((MODULE*)testItem)->m_Layer;
if( typeloc & MATCH_LAYER )
{
if( layer != mlayer )
return SEARCH_CONTINUE;
}
if( typeloc & VISIBLE_ONLY )
{
if( !IsModuleLayerVisible(mlayer) )
return SEARCH_CONTINUE;
}
if( testItem->HitTest( *refPos ) )
{
found = testItem;
return SEARCH_QUIT;
}
}
*/
}
else if( testItem->m_StructType == TYPEPAD )
{
/* not finished
if( testItem->HitTest( &refPos ) )
else if( testItem->m_StructType == TYPEPAD )
{
found = testItem;
return SEARCH_QUIT;
if( testItem->HitTest( *refPos ) )
{
found = testItem;
return SEARCH_QUIT;
}
}
*/
else { int debug=1; /* this should not happen, because of scanTypes */ }
return SEARCH_CONTINUE;
}
return SEARCH_CONTINUE;
}
};
};
// see pcbstruct.h
EDA_BaseStruct* BOARD::FindModuleOrPad( const wxPoint& refPos )
{
ModuleOrPad inspector;
PadOrModule inspector1( layer, MATCH_LAYER );
PadOrModule inspector2( layer, VISIBLE_ONLY );
static const KICAD_T scanTypes[] = { TYPEPAD, TYPEMODULE, EOT };
if( SEARCH_QUIT == IterateForward( m_Modules, &inspector, &refPos, scanTypes ) )
return inspector.found;
// search the current layer first
if( SEARCH_QUIT == IterateForward( m_Modules, &inspector1, &refPos, scanTypes ) )
return inspector1.found;
// if not found, set layer to don't care and search again
if( SEARCH_QUIT == IterateForward( m_Modules, &inspector2, &refPos, scanTypes ) )
return inspector2.found;
return NULL;
}
......
......@@ -163,7 +163,10 @@ void EDGE_MODULE::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
zoom = screen->GetZoom();
type_trace = m_Shape;
ux0 = m_Start.x - offset.x; uy0 = m_Start.y - offset.y;
ux0 = m_Start.x - offset.x;
uy0 = m_Start.y - offset.y;
dx = m_End.x - offset.x;
dy = m_End.y - offset.y;
......@@ -445,8 +448,29 @@ int EDGE_MODULE::ReadDescr( char* Line, FILE* File,
*/
void EDGE_MODULE::Show( int nestLevel, std::ostream& os )
{
const char* cp = "???";
switch( m_Shape )
{
case S_SEGMENT: cp = "line"; break;
case S_RECT: cp = "rect"; break;
case S_ARC: cp = "arc"; break;
case S_CIRCLE: cp = "circle"; break;
case S_ARC_RECT: cp = "arc_rect"; break;
case S_SPOT_OVALE: cp = "spot_oval"; break;
case S_SPOT_CIRCLE: cp = "spot_circle"; break;
case S_SPOT_RECT: cp = "spot_rect"; break;
case S_POLYGON: cp = "polygon"; break;
}
// for now, make it look like XML:
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << "/>\n";
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() <<
" type=\"" << cp << "\">\n";
NestedSpace( nestLevel+1, os ) << "<start" << m_Start0 << "/>\n";
NestedSpace( nestLevel+1, os ) << "<end" << m_End0 << "/>\n";
NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
}
#endif
......@@ -16,7 +16,7 @@ public:
int m_Angle; // pour les arcs de cercle: longueur de l'arc en 0,1 degres
int m_PolyCount; // For polygons : number of points (> 2)
int m_PolyCount; // For polygons: number of points (> 2)
int* m_PolyList; // For polygons: coord list (1 point = 2 coord)
// Coord are relative to Origin, orient 0
......@@ -50,7 +50,7 @@ public:
*/
virtual wxString GetClass() const
{
return wxT( "POLYLINE" );
return wxT( "GRAPHIC" );
// return wxT( "EDGE" ); ?
}
......
/*****************************************************************/
/* fonctions membres de la classe EQUIPOT et fonctions associes */
/* fonctions membres de la classe EQUIPOT et fonctions associs */
/*****************************************************************/
#include "fctsys.h"
......@@ -17,125 +17,132 @@
#include "protos.h"
/*********************************************************/
/* classe EQUIPOT: gestion des listes d'equipotentielles */
/*********************************************************/
/*********************************************************/
/* classe EQUIPOT: gestion des listes d'equipotentielles */
/*********************************************************/
/* Constructeur de la classe EQUIPOT */
EQUIPOT::EQUIPOT(EDA_BaseStruct * StructFather):
EDA_BaseStruct( StructFather, PCB_EQUIPOT_STRUCT_TYPE)
EQUIPOT::EQUIPOT( EDA_BaseStruct* StructFather ) :
EDA_BaseStruct( StructFather, PCB_EQUIPOT_STRUCT_TYPE )
{
m_NetCode = 0;
m_NbNodes = m_NbLink = m_NbNoconn = 0;
m_Masque_Layer = 0;
m_Masque_Plan = 0;
m_ForceWidth = 0;
m_PadzoneStart = NULL;// pointeur sur debut de liste pads du net
m_PadzoneEnd = NULL; // pointeur sur fin de liste pads du net
m_RatsnestStart = NULL; // pointeur sur debut de liste ratsnests du net
m_RatsnestEnd = NULL; // pointeur sur fin de liste ratsnests du net
m_NetCode = 0;
m_NbNodes = m_NbLink = m_NbNoconn = 0;
m_Masque_Layer = 0;
m_Masque_Plan = 0;
m_ForceWidth = 0;
m_PadzoneStart = NULL; // pointeur sur debut de liste pads du net
m_PadzoneEnd = NULL; // pointeur sur fin de liste pads du net
m_RatsnestStart = NULL; // pointeur sur debut de liste ratsnests du net
m_RatsnestEnd = NULL; // pointeur sur fin de liste ratsnests du net
}
/* destructeut */
EQUIPOT::~EQUIPOT(void)
/* destructeut */
EQUIPOT::~EQUIPOT( void )
{
}
void EQUIPOT::UnLink( void )
{
/* Modification du chainage arriere */
if( Pback )
{
if( Pback->m_StructType != TYPEPCB)
{
Pback->Pnext = Pnext;
}
else /* Le chainage arriere pointe sur la structure "Pere" */
{
((BOARD*)Pback)->m_Equipots = (EQUIPOT*)Pnext;
}
}
/* Modification du chainage avant */
if( Pnext) Pnext->Pback = Pback;
Pnext = Pback = NULL;
/* Modification du chainage arriere */
if( Pback )
{
if( Pback->m_StructType != TYPEPCB )
{
Pback->Pnext = Pnext;
}
else /* Le chainage arriere pointe sur la structure "Pere" */
{
( (BOARD*) Pback )->m_Equipots = (EQUIPOT*) Pnext;
}
}
/* Modification du chainage avant */
if( Pnext )
Pnext->Pback = Pback;
Pnext = Pback = NULL;
}
/*************************************************/
EQUIPOT * GetEquipot(BOARD * pcb, int netcode)
EQUIPOT* GetEquipot( BOARD* pcb, int netcode )
/**************************************************/
/*
retourne un pointeur sur la structure EQUIPOT de numero netcode
*/
* retourne un pointeur sur la structure EQUIPOT de numero netcode
*/
{
EQUIPOT * Equipot ;
if( netcode <= 0 ) return NULL;
Equipot = (EQUIPOT*)pcb->m_Equipots;
while ( Equipot )
{
if(Equipot->m_NetCode == netcode ) break;
Equipot = (EQUIPOT*) Equipot->Pnext;
}
return(Equipot);
EQUIPOT* Equipot;
if( netcode <= 0 )
return NULL;
Equipot = (EQUIPOT*) pcb->m_Equipots;
while( Equipot )
{
if( Equipot->m_NetCode == netcode )
break;
Equipot = (EQUIPOT*) Equipot->Pnext;
}
return Equipot;
}
/*********************************************************/
int EQUIPOT:: ReadEquipotDescr(FILE * File, int * LineNum)
int EQUIPOT:: ReadEquipotDescr( FILE* File, int* LineNum )
/*********************************************************/
/* Routine de lecture de 1 descr Equipotentielle.
retourne 0 si OK
1 si lecture incomplete
*/
* retourne 0 si OK
* 1 si lecture incomplete
*/
{
char Line[1024], Ltmp[1024];
int tmp;
while( GetLine(File, Line, LineNum ) )
{
if( strnicmp(Line,"$End",4) == 0 )return 0;
if( strncmp(Line,"Na", 2) == 0 ) /* Texte */
{
sscanf(Line+2," %d", &tmp);
m_NetCode = tmp;
ReadDelimitedText(Ltmp, Line + 2, sizeof(Ltmp) );
m_Netname = CONV_FROM_UTF8(Ltmp);
continue;
}
if( strncmp(Line,"Lw", 2) == 0 ) /* Texte */
{
sscanf(Line+2," %d", &tmp);
m_ForceWidth = tmp;
continue;
}
}
return 1;
char Line[1024], Ltmp[1024];
int tmp;
while( GetLine( File, Line, LineNum ) )
{
if( strnicmp( Line, "$End", 4 ) == 0 )
return 0;
if( strncmp( Line, "Na", 2 ) == 0 ) /* Texte */
{
sscanf( Line + 2, " %d", &tmp );
m_NetCode = tmp;
ReadDelimitedText( Ltmp, Line + 2, sizeof(Ltmp) );
m_Netname = CONV_FROM_UTF8( Ltmp );
continue;
}
if( strncmp( Line, "Lw", 2 ) == 0 ) /* Texte */
{
sscanf( Line + 2, " %d", &tmp );
m_ForceWidth = tmp;
continue;
}
}
return 1;
}
/********************************************/
int EQUIPOT:: WriteEquipotDescr(FILE * File)
int EQUIPOT:: WriteEquipotDescr( FILE* File )
/********************************************/
{
if( GetState(DELETED) ) return(0);
fprintf( File,"$EQUIPOT\n");
fprintf( File,"Na %d \"%.16s\"\n", m_NetCode, CONV_TO_UTF8(m_Netname) );
fprintf( File,"St %s\n","~");
if( m_ForceWidth) fprintf( File,"Lw %d\n",m_ForceWidth );
fprintf( File,"$EndEQUIPOT\n");
return(1);
if( GetState( DELETED ) )
return 0;
fprintf( File, "$EQUIPOT\n" );
fprintf( File, "Na %d \"%.16s\"\n", m_NetCode, CONV_TO_UTF8( m_Netname ) );
fprintf( File, "St %s\n", "~" );
if( m_ForceWidth )
fprintf( File, "Lw %d\n", m_ForceWidth );
fprintf( File, "$EndEQUIPOT\n" );
return 1;
}
......@@ -1146,6 +1146,29 @@ void MODULE::Display_Infos( WinEDA_BasePcbFrame* frame )
}
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool MODULE::HitTest( const wxPoint& refPos )
{
/* Calcul des coord souris dans le repere module */
int spot_cX = refPos.x - m_Pos.x;
int spot_cY = refPos.y - m_Pos.y;
RotatePoint( &spot_cX, &spot_cY, -m_Orient );
/* la souris est-elle dans ce rectangle : */
if( m_BoundaryBox.Inside( spot_cX, spot_cY ) )
return true;
return false;
}
#if defined(DEBUG)
/**
* Function Show
......@@ -1157,29 +1180,29 @@ void MODULE::Display_Infos( WinEDA_BasePcbFrame* frame )
void MODULE::Show( int nestLevel, std::ostream& os )
{
// for now, make it look like XML, expand on this later.
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() <<
// " ref=\"" << m_Reference->m_Text.mb_str() <<
// "\" value=\"" << m_Value->m_Text.mb_str() << '"' <<
" ref=\"" << m_Reference->m_Text.mb_str() << '"' <<
" value=\"" << m_Value->m_Text.mb_str() << '"' <<
">\n";
EDA_BaseStruct* p;
p = m_Reference;
for( ; p; p = p->Pnext )
p->Show( nestLevel+1, os );
NestedSpace( nestLevel+1, os ) <<
"<boundingBox" << m_BoundaryBox.m_Pos << m_BoundaryBox.m_Size << "/>\n";
p = m_Value;
for( ; p; p = p->Pnext )
p->Show( nestLevel+1, os );
NestedSpace( nestLevel+1, os ) << "<orientation tenths=\"" << m_Orient << "\"/>\n";
EDA_BaseStruct* p;
NestedSpace( nestLevel+1, os ) << "<pads>\n";
p = m_Pads;
for( ; p; p = p->Pnext )
p->Show( nestLevel+1, os );
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</pads>\n";
NestedSpace( nestLevel+1, os ) << "<drawings>\n";
p = m_Drawings;
for( ; p; p = p->Pnext )
p->Show( nestLevel+1, os );
p->Show( nestLevel+2, os );
NestedSpace( nestLevel+1, os ) << "</drawings>\n";
p = m_Son;
for( ; p; p = p->Pnext )
......@@ -1207,13 +1230,14 @@ SEARCH_RESULT MODULE::Visit( INSPECTOR* inspector, const void* testData,
}
else if( stype == TYPETEXTEMODULE )
{
// iterate over m_Reference
if( SEARCH_QUIT == IterateForward( m_Reference, inspector,
testData, scanTypes ) )
if( SEARCH_QUIT == inspector->Inspect( m_Reference, testData ) )
return SEARCH_QUIT;
// iterate over m_Value
if( SEARCH_QUIT == IterateForward( m_Value, inspector,
if( SEARCH_QUIT == inspector->Inspect( m_Value, testData ) )
return SEARCH_QUIT;
// m_Drawings can hold TYPETEXTMODULE also?
if( SEARCH_QUIT == IterateForward( m_Drawings, inspector,
testData, scanTypes ) )
return SEARCH_QUIT;
}
......
......@@ -133,6 +133,16 @@ public:
/* miscellaneous */
void Display_Infos( WinEDA_BasePcbFrame* frame );
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& refPos );
#if defined(DEBUG)
/**
......
......@@ -87,11 +87,16 @@ const wxPoint D_PAD::ReturnShapePos( void )
{
if( (m_Offset.x == 0) && (m_Offset.y == 0) )
return m_Pos;
wxPoint shape_pos;
int dX, dY;
dX = m_Offset.x; dY = m_Offset.y;
RotatePoint( &dX, &dY, m_Orient );
shape_pos.x = m_Pos.x + dX; shape_pos.y = m_Pos.y + dY;
shape_pos.x = m_Pos.x + dX;
shape_pos.y = m_Pos.y + dY;
return shape_pos;
}
......@@ -507,6 +512,7 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int
}
GRSetDrawMode( DC, draw_mode );
/* Trace du symbole "No connect" ( / ou \ ou croix en X) si necessaire : */
if( m_Netname.IsEmpty() && DisplayOpt.DisplayPadNoConn )
{
......@@ -520,20 +526,26 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int
GRLine( &panel->m_ClipBox, DC, cx0 + dx0, cy0 - dx0,
cx0 - dx0, cy0 + dx0, 0, nc_color );
}
/* Trace de la reference */
if( !frame->m_DisplayPadNum )
return;
dx = min( m_Size.x, m_Size.y ); /* dx = text size */
if( (dx / zoom) > 12 ) /* size must be enought to draw 2 chars */
{
wxString buffer;
ReturnStringPadName( buffer );
dy = buffer.Len();
/* Draw text with an angle between -90 deg and + 90 deg */
NORMALIZE_ANGLE_90( angle );
if( dy < 2 )
dy = 2; /* text min size is 2 char */
dx = (dx * 9 ) / (dy * 13 ); /* Text size ajusted to pad size */
DrawGraphicText( panel, DC, wxPoint( ux0, uy0 ),
WHITE, buffer, angle, wxSize( dx, dx ),
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER );
......@@ -579,6 +591,7 @@ int D_PAD::ReadDescr( FILE* File, int* LineNum )
if( *PtLine )
PtLine++;
memset( m_Padname, 0, sizeof(m_Padname) );
while( (*PtLine != '"') && *PtLine )
{
......@@ -629,6 +642,7 @@ int D_PAD::ReadDescr( FILE* File, int* LineNum )
&m_Offset.x, &m_Offset.y, BufCar, &dx, &dy );
m_Drill.y = m_Drill.x;
m_DrillShape = CIRCLE;
if( nn >= 6 ) // Drill shape = OVAL ?
{
if( BufCar[0] == 'O' )
......@@ -944,6 +958,54 @@ void D_PAD::Display_Infos( WinEDA_BasePcbFrame* frame )
Affiche_1_Parametre( frame, pos, _( "Y pos" ), Line, BLUE );
}
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param ref_pos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool D_PAD::HitTest( const wxPoint& ref_pos )
{
int deltaX, deltaY;
int dx, dy;
double dist;
wxPoint shape_pos = ReturnShapePos();
deltaX = ref_pos.x - shape_pos.x;
deltaY = ref_pos.y - shape_pos.y;
/* Test rapide: le point a tester doit etre a l'interieur du cercle exinscrit ... */
if( (abs( deltaX ) > m_Rayon )
|| (abs( deltaY ) > m_Rayon) )
return false;
/* calcul des demi dim dx et dy */
dx = m_Size.x >> 1; // dx also is the radius for rounded pads
dy = m_Size.y >> 1;
/* localisation ? */
switch( m_PadShape & 0x7F )
{
case CIRCLE:
dist = hypot( deltaX, deltaY );
if( (int) ( round( dist ) ) <= dx )
return true;
break;
default:
/* calcul des coord du point test dans le repere du Pad */
RotatePoint( &deltaX, &deltaY, -m_Orient );
if( (abs( deltaX ) <= dx ) && (abs( deltaY ) <= dy) )
return true;
break;
}
return false;
}
#if defined(DEBUG)
/**
* Function Show
......
......@@ -29,11 +29,11 @@ public:
char m_Padname[4]; /* nom (numero) de la pastille (assimilable a un long)*/
};
wxString m_Netname; /* Net Name */
wxString m_Netname; /* Net Name */
int m_Masque_Layer; // (Bit a Bit :1= cuivre, 15= cmp,
// 2..14 = interne
// 16 .. 31 = couches non cuivre
int m_Masque_Layer; // (Bit a Bit :1= cuivre, 15= cmp,
// 2..14 = interne
// 16 .. 31 = couches non cuivre
int m_PadShape; // forme CERCLE, RECT, OVALE, TRAPEZE ou libre
int m_DrillShape; // forme CERCLE, OVAL
......@@ -91,7 +91,15 @@ public:
// de la forme (pastilles excentrees)
void Display_Infos( WinEDA_BasePcbFrame* frame );
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& refPos );
#if defined(DEBUG)
/**
* Function GetClass
......
......@@ -162,11 +162,10 @@ void TEXTE_PCB::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
void TEXTE_PCB::Show( int nestLevel, std::ostream& os )
{
// for now, make it look like XML:
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
NestedSpace( nestLevel+1, os ) << m_Text.mb_str() << '\n';
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() <<
" string=\"" << m_Text.mb_str() << "\"/>\n";
NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
// NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
}
#endif
......@@ -305,12 +305,10 @@ int TEXTE_MODULE::GetDrawRotation( void )
*/
void TEXTE_MODULE::Show( int nestLevel, std::ostream& os )
{
// for now, make it look like XML, expand on this later.
// for now, make it look like XML:
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() <<
" string=\"" << m_Text.mb_str() << "\"/>\n";
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n";
NestedSpace( nestLevel+1, os ) << m_Text.mb_str() << '\n';
NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
// NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
}
#endif
......@@ -125,7 +125,14 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
break;
case ID_PCB_SHOW_1_RATSNEST_BUTT:
#if defined(DEBUG)
DrawStruct = m_Pcb->FindPadOrModule(
GetScreen()->RefPos(true),
GetScreen()->m_Active_Layer,
VISIBLE_ONLY );
#else
DrawStruct = PcbGeneralLocateAndDisplay();
#endif
Show_1_Ratsnest( DrawStruct, DC );
break;
......@@ -454,11 +461,12 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_OPEN_MODULE_EDITOR:
if( m_Parent->m_ModuleEditFrame == NULL )
{
m_Parent->m_ModuleEditFrame = new WinEDA_ModuleEditFrame( this,
m_Parent, _( "Module Editor" ),
wxPoint( -1,
-1 ),
wxSize( 600, 400 ) );
m_Parent->m_ModuleEditFrame =
new WinEDA_ModuleEditFrame( this,
m_Parent, _( "Module Editor" ),
wxPoint( -1,
-1 ),
wxSize( 600, 400 ) );
m_Parent->m_ModuleEditFrame->Show( TRUE );
m_Parent->m_ModuleEditFrame->Zoom_Automatique( TRUE );
}
......@@ -601,8 +609,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_END_LINE:
DrawPanel->MouseToCursorSchema();
// EndSegment(&dc);
// EndSegment(&dc);
break;
case ID_POPUP_PCB_EDIT_TRACK:
......
......@@ -341,7 +341,8 @@ void WinEDA_PcbFrame::Show_1_Ratsnest( EDA_BaseStruct* item, wxDC* DC )
{
if( item->m_StructType == TYPETEXTEMODULE )
{
Module = (MODULE*) item->m_Parent;
if( item->m_Parent && (item->m_Parent->m_StructType == TYPEMODULE) )
Module = (MODULE*) item->m_Parent;
}
else if( item->m_StructType == TYPEMODULE )
......
......@@ -32,30 +32,7 @@ EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch, int t
*/
wxPoint inline RefPos( int typeloc )
{
if( typeloc & CURSEUR_OFF_GRILLE )
return ActiveScreen->m_MousePosition;
else
return ActiveScreen->m_Curseur;
}
/**
* Function IsModuleLayerVisible
* expects either of the two layers on which a module can reside, and returns
* whether that layer is visible.
* @param layer One of the two allowed layers for modules: CMP_N or CUIVRE_N
* @return bool - true if the layer is visible, else false.
*/
bool inline IsModuleLayerVisible( int layer )
{
if( layer==CMP_N )
return DisplayOpt.Show_Modules_Cmp;
else if( layer==CUIVRE_N )
return DisplayOpt.Show_Modules_Cu;
else
return true;
return ActiveScreen->RefPos( (typeloc & CURSEUR_OFF_GRILLE) != 0 );
}
......@@ -344,6 +321,7 @@ EDGE_MODULE* Locate_Edge_Module( MODULE* module, int typeloc )
{
if( PtStruct->m_StructType != TYPEEDGEMODULE )
continue;
edge_mod = (EDGE_MODULE*) PtStruct;
type_trace = edge_mod->m_Shape;
ux0 = edge_mod->m_Start.x; uy0 = edge_mod->m_Start.y;
......@@ -418,6 +396,7 @@ EDA_BaseStruct* Locate_Cotation( BOARD* Pcb, int LayerSearch, int typeloc )
{
if( PtStruct->m_StructType != TYPECOTATION )
continue;
Cotation = (COTATION*) PtStruct;
if( (Cotation->m_Layer != LayerSearch) && (LayerSearch != -1) )
continue;
......@@ -426,7 +405,10 @@ EDA_BaseStruct* Locate_Cotation( BOARD* Pcb, int LayerSearch, int typeloc )
pt_txt = Cotation->m_Text;
if( pt_txt )
{
if( pt_txt->HitTest( ref_pos ) )
// because HitTest() is present in both base classes of TEXTE_PCB
// use a dis-ambiguating cast to tell compiler which HitTest()
// to call.
if( static_cast<EDA_TextStruct*>(pt_txt)->HitTest( ref_pos ) )
return PtStruct;
}
......@@ -666,52 +648,23 @@ D_PAD* Locate_Pads( MODULE* module, int masque_layer, int typeloc )
D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int masque_layer )
{
D_PAD* pt_pad;
int deltaX, deltaY;
wxPoint shape_pos;
double dist;
pt_pad = module->m_Pads;
D_PAD* pt_pad = module->m_Pads;
for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext )
{
shape_pos = pt_pad->ReturnShapePos();
/*
wxPoint shape_pos = ReturnShapePos();
why the global ux0?
ux0 = shape_pos.x;
uy0 = shape_pos.y; /* pos x,y du centre du pad */
deltaX = ref_pos.x - ux0;
deltaY = ref_pos.y - uy0;
/* Test rapide: le point a tester doit etre a l'interieur du cercle
* exinscrit ... */
if( (abs( deltaX ) > pt_pad->m_Rayon )
|| (abs( deltaY ) > pt_pad->m_Rayon) )
continue;
uy0 = shape_pos.y; // pos x,y du centre du pad
*/
/* ... et sur la bonne couche */
if( (pt_pad->m_Masque_Layer & masque_layer) == 0 )
continue;
/* calcul des demi dim dx et dy */
dx = pt_pad->m_Size.x >> 1; // dx also is the radius for rounded pads
dy = pt_pad->m_Size.y >> 1;
/* localisation ? */
switch( pt_pad->m_PadShape & 0x7F )
{
case CIRCLE:
dist = hypot( deltaX, deltaY );
if( (int) ( round( dist ) ) <= dx )
return pt_pad;
break;
default:
/* calcul des coord du point test dans le repere du Pad */
RotatePoint( &deltaX, &deltaY, -pt_pad->m_Orient );
if( (abs( deltaX ) <= dx ) && (abs( deltaY ) <= dy) )
return pt_pad;
break;
}
if( pt_pad->HitTest( ref_pos ) )
return pt_pad;
}
return NULL;
......@@ -743,17 +696,8 @@ MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc )
pt_module = Pcb->m_Modules;
for( ; pt_module; pt_module = (MODULE*) pt_module->Pnext )
{
/* calcul des dimensions du cadre :*/
lx = pt_module->m_BoundaryBox.GetWidth();
ly = pt_module->m_BoundaryBox.GetHeight();
/* Calcul des coord souris dans le repere module */
spot_cX = ref_pos.x - pt_module->m_Pos.x;
spot_cY = ref_pos.y - pt_module->m_Pos.y;
RotatePoint( &spot_cX, &spot_cY, -pt_module->m_Orient );
/* la souris est-elle dans ce rectangle : */
if( !pt_module->m_BoundaryBox.Inside( spot_cX, spot_cY ) )
// is the ref point within the module's bounds?
if( !pt_module->HitTest( ref_pos ) )
continue;
// if caller wants to ignore locked modules, and this one is locked, skip it.
......@@ -773,13 +717,18 @@ MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc )
else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP )
layer = CMP_N;
/* calcul des dimensions du cadre :*/
lx = pt_module->m_BoundaryBox.GetWidth();
ly = pt_module->m_BoundaryBox.GetHeight();
if( ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer == layer )
{
if( min( lx, ly ) <= min_dim )
{
/* meilleure empreinte localisee sur couche active */
module = pt_module; min_dim = min( lx, ly );
module = pt_module;
min_dim = min( lx, ly );
}
}
else if( !(typeloc & MATCH_LAYER)
......@@ -1155,11 +1104,18 @@ TEXTE_PCB* Locate_Texte_Pcb( EDA_BaseStruct* PtStruct, int LayerSearch, int type
{
if( PtStruct->m_StructType != TYPETEXTE )
continue;
TEXTE_PCB* pt_txt_pcb = (TEXTE_PCB*) PtStruct;
if( pt_txt_pcb->HitTest( ref ) )
if( pt_txt_pcb->m_Layer == LayerSearch )
{
if( pt_txt_pcb->m_Layer == LayerSearch )
// because HitTest() is present in both base classes of TEXTE_PCB
// use a dis-ambiguating cast to tell compiler which HitTest()
// to call.
if( static_cast<EDA_TextStruct*>(pt_txt_pcb)->HitTest( ref ) )
{
return pt_txt_pcb;
}
}
}
......
/****************************************************/
/* Gestion des composants specifiques aux microndes */
/****************************************************/
/****************************************************/
/* Gestion des composants specifiques aux microndes */
/****************************************************/
/* Fichier MUONDE.CPP */
/* Fichier MUONDE.CPP */
#include "fctsys.h"
#include "gr_basic.h"
......@@ -20,688 +20,717 @@
/* fonctions importees */
/* Fonctions locales */
//static void Exit_Muonde(WinEDA_DrawFrame * frame, wxDC *DC);
/* Variables locales : */
#define COEFF_COUNT 6
double * PolyEdges;
int PolyEdgesCount;
double ShapeScaleX, ShapeScaleY;
wxSize ShapeSize;
int PolyShapeType;
double* PolyEdges;
int PolyEdgesCount;
double ShapeScaleX, ShapeScaleY;
wxSize ShapeSize;
int PolyShapeType;
#include "gen_self.h"
/***************************************************************************/
MODULE * WinEDA_PcbFrame::Create_MuWaveBasicShape(wxDC * DC,
const wxString & name, int pad_count)
MODULE* WinEDA_PcbFrame::Create_MuWaveBasicShape( wxDC* DC,
const wxString& name, int pad_count )
/***************************************************************************/
/* Create a footprint with pad_count pads for micro wave applications
This footprint has pad_count pads:
SMD, rectangular, H size = V size = current track width.
*/
* This footprint has pad_count pads:
* SMD, rectangular, H size = V size = current track width.
*/
{
MODULE * Module;
int pad_num = 1;
wxString Line;
Module = Create_1_Module(DC, name);
if ( Module == NULL ) return NULL;
Module->m_TimeStamp = GetTimeStamp();
Module->m_Value->m_Size = wxSize(30,30);
Module->m_Value->m_Pos0.y = -30;
Module->m_Value->m_Pos.y += Module->m_Value->m_Pos0.y;
Module->m_Reference->m_Size = wxSize(30,30);
Module->m_Reference->m_Pos0.y = 30;
Module->m_Reference->m_Pos.y += Module->m_Reference->m_Pos0.y;
/* Creation des pastilles formant le gap */
while ( pad_count -- )
{
D_PAD* pad;
pad = new D_PAD(Module);
pad->Pback = Module;
if ( Module->m_Pads == NULL )
{
Module->m_Pads = pad;
}
else
{
Module->m_Pads->Pback = pad;
pad->Pnext = Module->m_Pads;
Module->m_Pads = pad;
}
pad->m_Size.x = pad->m_Size.y = g_DesignSettings.m_CurrentTrackWidth;
pad->m_Pos = Module->m_Pos;
pad->m_PadShape = RECT;
pad->m_Attribut = SMD;
pad->m_Masque_Layer = CMP_LAYER;
Line.Printf( wxT("%d"), pad_num);
pad->SetPadName(Line);
pad_num++;
}
if (DC) Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ;
return Module;
MODULE* Module;
int pad_num = 1;
wxString Line;
Module = Create_1_Module( DC, name );
if( Module == NULL )
return NULL;
Module->m_TimeStamp = GetTimeStamp();
Module->m_Value->m_Size = wxSize( 30, 30 );
Module->m_Value->m_Pos0.y = -30;
Module->m_Value->m_Pos.y += Module->m_Value->m_Pos0.y;
Module->m_Reference->m_Size = wxSize( 30, 30 );
Module->m_Reference->m_Pos0.y = 30;
Module->m_Reference->m_Pos.y += Module->m_Reference->m_Pos0.y;
/* Creation des pastilles formant le gap */
while( pad_count-- )
{
D_PAD* pad;
pad = new D_PAD( Module );
pad->Pback = Module;
if( Module->m_Pads == NULL )
{
Module->m_Pads = pad;
}
else
{
Module->m_Pads->Pback = pad;
pad->Pnext = Module->m_Pads;
Module->m_Pads = pad;
}
pad->m_Size.x = pad->m_Size.y = g_DesignSettings.m_CurrentTrackWidth;
pad->m_Pos = Module->m_Pos;
pad->m_PadShape = RECT;
pad->m_Attribut = SMD;
pad->m_Masque_Layer = CMP_LAYER;
Line.Printf( wxT( "%d" ), pad_num );
pad->SetPadName( Line );
pad_num++;
}
if( DC )
Module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
return Module;
}
#if 0
/**********************************************************/
static void Exit_Muonde(WinEDA_DrawFrame * frame, wxDC *DC )
static void Exit_Muonde( WinEDA_DrawFrame* frame, wxDC* DC )
/**********************************************************/
{
MODULE * Module = (MODULE*) frame->m_CurrentScreen->m_CurrentItem;
if( Module )
{
if ( Module->m_Flags & IS_NEW)
{
Module->Draw(frame->DrawPanel, DC, wxPoint(0,0), GR_XOR) ;
DeleteStructure( Module);
}
else
{
Module->Draw(frame->DrawPanel, DC, wxPoint(0,0), GR_XOR) ;
}
}
frame->DrawPanel->ManageCurseur = NULL;
frame->DrawPanel->ForceCloseManageCurseur = NULL;
frame->m_CurrentScreen->m_CurrentItem = NULL;
MODULE* Module = (MODULE*) frame->m_CurrentScreen->m_CurrentItem;
if( Module )
{
if( Module->m_Flags & IS_NEW )
{
Module->Draw( frame->DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
DeleteStructure( Module );
}
else
{
Module->Draw( frame->DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
}
}
frame->DrawPanel->ManageCurseur = NULL;
frame->DrawPanel->ForceCloseManageCurseur = NULL;
frame->m_CurrentScreen->m_CurrentItem = NULL;
}
#endif
/***************************************************************************/
MODULE * WinEDA_PcbFrame::Create_MuWaveComponent(wxDC * DC, int shape_type)
MODULE* WinEDA_PcbFrame::Create_MuWaveComponent( wxDC* DC, int shape_type )
/***************************************************************************/
/* Create a module "GAP" or "STUB"
This a "gap" or "stub" used in micro wave designs
This modue has 2 pads:
SMD, rectangular, H size = V size = current track width.
the "gap" is isolation created between this 2 pads
*/
* This a "gap" or "stub" used in micro wave designs
* This modue has 2 pads:
* SMD, rectangular, H size = V size = current track width.
* the "gap" is isolation created between this 2 pads
*/
{
int gap_size, oX, ii;
float fcoeff;
D_PAD* pt_pad;
MODULE * Module;
wxString msg, cmp_name;
int pad_count = 2;
int angle = 0;
bool abort;
/* Entree de la longueur desiree du gap*/
gap_size = g_DesignSettings.m_CurrentTrackWidth; // Valeur raisonnable
switch ( shape_type )
{
case 0:
msg = _("Gap");
cmp_name = wxT("GAP");
break;
case 1:
msg = _("Stub");
cmp_name = wxT("STUB");
pad_count = 2;
break;
case 2:
msg = _("Arc Stub");
cmp_name = wxT("ASTUB");
pad_count = 1;
break;
default:
msg = wxT("???");
break;
}
wxString value;
if( g_UnitMetric)
{
fcoeff = 10000.0/25.4 ;
value.Printf( wxT("%2.4f"),gap_size / fcoeff);
msg += _(" (mm):");
abort = Get_Message(msg,value, this);
}
else
{
fcoeff = 10000.0 ;
value.Printf( wxT("%2.3f"),gap_size / fcoeff);
msg += _(" (inch):");
abort = Get_Message(msg, value, this);
}
double fval;
if ( ! value.ToDouble(&fval) )
{
DisplayError(this, _("Incorrect number, abort"));
abort = TRUE;
}
gap_size = ABS( (int) round( fval * fcoeff ));
if ( ! abort && (shape_type == 2) )
{
fcoeff = 10.0 ;
value.Printf( wxT("%3.1f"),angle / fcoeff);
msg = _("Angle (0.1deg):");
abort = Get_Message(msg, value, this);
if ( ! value.ToDouble(&fval) )
{
DisplayError(this, _("Incorrect number, abort"));
abort = TRUE;
}
angle = ABS( (int) round( fval * fcoeff ));
if ( angle > 1800 ) angle = 1800;
}
if (abort)
{
DrawPanel->MouseToCursorSchema();
return NULL;
}
Module = Create_MuWaveBasicShape(NULL, cmp_name, pad_count);
pt_pad = Module->m_Pads;
switch ( shape_type )
{
case 0: //Gap :
oX = pt_pad->m_Pos0.x = - (gap_size + pt_pad->m_Size.x) / 2;
pt_pad->m_Pos.x += pt_pad->m_Pos0.x;
pt_pad = (D_PAD *) pt_pad->Pnext;
pt_pad->m_Pos0.x = oX + gap_size + pt_pad->m_Size.x;
pt_pad->m_Pos.x += pt_pad->m_Pos0.x;
break;
case 1: //Stub :
pt_pad->SetPadName( wxT("1"));
pt_pad = (D_PAD *) pt_pad->Pnext;
pt_pad->m_Pos0.y = -(gap_size + pt_pad->m_Size.y) /2;
pt_pad->m_Size.y = gap_size;
pt_pad->m_Pos.y += pt_pad->m_Pos0.y;
break;
case 2: //Arc Stub :
{
EDGE_MODULE * edge; int * ptr, theta;
ii = angle / 50;
edge = new EDGE_MODULE(Module);
Module->m_Drawings = edge;
edge->Pback = Module;
edge->m_Shape = S_POLYGON;
edge->m_Layer = LAYER_CMP_N;
edge->m_PolyCount = ii + 3;
edge->m_PolyList = (int*) MyMalloc( edge->m_PolyCount * 2 * sizeof(int) );
ptr = edge->m_PolyList;
edge->m_Start0.y = - pt_pad->m_Size.y / 2;
* ptr = 0; ptr++;
* ptr = 0; ptr++;
theta = - angle/2;
for ( ii = 1; ii < edge->m_PolyCount - 1; ii ++)
{
int x, y;
x = 0; y = - gap_size;
RotatePoint(&x, &y, theta);
* ptr = x; ptr++; *ptr = y; ptr++;
theta += 50;
if ( theta > angle/2) theta = angle/2;
}
*ptr = edge->m_PolyList[0]; ptr++;
*ptr = edge->m_PolyList[1];
break;
}
default:
break;
}
Module->Set_Rectangle_Encadrement();
Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ;
DrawPanel->MouseToCursorSchema();
m_Pcb->m_Status_Pcb = 0 ;
m_CurrentScreen->SetModify();
return Module;
int gap_size, oX, ii;
float fcoeff;
D_PAD* pt_pad;
MODULE* Module;
wxString msg, cmp_name;
int pad_count = 2;
int angle = 0;
bool abort;
/* Entree de la longueur desiree du gap*/
gap_size = g_DesignSettings.m_CurrentTrackWidth; // Valeur raisonnable
switch( shape_type )
{
case 0:
msg = _( "Gap" );
cmp_name = wxT( "GAP" );
break;
case 1:
msg = _( "Stub" );
cmp_name = wxT( "STUB" );
pad_count = 2;
break;
case 2:
msg = _( "Arc Stub" );
cmp_name = wxT( "ASTUB" );
pad_count = 1;
break;
default:
msg = wxT( "???" );
break;
}
wxString value;
if( g_UnitMetric )
{
fcoeff = 10000.0 / 25.4;
value.Printf( wxT( "%2.4f" ), gap_size / fcoeff );
msg += _( " (mm):" );
abort = Get_Message( msg, value, this );
}
else
{
fcoeff = 10000.0;
value.Printf( wxT( "%2.3f" ), gap_size / fcoeff );
msg += _( " (inch):" );
abort = Get_Message( msg, value, this );
}
double fval;
if( !value.ToDouble( &fval ) )
{
DisplayError( this, _( "Incorrect number, abort" ) );
abort = TRUE;
}
gap_size = ABS( (int) round( fval * fcoeff ) );
if( !abort && (shape_type == 2) )
{
fcoeff = 10.0;
value.Printf( wxT( "%3.1f" ), angle / fcoeff );
msg = _( "Angle (0.1deg):" );
abort = Get_Message( msg, value, this );
if( !value.ToDouble( &fval ) )
{
DisplayError( this, _( "Incorrect number, abort" ) );
abort = TRUE;
}
angle = ABS( (int) round( fval * fcoeff ) );
if( angle > 1800 )
angle = 1800;
}
if( abort )
{
DrawPanel->MouseToCursorSchema();
return NULL;
}
Module = Create_MuWaveBasicShape( NULL, cmp_name, pad_count );
pt_pad = Module->m_Pads;
switch( shape_type )
{
case 0: //Gap :
oX = pt_pad->m_Pos0.x = -(gap_size + pt_pad->m_Size.x) / 2;
pt_pad->m_Pos.x += pt_pad->m_Pos0.x;
pt_pad = (D_PAD*) pt_pad->Pnext;
pt_pad->m_Pos0.x = oX + gap_size + pt_pad->m_Size.x;
pt_pad->m_Pos.x += pt_pad->m_Pos0.x;
break;
case 1: //Stub :
pt_pad->SetPadName( wxT( "1" ) );
pt_pad = (D_PAD*) pt_pad->Pnext;
pt_pad->m_Pos0.y = -(gap_size + pt_pad->m_Size.y) / 2;
pt_pad->m_Size.y = gap_size;
pt_pad->m_Pos.y += pt_pad->m_Pos0.y;
break;
case 2: //Arc Stub :
{
EDGE_MODULE* edge; int* ptr, theta;
ii = angle / 50;
edge = new EDGE_MODULE( Module );
Module->m_Drawings = edge;
edge->Pback = Module;
edge->m_Shape = S_POLYGON;
edge->m_Layer = LAYER_CMP_N;
edge->m_PolyCount = ii + 3;
edge->m_PolyList = (int*) MyMalloc( edge->m_PolyCount * 2 * sizeof(int) );
ptr = edge->m_PolyList;
edge->m_Start0.y = -pt_pad->m_Size.y / 2;
*ptr = 0; ptr++;
*ptr = 0; ptr++;
theta = -angle / 2;
for( ii = 1; ii < edge->m_PolyCount - 1; ii++ )
{
int x, y;
x = 0; y = -gap_size;
RotatePoint( &x, &y, theta );
*ptr = x; ptr++; *ptr = y; ptr++;
theta += 50;
if( theta > angle / 2 )
theta = angle / 2;
}
*ptr = edge->m_PolyList[0]; ptr++;
*ptr = edge->m_PolyList[1];
break;
}
default:
break;
}
Module->Set_Rectangle_Encadrement();
Module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
DrawPanel->MouseToCursorSchema();
m_Pcb->m_Status_Pcb = 0;
m_CurrentScreen->SetModify();
return Module;
}
/**************** Polygon Shapes ***********************/
enum id_mw_cmd
{
ID_ACCEPT_OPT = 1000,
ID_CANCEL_OPT,
ID_READ_SHAPE_FILE
enum id_mw_cmd {
ID_ACCEPT_OPT = 1000,
ID_CANCEL_OPT,
ID_READ_SHAPE_FILE
};
/*************************************************/
class WinEDA_SetParamShapeFrame: public wxDialog
class WinEDA_SetParamShapeFrame : public wxDialog
/*************************************************/
/* Reglages des parametres des forme polynomiales
*/
*/
{
private:
WinEDA_PcbFrame * m_Parent;
wxRadioBox * m_ShapeOptionCtrl;
WinEDA_SizeCtrl * m_SizeCtrl;
WinEDA_PcbFrame* m_Parent;
wxRadioBox* m_ShapeOptionCtrl;
WinEDA_SizeCtrl* m_SizeCtrl;
public:
// Constructor and destructor
WinEDA_SetParamShapeFrame(WinEDA_PcbFrame *parent,const wxPoint& pos);
~WinEDA_SetParamShapeFrame(void) {};
private:
void OnCloseWindow(wxCloseEvent & event);
void OnCancel(wxCommandEvent& event);
void ReadDataShapeDescr(wxCommandEvent& event);
void AcceptOptions(wxCommandEvent& event);
// Constructor and destructor
WinEDA_SetParamShapeFrame( WinEDA_PcbFrame* parent, const wxPoint& pos );
~WinEDA_SetParamShapeFrame( void ) { };
DECLARE_EVENT_TABLE()
private:
void OnCloseWindow( wxCloseEvent& event );
void OnCancel( wxCommandEvent& event );
void ReadDataShapeDescr( wxCommandEvent& event );
void AcceptOptions( wxCommandEvent& event );
DECLARE_EVENT_TABLE()
};
/* Construction de la table des evenements pour WinEDA_SetParamShapeFrame */
BEGIN_EVENT_TABLE(WinEDA_SetParamShapeFrame, wxDialog)
EVT_BUTTON(ID_ACCEPT_OPT, WinEDA_SetParamShapeFrame::AcceptOptions)
EVT_BUTTON(ID_CANCEL_OPT, WinEDA_SetParamShapeFrame::OnCancel)
EVT_BUTTON(ID_READ_SHAPE_FILE, WinEDA_SetParamShapeFrame::ReadDataShapeDescr)
BEGIN_EVENT_TABLE( WinEDA_SetParamShapeFrame, wxDialog )
EVT_BUTTON( ID_ACCEPT_OPT, WinEDA_SetParamShapeFrame::AcceptOptions )
EVT_BUTTON( ID_CANCEL_OPT, WinEDA_SetParamShapeFrame::OnCancel )
EVT_BUTTON( ID_READ_SHAPE_FILE, WinEDA_SetParamShapeFrame::ReadDataShapeDescr )
END_EVENT_TABLE()
/*************************************************/
/* Constructeur de WinEDA_SetParamShapeFrame */
/************************************************/
/*************************************************/
/* Constructeur de WinEDA_SetParamShapeFrame */
/************************************************/
WinEDA_SetParamShapeFrame::WinEDA_SetParamShapeFrame(WinEDA_PcbFrame *parent,
const wxPoint& framepos):
wxDialog(parent, -1, _("Complex shape"), framepos, wxSize(350, 280),
DIALOG_STYLE )
WinEDA_SetParamShapeFrame::WinEDA_SetParamShapeFrame( WinEDA_PcbFrame* parent,
const wxPoint& framepos ) :
wxDialog( parent, -1, _( "Complex shape" ), framepos, wxSize( 350, 280 ),
DIALOG_STYLE )
{
m_Parent = parent;
SetFont(*g_DialogFont);
if ( PolyEdges ) free(PolyEdges);
PolyEdges = NULL;
PolyEdgesCount = 0;
wxBoxSizer * MainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
SetSizer(MainBoxSizer);
wxBoxSizer * LeftBoxSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer * RightBoxSizer = new wxBoxSizer(wxVERTICAL);
MainBoxSizer->Add(LeftBoxSizer, 0, wxGROW|wxALL, 5);
MainBoxSizer->Add(RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
wxButton * Button = new wxButton(this, ID_ACCEPT_OPT, _("Ok"));
Button->SetForegroundColour(*wxRED);
RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);
Button = new wxButton(this, ID_CANCEL_OPT, _("Cancel"));
Button->SetForegroundColour(*wxBLUE);
RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);
Button = new wxButton(this, ID_READ_SHAPE_FILE, _("Read Shape Descr File"));
Button->SetForegroundColour(wxColor(0,100,0) );
RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5);
wxString shapelist[3] = { _("Normal"), _("Symmetrical"), _("mirrored") };
m_ShapeOptionCtrl = new wxRadioBox(this, -1, _("ShapeOption"),
wxDefaultPosition, wxDefaultSize, 3, shapelist, 1, wxRA_SPECIFY_COLS);
LeftBoxSizer->Add(m_ShapeOptionCtrl, 0, wxGROW|wxALL, 5);
m_SizeCtrl = new WinEDA_SizeCtrl(this, _("Size"),
ShapeSize,
g_UnitMetric, LeftBoxSizer, PCB_INTERNAL_UNIT) ;
GetSizer()->Fit(this);
GetSizer()->SetSizeHints(this);
m_Parent = parent;
SetFont( *g_DialogFont );
if( PolyEdges )
free( PolyEdges );
PolyEdges = NULL;
PolyEdgesCount = 0;
wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
SetSizer( MainBoxSizer );
wxBoxSizer* LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* RightBoxSizer = new wxBoxSizer( wxVERTICAL );
MainBoxSizer->Add( LeftBoxSizer, 0, wxGROW | wxALL, 5 );
MainBoxSizer->Add( RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
wxButton* Button = new wxButton( this, ID_ACCEPT_OPT, _( "Ok" ) );
Button->SetForegroundColour( *wxRED );
RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
Button = new wxButton( this, ID_CANCEL_OPT, _( "Cancel" ) );
Button->SetForegroundColour( *wxBLUE );
RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
Button = new wxButton( this, ID_READ_SHAPE_FILE, _( "Read Shape Descr File" ) );
Button->SetForegroundColour( wxColor( 0, 100, 0 ) );
RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
wxString shapelist[3] = { _( "Normal" ), _( "Symmetrical" ), _( "mirrored" ) };
m_ShapeOptionCtrl = new wxRadioBox( this, -1, _(
"ShapeOption" ),
wxDefaultPosition, wxDefaultSize, 3, shapelist, 1,
wxRA_SPECIFY_COLS );
LeftBoxSizer->Add( m_ShapeOptionCtrl, 0, wxGROW | wxALL, 5 );
m_SizeCtrl = new WinEDA_SizeCtrl( this, _( "Size" ),
ShapeSize,
g_UnitMetric, LeftBoxSizer, PCB_INTERNAL_UNIT );
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
}
/**********************************************************************/
void WinEDA_SetParamShapeFrame::OnCancel(wxCommandEvent& WXUNUSED(event))
void WinEDA_SetParamShapeFrame::OnCancel( wxCommandEvent& WXUNUSED (event) )
/**********************************************************************/
{
if ( PolyEdges ) free(PolyEdges);
PolyEdges = NULL;
PolyEdgesCount = 0;
EndModal(0);
if( PolyEdges )
free( PolyEdges );
PolyEdges = NULL;
PolyEdgesCount = 0;
EndModal( 0 );
}
/*******************************************************************/
void WinEDA_SetParamShapeFrame::AcceptOptions(wxCommandEvent& event)
void WinEDA_SetParamShapeFrame::AcceptOptions( wxCommandEvent& event )
/*******************************************************************/
{
ShapeSize = m_SizeCtrl->GetValue();
PolyShapeType = m_ShapeOptionCtrl->GetSelection();
EndModal(1);
ShapeSize = m_SizeCtrl->GetValue();
PolyShapeType = m_ShapeOptionCtrl->GetSelection();
EndModal( 1 );
}
/************************************************************************/
void WinEDA_SetParamShapeFrame::ReadDataShapeDescr(wxCommandEvent& event)
void WinEDA_SetParamShapeFrame::ReadDataShapeDescr( wxCommandEvent& event )
/************************************************************************/
/* Read a description shape file
File format is
Unit=MM
XScale=271.501
YScale=1.00133
$COORD
0 0.6112600148417837
0.001851851851851852 0.6104800531118608
....
$ENDCOORD
Each line is the X Y coord (normalised units from 0 to 1)
*/
* File format is
* Unit=MM
* XScale=271.501
* YScale=1.00133
*
* $COORD
* 0 0.6112600148417837
* 0.001851851851851852 0.6104800531118608
* ....
* $ENDCOORD
*
* Each line is the X Y coord (normalised units from 0 to 1)
*/
{
wxString FullFileName;
wxString ext, mask;
FILE * File;
char Line[1024];
double unitconv = 10000;
char * param1, *param2;
int bufsize;
double * ptbuf;
ext = wxT(".txt");
mask = wxT("*") + ext;
FullFileName = EDA_FileSelector(_("Read descr shape file"),
wxEmptyString, /* Chemin par defaut */
FullFileName, /* nom fichier par defaut */
ext, /* extension par defaut */
mask, /* Masque d'affichage */
this,
wxFD_OPEN,
TRUE /* ne change pas de repertoire courant */
);
if ( FullFileName.IsEmpty()) return;
File = wxFopen(FullFileName, wxT("rt"));
if ( File == NULL )
{
DisplayError(this, _("File not found") );
return;
}
bufsize = 100;
ptbuf = PolyEdges = (double*) MyZMalloc( bufsize * 2 * sizeof(double));
setlocale(LC_NUMERIC, "C");
int LineNum = 0;
while( GetLine(File, Line, &LineNum , sizeof(Line) -1) != NULL )
{
param1 = strtok(Line," =\n\r");
param2 = strtok(NULL," \t\n\r");
if ( strnicmp(param1, "Unit", 4) == 0)
{
if ( strnicmp(param2, "inch", 4) == 0) unitconv = 10000;
if ( strnicmp(param2, "mm", 2) == 0) unitconv = 10000/25.4;
}
if ( strnicmp(param1, "$ENDCOORD", 8) == 0) break;
if ( strnicmp(param1, "$COORD", 6) == 0)
{
while( GetLine(File, Line, &LineNum , sizeof(Line) -1) != NULL )
{
param1 = strtok(Line," \t\n\r");
param2 = strtok(NULL," \t\n\r");
if ( strnicmp(param1, "$ENDCOORD", 8) == 0) break;
if ( bufsize <= PolyEdgesCount )
{
int index = ptbuf - PolyEdges;
bufsize *= 2;
ptbuf = PolyEdges = (double*) realloc( PolyEdges, bufsize * 2 * sizeof(double));
ptbuf += index;
}
* ptbuf = atof(param1);
ptbuf++;
* ptbuf = atof(param2);
ptbuf++;
PolyEdgesCount++;
}
}
if ( strnicmp(Line, "XScale", 6) == 0)
{
ShapeScaleX = atof(param2);
}
if ( strnicmp(Line, "YScale", 6) == 0)
{
ShapeScaleY = atof(param2);
}
}
if ( PolyEdgesCount == 0 )
{
free(PolyEdges);
PolyEdges = NULL;
}
fclose( File);
setlocale(LC_NUMERIC, ""); // revert to the current locale
ShapeScaleX *= unitconv;
ShapeScaleY *= unitconv;
m_SizeCtrl->SetValue( (int) ShapeScaleX, (int) ShapeScaleY);
wxString FullFileName;
wxString ext, mask;
FILE* File;
char Line[1024];
double unitconv = 10000;
char* param1, * param2;
int bufsize;
double* ptbuf;
ext = wxT( ".txt" );
mask = wxT( "*" ) + ext;
FullFileName = EDA_FileSelector( _( "Read descr shape file" ),
wxEmptyString, /* Chemin par defaut */
FullFileName, /* nom fichier par defaut */
ext, /* extension par defaut */
mask, /* Masque d'affichage */
this,
wxFD_OPEN,
TRUE /* ne change pas de repertoire courant */
);
if( FullFileName.IsEmpty() )
return;
File = wxFopen( FullFileName, wxT( "rt" ) );
if( File == NULL )
{
DisplayError( this, _( "File not found" ) );
return;
}
bufsize = 100;
ptbuf = PolyEdges = (double*) MyZMalloc( bufsize * 2 * sizeof(double) );
setlocale( LC_NUMERIC, "C" );
int LineNum = 0;
while( GetLine( File, Line, &LineNum, sizeof(Line) - 1 ) != NULL )
{
param1 = strtok( Line, " =\n\r" );
param2 = strtok( NULL, " \t\n\r" );
if( strnicmp( param1, "Unit", 4 ) == 0 )
{
if( strnicmp( param2, "inch", 4 ) == 0 )
unitconv = 10000;
if( strnicmp( param2, "mm", 2 ) == 0 )
unitconv = 10000 / 25.4;
}
if( strnicmp( param1, "$ENDCOORD", 8 ) == 0 )
break;
if( strnicmp( param1, "$COORD", 6 ) == 0 )
{
while( GetLine( File, Line, &LineNum, sizeof(Line) - 1 ) != NULL )
{
param1 = strtok( Line, " \t\n\r" );
param2 = strtok( NULL, " \t\n\r" );
if( strnicmp( param1, "$ENDCOORD", 8 ) == 0 )
break;
if( bufsize <= PolyEdgesCount )
{
int index = ptbuf - PolyEdges;
bufsize *= 2;
ptbuf = PolyEdges = (double*) realloc( PolyEdges, bufsize * 2 *
sizeof(double) );
ptbuf += index;
}
*ptbuf = atof( param1 );
ptbuf++;
*ptbuf = atof( param2 );
ptbuf++;
PolyEdgesCount++;
}
}
if( strnicmp( Line, "XScale", 6 ) == 0 )
{
ShapeScaleX = atof( param2 );
}
if( strnicmp( Line, "YScale", 6 ) == 0 )
{
ShapeScaleY = atof( param2 );
}
}
if( PolyEdgesCount == 0 )
{
free( PolyEdges );
PolyEdges = NULL;
}
fclose( File );
setlocale( LC_NUMERIC, "" ); // revert to the current locale
ShapeScaleX *= unitconv;
ShapeScaleY *= unitconv;
m_SizeCtrl->SetValue( (int) ShapeScaleX, (int) ShapeScaleY );
}
/*************************************************************/
MODULE * WinEDA_PcbFrame::Create_MuWavePolygonShape(wxDC * DC)
MODULE* WinEDA_PcbFrame::Create_MuWavePolygonShape( wxDC* DC )
/*************************************************************/
{
D_PAD * pad1, *pad2;
MODULE * Module;
wxString cmp_name;
int pad_count = 2;
EDGE_MODULE * edge; int * ptr;
int ii, npoints;
WinEDA_SetParamShapeFrame * frame = new WinEDA_SetParamShapeFrame(this, wxPoint(-1,-1));
int ok = frame->ShowModal(); frame->Destroy();
DrawPanel->MouseToCursorSchema();
if ( ok != 1 )
{
if ( PolyEdges ) free(PolyEdges);
PolyEdges = NULL;
PolyEdgesCount = 0;
return NULL;
}
if ( PolyShapeType == 2 ) // mirrored
ShapeScaleY = - ShapeScaleY;
ShapeSize.x = (int) round( ShapeScaleX);
ShapeSize.y = (int) round( ShapeScaleY);
if ( (ShapeSize.x) == 0 || (ShapeSize.y == 0) )
{
DisplayError(this, _("Shape has a null size!") );
return NULL;
}
if (PolyEdgesCount == 0)
{
DisplayError(this, _("Shape has no points!") );
return NULL;
}
cmp_name = wxT("POLY");
Module = Create_MuWaveBasicShape(NULL, cmp_name, pad_count);
pad1 = Module->m_Pads;
pad1->m_Pos0.x = - ShapeSize.x / 2;
pad1->m_Pos.x += pad1->m_Pos0.x;
pad2 = (D_PAD *) pad1->Pnext;
pad2->m_Pos0.x = pad1->m_Pos0.x + ShapeSize.x;
pad2->m_Pos.x += pad2->m_Pos0.x;
edge = new EDGE_MODULE(Module);
Module->m_Drawings = edge;
edge->Pback = Module;
edge->m_Shape = S_POLYGON;
edge->m_Layer = LAYER_CMP_N;
npoints = PolyEdgesCount;
switch (PolyShapeType)
{
case 0: // Single
case 2: // Single, mirrored
edge->m_PolyCount = PolyEdgesCount + 2;
break;
case 1: // Symetric
edge->m_PolyCount = (2 * PolyEdgesCount) + 2;
break;
}
edge->m_PolyList = (int*) MyMalloc( edge->m_PolyCount * 2 * sizeof(int) );
ptr = edge->m_PolyList;
// Init start point coord:
* ptr = pad1->m_Pos0.x; ptr++;
* ptr = 0; ptr++;
double * dptr = PolyEdges;
wxPoint first_cordinate, last_cordinate;
for ( ii = 0; ii < npoints; ii ++) // Copy points
{
last_cordinate.x = * ptr = (int)round(*dptr * ShapeScaleX) + pad1->m_Pos0.x;
dptr++; ptr++;
last_cordinate.y = *ptr = - (int) round( *dptr * ShapeScaleY);
dptr++; ptr++;
}
first_cordinate.y = edge->m_PolyList[3];
switch (PolyShapeType)
{
int * ptr1;
case 0: // Single
case 2: // Single mirrored
// Init end point coord:
* ptr = pad2->m_Pos0.x = last_cordinate.x; ptr++;
* ptr = 0;
pad1->m_Size.x = pad1->m_Size.y = ABS(first_cordinate.y);
pad2->m_Size.x = pad2->m_Size.y = ABS(last_cordinate.y);
pad1->m_Pos0.y = first_cordinate.y/2;
pad2->m_Pos0.y = last_cordinate.y/2;
pad1->m_Pos.y = pad1->m_Pos0.y + Module->m_Pos.y;
pad2->m_Pos.y = pad2->m_Pos0.y + Module->m_Pos.y;
break;
case 1: // Symetric
ptr1 = ptr-2;
for ( ii = 0; ii <= npoints; ii ++)
{
* ptr = * ptr1; // Copy X coord
ptr++;
*ptr = - *(ptr1+1); // Copy Y coord, mirror X axis
ptr1 -= 2; ptr++;
}
pad1->m_Size.x = pad1->m_Size.y = 2 * ABS(first_cordinate.y);
pad2->m_Size.x = pad2->m_Size.y = 2 * ABS(last_cordinate.y);
break;
}
free(PolyEdges);
PolyEdgesCount = 0;
PolyEdges = NULL;
Module->Set_Rectangle_Encadrement();
Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ;
m_Pcb->m_Status_Pcb = 0 ;
m_CurrentScreen->SetModify();
return Module;
D_PAD* pad1, * pad2;
MODULE* Module;
wxString cmp_name;
int pad_count = 2;
EDGE_MODULE* edge; int* ptr;
int ii, npoints;
WinEDA_SetParamShapeFrame* frame = new WinEDA_SetParamShapeFrame( this, wxPoint( -1, -1 ) );
int ok = frame->ShowModal(); frame->Destroy();
DrawPanel->MouseToCursorSchema();
if( ok != 1 )
{
if( PolyEdges )
free( PolyEdges );
PolyEdges = NULL;
PolyEdgesCount = 0;
return NULL;
}
if( PolyShapeType == 2 ) // mirrored
ShapeScaleY = -ShapeScaleY;
ShapeSize.x = (int) round( ShapeScaleX );
ShapeSize.y = (int) round( ShapeScaleY );
if( (ShapeSize.x) == 0 || (ShapeSize.y == 0) )
{
DisplayError( this, _( "Shape has a null size!" ) );
return NULL;
}
if( PolyEdgesCount == 0 )
{
DisplayError( this, _( "Shape has no points!" ) );
return NULL;
}
cmp_name = wxT( "POLY" );
Module = Create_MuWaveBasicShape( NULL, cmp_name, pad_count );
pad1 = Module->m_Pads;
pad1->m_Pos0.x = -ShapeSize.x / 2;
pad1->m_Pos.x += pad1->m_Pos0.x;
pad2 = (D_PAD*) pad1->Pnext;
pad2->m_Pos0.x = pad1->m_Pos0.x + ShapeSize.x;
pad2->m_Pos.x += pad2->m_Pos0.x;
edge = new EDGE_MODULE( Module );
Module->m_Drawings = edge;
edge->Pback = Module;
edge->m_Shape = S_POLYGON;
edge->m_Layer = LAYER_CMP_N;
npoints = PolyEdgesCount;
switch( PolyShapeType )
{
case 0: // Single
case 2: // Single, mirrored
edge->m_PolyCount = PolyEdgesCount + 2;
break;
case 1: // Symetric
edge->m_PolyCount = (2 * PolyEdgesCount) + 2;
break;
}
edge->m_PolyList = (int*) MyMalloc( edge->m_PolyCount * 2 * sizeof(int) );
ptr = edge->m_PolyList;
// Init start point coord:
*ptr = pad1->m_Pos0.x; ptr++;
*ptr = 0; ptr++;
double* dptr = PolyEdges;
wxPoint first_cordinate, last_cordinate;
for( ii = 0; ii < npoints; ii++ ) // Copy points
{
last_cordinate.x = *ptr = (int) round( *dptr * ShapeScaleX ) + pad1->m_Pos0.x;
dptr++; ptr++;
last_cordinate.y = *ptr = -(int) round( *dptr * ShapeScaleY );
dptr++; ptr++;
}
first_cordinate.y = edge->m_PolyList[3];
switch( PolyShapeType )
{
int* ptr1;
case 0: // Single
case 2: // Single mirrored
// Init end point coord:
*ptr = pad2->m_Pos0.x = last_cordinate.x; ptr++;
*ptr = 0;
pad1->m_Size.x = pad1->m_Size.y = ABS( first_cordinate.y );
pad2->m_Size.x = pad2->m_Size.y = ABS( last_cordinate.y );
pad1->m_Pos0.y = first_cordinate.y / 2;
pad2->m_Pos0.y = last_cordinate.y / 2;
pad1->m_Pos.y = pad1->m_Pos0.y + Module->m_Pos.y;
pad2->m_Pos.y = pad2->m_Pos0.y + Module->m_Pos.y;
break;
case 1: // Symetric
ptr1 = ptr - 2;
for( ii = 0; ii <= npoints; ii++ )
{
*ptr = *ptr1; // Copy X coord
ptr++;
*ptr = -*(ptr1 + 1); // Copy Y coord, mirror X axis
ptr1 -= 2; ptr++;
}
pad1->m_Size.x = pad1->m_Size.y = 2* ABS( first_cordinate.y );
pad2->m_Size.x = pad2->m_Size.y = 2* ABS( last_cordinate.y );
break;
}
free( PolyEdges );
PolyEdgesCount = 0;
PolyEdges = NULL;
Module->Set_Rectangle_Encadrement();
Module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
m_Pcb->m_Status_Pcb = 0;
m_CurrentScreen->SetModify();
return Module;
}
/***************************************************************/
void WinEDA_PcbFrame::Edit_Gap(wxDC * DC, MODULE * Module)
void WinEDA_PcbFrame::Edit_Gap( wxDC* DC, MODULE* Module )
/***************************************************************/
/*
Edit le module GAP, c'est a dire modifie la position et la taille
des pastilles formant le gap pour obtenir une nouvelle valeur du gap
* Edit le module GAP, c'est a dire modifie la position et la taille
* des pastilles formant le gap pour obtenir une nouvelle valeur du gap
*/
{
int gap_size, oX;
float fcoeff;
D_PAD* pad, * next_pad;
wxString msg;
if( Module == NULL) return; /* Module non trouve */
/* Test si module = gap ( nom commence par GAP, et 2 pastilles) */
msg = Module->m_Reference->m_Text.Left(3);
if( msg != wxT("GAP") ) return;
pad = Module->m_Pads;
if(pad == NULL )
{
DisplayError(this, _("No pad for this module")); return;
}
next_pad = (D_PAD*)pad->Pnext;
if(next_pad == NULL )
{
DisplayError(this, _("Only one pad for this module")); return;
}
/* Effacement du module: */
Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR) ;
/* Calcul de la dimension actuelle */
gap_size = next_pad->m_Pos0.x - pad->m_Pos0.x - pad->m_Size.x;
/* Entree de la longueur desiree du gap*/
if( g_UnitMetric)
{
fcoeff = 10000.0/25.4 ;
msg.Printf( wxT("%2.3f"),gap_size / fcoeff);
Get_Message( _("Gap (mm):"),msg, this);
}
else
{
fcoeff = 10000.0 ;
msg.Printf( wxT("%2.4f"),gap_size / fcoeff);
Get_Message( _("Gap (inch):"),msg, this);
}
if ( ! msg.IsEmpty() )
{
double fval;
if ( msg.ToDouble(&fval) )
gap_size = (int)( fval * fcoeff );
}
/* Mise a jour des tailles des pastilles formant le gap */
pad->m_Size.x = pad->m_Size.y = g_DesignSettings.m_CurrentTrackWidth;
pad->m_Pos0.y = 0;
oX = pad->m_Pos0.x =- ((gap_size + pad->m_Size.x) /2);
pad->m_Pos.x = pad->m_Pos0.x + Module->m_Pos.x;
pad->m_Pos.y = pad->m_Pos0.y + Module->m_Pos.y;
RotatePoint(&(pad->m_Pos.x),&(pad->m_Pos.y),
Module->m_Pos.x,Module->m_Pos.y,Module->m_Orient);
next_pad->m_Size.x = next_pad->m_Size.y = g_DesignSettings.m_CurrentTrackWidth;
next_pad->m_Pos0.y = 0;
next_pad->m_Pos0.x = oX + gap_size + next_pad->m_Size.x;
next_pad->m_Pos.x = next_pad->m_Pos0.x + Module->m_Pos.x;
next_pad->m_Pos.y = next_pad->m_Pos0.y + Module->m_Pos.y;
RotatePoint(&(next_pad->m_Pos.x), &(next_pad->m_Pos.y),
Module->m_Pos.x,Module->m_Pos.y, Module->m_Orient);
Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ;
int gap_size, oX;
float fcoeff;
D_PAD* pad, * next_pad;
wxString msg;
if( Module == NULL )
return; /* Module non trouve */
/* Test si module = gap ( nom commence par GAP, et 2 pastilles) */
msg = Module->m_Reference->m_Text.Left( 3 );
if( msg != wxT( "GAP" ) )
return;
pad = Module->m_Pads;
if( pad == NULL )
{
DisplayError( this, _( "No pad for this module" ) ); return;
}
next_pad = (D_PAD*) pad->Pnext;
if( next_pad == NULL )
{
DisplayError( this, _( "Only one pad for this module" ) ); return;
}
/* Effacement du module: */
Module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
/* Calcul de la dimension actuelle */
gap_size = next_pad->m_Pos0.x - pad->m_Pos0.x - pad->m_Size.x;
/* Entree de la longueur desiree du gap*/
if( g_UnitMetric )
{
fcoeff = 10000.0 / 25.4;
msg.Printf( wxT( "%2.3f" ), gap_size / fcoeff );
Get_Message( _( "Gap (mm):" ), msg, this );
}
else
{
fcoeff = 10000.0;
msg.Printf( wxT( "%2.4f" ), gap_size / fcoeff );
Get_Message( _( "Gap (inch):" ), msg, this );
}
if( !msg.IsEmpty() )
{
double fval;
if( msg.ToDouble( &fval ) )
gap_size = (int) ( fval * fcoeff );
}
/* Mise a jour des tailles des pastilles formant le gap */
pad->m_Size.x = pad->m_Size.y = g_DesignSettings.m_CurrentTrackWidth;
pad->m_Pos0.y = 0;
oX = pad->m_Pos0.x = -( (gap_size + pad->m_Size.x) / 2 );
pad->m_Pos.x = pad->m_Pos0.x + Module->m_Pos.x;
pad->m_Pos.y = pad->m_Pos0.y + Module->m_Pos.y;
RotatePoint( &(pad->m_Pos.x), &(pad->m_Pos.y),
Module->m_Pos.x, Module->m_Pos.y, Module->m_Orient );
next_pad->m_Size.x = next_pad->m_Size.y = g_DesignSettings.m_CurrentTrackWidth;
next_pad->m_Pos0.y = 0;
next_pad->m_Pos0.x = oX + gap_size + next_pad->m_Size.x;
next_pad->m_Pos.x = next_pad->m_Pos0.x + Module->m_Pos.x;
next_pad->m_Pos.y = next_pad->m_Pos0.y + Module->m_Pos.y;
RotatePoint( &(next_pad->m_Pos.x), &(next_pad->m_Pos.y),
Module->m_Pos.x, Module->m_Pos.y, Module->m_Orient );
Module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
}
......@@ -14,7 +14,7 @@
#define U_PCB (PCB_INTERNAL_UNIT / EESCHEMA_INTERNAL_UNIT)
/* valeur de flag indicant si le pointeur de reference pour une localisation
* est le curseur sur grille ou le curseur a deplacement fin hors grille */
* est le curseur sur grille ou le curseur a deplacement fin hors grille */
#define CURSEUR_ON_GRILLE (0 << 0)
#define CURSEUR_OFF_GRILLE (1 << 0)
......@@ -57,7 +57,7 @@
eda_global wxArrayString g_LibName_List; // library list to load
eda_global wxSize g_GridList[]
eda_global wxSize g_GridList[]
#ifdef MAIN
= {
wxSize( 1000, 1000 ), wxSize( 500, 500 ), wxSize( 250, 250 ), wxSize( 200, 200 ),
......@@ -71,7 +71,7 @@ eda_global wxSize g_GridList[]
;
#define UNDELETE_STACK_SIZE 10
eda_global EDA_BaseStruct* g_UnDeleteStack[UNDELETE_STACK_SIZE]; //Liste des elements supprimes
eda_global EDA_BaseStruct* g_UnDeleteStack[UNDELETE_STACK_SIZE]; // Liste des elements supprimes
eda_global int g_UnDeleteStackPtr;
eda_global bool g_ShowGrid
......@@ -146,6 +146,26 @@ eda_global bool g_ShowIsolDuringCreateTrack; /* .State controle l'affichage
eda_global DISPLAY_OPTIONS DisplayOpt;
/**
* Function IsModuleLayerVisible
* expects either of the two layers on which a module can reside, and returns
* whether that layer is visible.
* @param layer One of the two allowed layers for modules: CMP_N or CUIVRE_N
* @return bool - true if the layer is visible, else false.
*/
bool inline IsModuleLayerVisible( int layer )
{
if( layer==CMP_N )
return DisplayOpt.Show_Modules_Cmp;
else if( layer==CUIVRE_N )
return DisplayOpt.Show_Modules_Cu;
else
return true;
}
eda_global bool Track_45_Only; /* Flag pour limiter l'inclinaison
* pistes a 45 degres seulement */
eda_global bool Segments_45_Only;/* Flag pour limiter l'inclinaison
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment