diff --git a/change_log.txt b/change_log.txt index 0f1cb4f18e..816c648964 100644 --- a/change_log.txt +++ b/change_log.txt @@ -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 +================================================================================ ++ 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 ================================================================================ + pcbnew & common diff --git a/common/base_struct.cpp b/common/base_struct.cpp index 4cb3698664..981536a2c2 100644 --- a/common/base_struct.cpp +++ b/common/base_struct.cpp @@ -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 diff --git a/include/base_struct.h b/include/base_struct.h index e211a4ae1c..8eb291210c 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -8,6 +8,8 @@ #if defined(DEBUG) #include // 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 { diff --git a/include/drawpanel_wxstruct.h b/include/drawpanel_wxstruct.h index a70f6147b0..4530ee0f9f 100644 --- a/include/drawpanel_wxstruct.h +++ b/include/drawpanel_wxstruct.h @@ -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 }; diff --git a/include/pcbstruct.h b/include/pcbstruct.h index abdd75b6bb..65e89fc9fc 100644 --- a/include/pcbstruct.h +++ b/include/pcbstruct.h @@ -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; diff --git a/makefile.gtk b/makefile.gtk index 2cf3ba5f6f..b4ead3822e 100644 --- a/makefile.gtk +++ b/makefile.gtk @@ -1,6 +1,6 @@ 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 diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 006e172ef7..96e5aca7e6 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -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) + class PadOrModule : public INSPECTOR { - } - - SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData ) - { - 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 ) + { + if( testItem->HitTest( *refPos ) ) + { + found = testItem; + return SEARCH_QUIT; + } + } + else { int debug=1; /* this should not happen, because of scanTypes */ } - else if( testItem->m_StructType == TYPEPAD ) - { - /* not finished - if( testItem->HitTest( &refPos ) ) - { - found = testItem; - return SEARCH_QUIT; - } - */ + 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; } diff --git a/pcbnew/class_edge_mod.cpp b/pcbnew/class_edge_mod.cpp index 78670b5e4f..cf45cb25f3 100644 --- a/pcbnew/class_edge_mod.cpp +++ b/pcbnew/class_edge_mod.cpp @@ -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 ) << "\n"; + NestedSpace( nestLevel+1, os ) << "\n"; + + NestedSpace( nestLevel, os ) << "\n"; } #endif diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h index 037adbf135..843be47d65 100644 --- a/pcbnew/class_edge_mod.h +++ b/pcbnew/class_edge_mod.h @@ -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" ); ? } diff --git a/pcbnew/class_equipot.cpp b/pcbnew/class_equipot.cpp index 140b1d2d64..07d607b5ee 100644 --- a/pcbnew/class_equipot.cpp +++ b/pcbnew/class_equipot.cpp @@ -1,5 +1,5 @@ /*****************************************************************/ -/* fonctions membres de la classe EQUIPOT et fonctions associées */ +/* fonctions membres de la classe EQUIPOT et fonctions associ�s */ /*****************************************************************/ #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; - } + /* 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; + } + } - else /* Le chainage arriere pointe sur la structure "Pere" */ - { - ((BOARD*)Pback)->m_Equipots = (EQUIPOT*)Pnext; - } - } + /* Modification du chainage avant */ + if( Pnext ) + Pnext->Pback = Pback; - /* Modification du chainage avant */ - if( Pnext) Pnext->Pback = Pback; - - Pnext = Pback = NULL; + 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 ; + EQUIPOT* Equipot; - if( netcode <= 0 ) return NULL; - - Equipot = (EQUIPOT*)pcb->m_Equipots; - while ( Equipot ) - { - if(Equipot->m_NetCode == netcode ) break; - Equipot = (EQUIPOT*) Equipot->Pnext; - } + if( netcode <= 0 ) + return NULL; - return(Equipot); + 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; + char Line[1024], Ltmp[1024]; + int tmp; - while( GetLine(File, Line, LineNum ) ) - { - if( strnicmp(Line,"$End",4) == 0 )return 0; + 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; + 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; - } + 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; + 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); + 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); + 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; } - - diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 4fd7633017..e9189a60d4 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -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 ) << + "\n"; - p = m_Value; - for( ; p; p = p->Pnext ) - p->Show( nestLevel+1, os ); + NestedSpace( nestLevel+1, os ) << "\n"; + + EDA_BaseStruct* p; + NestedSpace( nestLevel+1, os ) << "\n"; p = m_Pads; for( ; p; p = p->Pnext ) - p->Show( nestLevel+1, os ); + p->Show( nestLevel+2, os ); + NestedSpace( nestLevel+1, os ) << "\n"; + NestedSpace( nestLevel+1, os ) << "\n"; p = m_Drawings; for( ; p; p = p->Pnext ) - p->Show( nestLevel+1, os ); + p->Show( nestLevel+2, os ); + NestedSpace( nestLevel+1, os ) << "\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; } diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 1ced83f1dc..783bc59eb8 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -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) /** diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 335b6cb6b5..8bf310e638 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -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 diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 3e6ab7ccd3..3946de1b37 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -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 diff --git a/pcbnew/class_pcb_text.cpp b/pcbnew/class_pcb_text.cpp index 76aa0af1c5..38b97e287e 100644 --- a/pcbnew/class_pcb_text.cpp +++ b/pcbnew/class_pcb_text.cpp @@ -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 ) << "\n"; +// NestedSpace( nestLevel, os ) << "\n"; } #endif diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index 822bcaa413..aab052e3e9 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -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 ) << "\n"; +// NestedSpace( nestLevel, os ) << "\n"; } #endif diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 9f84f7a2a1..bc1a711092 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -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: diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp index 3836e01310..516e9068b9 100644 --- a/pcbnew/editrack-part2.cpp +++ b/pcbnew/editrack-part2.cpp @@ -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 ) diff --git a/pcbnew/locate.cpp b/pcbnew/locate.cpp index c5000f4430..522c06f5e2 100644 --- a/pcbnew/locate.cpp +++ b/pcbnew/locate.cpp @@ -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(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(pt_txt_pcb)->HitTest( ref ) ) + { return pt_txt_pcb; + } } } diff --git a/pcbnew/muonde.cpp b/pcbnew/muonde.cpp index b10a34b429..5733058035 100644 --- a/pcbnew/muonde.cpp +++ b/pcbnew/muonde.cpp @@ -1,8 +1,8 @@ - /****************************************************/ - /* 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* 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; + Module = Create_1_Module( DC, name ); + if( Module == NULL ) + return NULL; - /* 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++; - } + 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; - if (DC) Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ; - return Module; + /* 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; + 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) ; - } - } + 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; + 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 + 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; - switch ( shape_type ) - { - case 0: - msg = _("Gap"); - cmp_name = wxT("GAP"); - break; + /* Entree de la longueur desiree du gap*/ + gap_size = g_DesignSettings.m_CurrentTrackWidth; // Valeur raisonnable - case 1: - msg = _("Stub"); - cmp_name = wxT("STUB"); - pad_count = 2; - break; + switch( shape_type ) + { + case 0: + msg = _( "Gap" ); + cmp_name = wxT( "GAP" ); + break; - case 2: - msg = _("Arc Stub"); - cmp_name = wxT("ASTUB"); - pad_count = 1; - break; + case 1: + msg = _( "Stub" ); + cmp_name = wxT( "STUB" ); + pad_count = 2; + 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); - } + case 2: + msg = _( "Arc Stub" ); + cmp_name = wxT( "ASTUB" ); + pad_count = 1; + break; - double fval; - if ( ! value.ToDouble(&fval) ) - { - DisplayError(this, _("Incorrect number, abort")); - abort = TRUE; - } - gap_size = ABS( (int) round( fval * fcoeff )); + default: + msg = wxT( "???" ); + break; + } - 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; - } + 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 ); + } - if (abort) - { - DrawPanel->MouseToCursorSchema(); - return NULL; - } + double fval; + if( !value.ToDouble( &fval ) ) + { + DisplayError( this, _( "Incorrect number, abort" ) ); + abort = TRUE; + } + gap_size = ABS( (int) round( fval * fcoeff ) ); - Module = Create_MuWaveBasicShape(NULL, cmp_name, pad_count); - pt_pad = Module->m_Pads; + 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; + } - 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; + if( abort ) + { + DrawPanel->MouseToCursorSchema(); + return NULL; + } - 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 = Create_MuWaveBasicShape( NULL, cmp_name, pad_count ); + pt_pad = Module->m_Pads; - 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; + 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) {}; + + // 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); - - DECLARE_EVENT_TABLE() + 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; + m_Parent = parent; + SetFont( *g_DialogFont ); - 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); + if( PolyEdges ) + free( PolyEdges ); + PolyEdges = NULL; + PolyEdgesCount = 0; - wxButton * Button = new wxButton(this, ID_ACCEPT_OPT, _("Ok")); - Button->SetForegroundColour(*wxRED); - RightBoxSizer->Add(Button, 0, wxGROW|wxALL, 5); + 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 ); - Button = new wxButton(this, ID_CANCEL_OPT, _("Cancel")); - Button->SetForegroundColour(*wxBLUE); - RightBoxSizer->Add(Button, 0, wxGROW|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_READ_SHAPE_FILE, _("Read Shape Descr File")); - Button->SetForegroundColour(wxColor(0,100,0) ); - 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 ); -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); + 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 ); - m_SizeCtrl = new WinEDA_SizeCtrl(this, _("Size"), - ShapeSize, - g_UnitMetric, LeftBoxSizer, PCB_INTERNAL_UNIT) ; - + 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 ); - GetSizer()->Fit(this); - GetSizer()->SetSizeHints(this); + 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) -*/ -{ -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) -/*************************************************************/ -{ -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) -/***************************************************************/ -/* -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 + * 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) */ { -int gap_size, oX; -float fcoeff; -D_PAD* pad, * next_pad; -wxString msg; - - if( Module == NULL) return; /* Module non trouve */ + wxString FullFileName; + wxString ext, mask; + FILE* File; + char Line[1024]; + double unitconv = 10000; + char* param1, * param2; + int bufsize; + double* ptbuf; - /* Test si module = gap ( nom commence par GAP, et 2 pastilles) */ - msg = Module->m_Reference->m_Text.Left(3); - if( msg != wxT("GAP") ) return; + 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; - 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; - } + File = wxFopen( FullFileName, wxT( "rt" ) ); - /* Effacement du module: */ - Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR) ; + if( File == NULL ) + { + DisplayError( this, _( "File not found" ) ); + return; + } - /* 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); - } + bufsize = 100; + ptbuf = PolyEdges = (double*) MyZMalloc( bufsize * 2 * sizeof(double) ); - if ( ! msg.IsEmpty() ) - { - double fval; - if ( msg.ToDouble(&fval) ) - gap_size = (int)( fval * fcoeff ); - } + 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" ); - /* 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); + 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 ); + } + } - 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); + if( PolyEdgesCount == 0 ) + { + free( PolyEdges ); + PolyEdges = NULL; + } + fclose( File ); + setlocale( LC_NUMERIC, "" ); // revert to the current locale - Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ; + ShapeScaleX *= unitconv; + ShapeScaleY *= unitconv; + + m_SizeCtrl->SetValue( (int) ShapeScaleX, (int) ShapeScaleY ); } +/*************************************************************/ +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; +} + + +/***************************************************************/ +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 + */ +{ + 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 ); +} diff --git a/pcbnew/pcbnew.h b/pcbnew/pcbnew.h index db65889100..0c66a1ae15 100644 --- a/pcbnew/pcbnew.h +++ b/pcbnew/pcbnew.h @@ -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