From 658ca2a21e9821cea8f0422427dfe67c78322177 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sat, 11 Sep 2010 18:33:43 +0200 Subject: [PATCH 1/2] Fixed some issues about trapezoidal pads. Better pad editor dialog. fixed other (very) minor bugs. Code cleaning --- common/drawtxt.cpp | 136 ++-- common/gr_basic.cpp | 3 + cvpcb/writenetlistpcbnew.cpp | 48 -- eeschema/class_drawsheet.h | 18 +- eeschema/class_hierarchical_PIN_sheet.cpp | 16 + eeschema/class_text-label.cpp | 39 +- eeschema/class_text-label.h | 22 +- eeschema/dangling_ends.cpp | 275 +++---- .../dialog_edit_component_in_lib_base.cpp | 6 +- .../dialog_edit_component_in_lib_base.fbp | 6 +- eeschema/plot.cpp | 14 +- eeschema/schedit.cpp | 2 +- pcbnew/class_module_transform_functions.cpp | 7 +- pcbnew/class_pad.cpp | 20 +- pcbnew/class_pad.h | 38 + pcbnew/class_pad_draw_functions.cpp | 555 ++++++++------ pcbnew/dialog_gendrill_base.cpp | 2 +- pcbnew/dialog_gendrill_base.fbp | 2 +- pcbnew/dialog_pad_properties.cpp | 702 +++++++++++------- pcbnew/dialog_pad_properties_base.cpp | 118 ++- pcbnew/dialog_pad_properties_base.fbp | 364 ++++++++- pcbnew/dialog_pad_properties_base.h | 13 +- pcbnew/menubar_pcbframe.cpp | 4 +- 23 files changed, 1565 insertions(+), 845 deletions(-) diff --git a/common/drawtxt.cpp b/common/drawtxt.cpp index 4a18600bda..c803f2ac89 100644 --- a/common/drawtxt.cpp +++ b/common/drawtxt.cpp @@ -29,7 +29,6 @@ double s_HerscheyScaleFactor = HERSHEY_SCALE_FACTOR; - /** Function GetPensizeForBold * @return the "best" value for a pen size to draw/plot a bold text * @param aTextSize = the char size (height or width) @@ -53,21 +52,22 @@ int GetPenSizeForBold( int aTextSize ) */ int Clamp_Text_PenSize( int aPenSize, int aSize, bool aBold ) { - int penSize = aPenSize; - double scale = aBold ? 4.0 : 6.0; - int maxWidth = wxRound( ABS( aSize ) / scale ); + int penSize = aPenSize; + double scale = aBold ? 4.0 : 6.0; + int maxWidth = wxRound( ABS( aSize ) / scale ); if( penSize > maxWidth ) penSize = maxWidth; return penSize; } + int Clamp_Text_PenSize( int aPenSize, wxSize aSize, bool aBold ) { - int size = MIN( ABS( aSize.x ), ABS( aSize.y ) ); - return Clamp_Text_PenSize(aPenSize, size, aBold);; -} + int size = MIN( ABS( aSize.x ), ABS( aSize.y ) ); + return Clamp_Text_PenSize( aPenSize, size, aBold );; +} /* Functions to draw / plot a string. @@ -97,7 +97,6 @@ int NegableTextLength( const wxString& aText ) } - /* Function GetHersheyShapeDescription() * return a pointer to the shape corresponding to unicode value AsciiCode * Note we use the same font for Bold and Normal texts @@ -108,7 +107,8 @@ static const char* GetHersheyShapeDescription( int AsciiCode ) { /* calculate font length */ int font_length_max = newstroke_font_bufsize; - if ( AsciiCode >= (32 + font_length_max) ) + + if( AsciiCode >= (32 + font_length_max) ) AsciiCode = '?'; if( AsciiCode < 32 ) AsciiCode = 32; /* Clamp control chars */ @@ -150,7 +150,7 @@ int ReturnGraphicTextWidth( const wxString& aText, int aXSize, bool aItalic, boo /* Helper function for drawing character polygons */ static void DrawGraphicTextPline( - WinEDA_DrawPanel* aPanel, + EDA_Rect* aClipBox, wxDC* aDC, EDA_Colors aColor, int aWidth, @@ -158,18 +158,19 @@ static void DrawGraphicTextPline( int point_count, wxPoint* coord, void (* aCallback)(int x0, int y0, int xf, int yf ), - PLOTTER *plotter ) + PLOTTER* plotter ) { if( plotter ) { - plotter->move_to(coord[0]); + plotter->move_to( coord[0] ); for( int ik = 1; ik < point_count; ik++ ) { plotter->line_to( coord[ik] ); } - plotter->pen_finish(); + + plotter->pen_finish(); } - else if (aCallback) + else if( aCallback ) { for( int ik = 0; ik < (point_count - 1); ik++ ) { @@ -180,11 +181,11 @@ static void DrawGraphicTextPline( else if( sketch_mode ) { for( int ik = 0; ik < (point_count - 1); ik++ ) - GRCSegm( &aPanel->m_ClipBox, aDC, coord[ik].x, coord[ik].y, + GRCSegm( aClipBox, aDC, coord[ik].x, coord[ik].y, coord[ik + 1].x, coord[ik + 1].y, aWidth, aColor ); } else - GRPoly( &aPanel->m_ClipBox, aDC, point_count, coord, 0, + GRPoly( aClipBox, aDC, point_count, coord, 0, aWidth, aColor, aColor ); } @@ -216,32 +217,33 @@ static int overbar_position( int size_v, int thickness ) */ /****************************************************************************************************/ void DrawGraphicText( WinEDA_DrawPanel* aPanel, - wxDC* aDC, - const wxPoint& aPos, - EDA_Colors aColor, - const wxString& aText, - int aOrient, - const wxSize& aSize, - enum GRTextHorizJustifyType aH_justify, - enum GRTextVertJustifyType aV_justify, - int aWidth, - bool aItalic, - bool aBold, - void (* aCallback)( int x0, int y0, int xf, int yf ), - PLOTTER *plotter ) + wxDC* aDC, + const wxPoint& aPos, + EDA_Colors aColor, + const wxString& aText, + int aOrient, + const wxSize& aSize, + enum GRTextHorizJustifyType aH_justify, + enum GRTextVertJustifyType aV_justify, + int aWidth, + bool aItalic, + bool aBold, + void (* aCallback)( int x0, int y0, int xf, int yf ), + PLOTTER* plotter ) /****************************************************************************************************/ { - int AsciiCode; - int x0, y0; - int size_h, size_v; - unsigned ptr; - int dx, dy; // Draw coordinate for segments to draw. also used in some other calculation - wxPoint current_char_pos; // Draw coordinates for the current char - wxPoint overbar_pos; // Start point for the current overbar - int overbars; // Number of ~ seen - int overbar_italic_comp; // Italic compensation for overbar - + int AsciiCode; + int x0, y0; + int size_h, size_v; + unsigned ptr; + int dx, dy; // Draw coordinate for segments to draw. also used in some other calculation + wxPoint current_char_pos; // Draw coordinates for the current char + wxPoint overbar_pos; // Start point for the current overbar + int overbars; // Number of ~ seen + int overbar_italic_comp; // Italic compensation for overbar + EDA_Rect* clipBox; // Clip box used in basic draw functions + clipBox = aPanel ? &aPanel->m_ClipBox : NULL; #define BUF_SIZE 100 wxPoint coord[BUF_SIZE + 1]; // Buffer coordinate used to draw polylines (one char shape) bool sketch_mode = false; @@ -327,7 +329,7 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel, break; case GR_TEXT_VJUSTIFY_TOP: - current_char_pos.y += dy; + current_char_pos.y += dy; break; case GR_TEXT_VJUSTIFY_BOTTOM: @@ -347,14 +349,15 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel, RotatePoint( ¤t_char_pos, aPos, aOrient ); RotatePoint( &end, aPos, aOrient ); - if( plotter ) { - plotter->move_to(current_char_pos); + if( plotter ) + { + plotter->move_to( current_char_pos ); plotter->finish_to( end ); - } - else if (aCallback) - { + } + else if( aCallback ) + { aCallback( current_char_pos.x, current_char_pos.y, end.x, end.y ); - } + } else GRLine( &aPanel->m_ClipBox, aDC, current_char_pos.x, current_char_pos.y, end.x, end.y, aWidth, aColor ); @@ -402,8 +405,8 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel, RotatePoint( &overbar_pos, aPos, aOrient ); coord[1] = overbar_pos; /* Plot the overbar segment */ - DrawGraphicTextPline( aPanel, aDC, aColor, aWidth, - sketch_mode, 2, coord, aCallback, plotter ); + DrawGraphicTextPline( clipBox, aDC, aColor, aWidth, + sketch_mode, 2, coord, aCallback, plotter ); } continue; /* Skip ~ processing */ } @@ -426,12 +429,13 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel, } else { - /* End of character, insert a synthetic pen up */ + // End of character, insert a synthetic pen up: hc1 = ' '; hc2 = 'R'; endcar = true; } - hc1 -= 'R'; hc2 -= 'R'; /* Do the Hershey decode thing: coordinates values are coded as + 'R' */ + // Do the Hershey decode thing: coordinates values are coded as + 'R' + hc1 -= 'R'; hc2 -= 'R'; /* Pen up request */ if( hc1 == -50 && hc2 == 0 ) @@ -440,9 +444,9 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel, { if( aWidth <= 1 ) aWidth = 0; - DrawGraphicTextPline( aPanel, aDC, aColor, aWidth, + DrawGraphicTextPline( clipBox, aDC, aColor, aWidth, sketch_mode, point_count, coord, - aCallback, plotter ); + aCallback, plotter ); } point_count = 0; } @@ -483,8 +487,8 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel, RotatePoint( &overbar_pos, aPos, aOrient ); coord[1] = overbar_pos; /* Plot the overbar segment */ - DrawGraphicTextPline( aPanel, aDC, aColor, aWidth, - sketch_mode, 2, coord, aCallback, plotter ); + DrawGraphicTextPline( clipBox, aDC, aColor, aWidth, + sketch_mode, 2, coord, aCallback, plotter ); } } @@ -507,24 +511,24 @@ void DrawGraphicText( WinEDA_DrawPanel* aPanel, */ /******************************************************************************************/ void PLOTTER::text( const wxPoint& aPos, - enum EDA_Colors aColor, - const wxString& aText, - int aOrient, - const wxSize& aSize, - enum GRTextHorizJustifyType aH_justify, - enum GRTextVertJustifyType aV_justify, - int aWidth, - bool aItalic, - bool aBold ) + enum EDA_Colors aColor, + const wxString& aText, + int aOrient, + const wxSize& aSize, + enum GRTextHorizJustifyType aH_justify, + enum GRTextVertJustifyType aV_justify, + int aWidth, + bool aItalic, + bool aBold ) /******************************************************************************************/ { if( aWidth == 0 && aBold ) // Use default values if aWidth == 0 aWidth = GetPenSizeForBold( MIN( aSize.x, aSize.y ) ); - if ( aWidth >= 0 ) + if( aWidth >= 0 ) aWidth = Clamp_Text_PenSize( aWidth, aSize, aBold ); else - aWidth = - Clamp_Text_PenSize( -aWidth, aSize, aBold ); + aWidth = -Clamp_Text_PenSize( -aWidth, aSize, aBold ); set_current_line_width( aWidth ); @@ -537,6 +541,6 @@ void PLOTTER::text( const wxPoint& aPos, aH_justify, aV_justify, aWidth, aItalic, aBold, - NULL, + NULL, this ); } diff --git a/common/gr_basic.cpp b/common/gr_basic.cpp index 08a09dfbff..3d2e9669b2 100644 --- a/common/gr_basic.cpp +++ b/common/gr_basic.cpp @@ -1138,6 +1138,9 @@ void GRSCSegm( EDA_Rect* ClipBox, static bool IsGRSPolyDrawable( EDA_Rect* ClipBox, int n, wxPoint Points[] ) { + if( ! ClipBox ) + return true; + int Xmin, Xmax, Ymin, Ymax; Xmin = Xmax = Points[0].x; diff --git a/cvpcb/writenetlistpcbnew.cpp b/cvpcb/writenetlistpcbnew.cpp index 66a3aab462..75340f6257 100644 --- a/cvpcb/writenetlistpcbnew.cpp +++ b/cvpcb/writenetlistpcbnew.cpp @@ -13,11 +13,6 @@ #include "cvpcb.h" #include "protos.h" -#define MAX_LEN_NETNAME 16 - - -static void ChangePinNet( COMPONENT_LIST& list, wxString& PinNet, - int* netNumber, bool rightJustify ); static void WriteFootprintFilterInfos( FILE* dest, COMPONENT_LIST& list ); @@ -74,7 +69,6 @@ int GenNetlistPcbnew( FILE* file, COMPONENT_LIST& list, bool isEESchemaNetlist, { #define NETLIST_HEAD_STRING "EESchema Netlist Version 1.1" char Line[1024]; - int netNumber = 1; DateAndTime( Line ); @@ -103,9 +97,6 @@ int GenNetlistPcbnew( FILE* file, COMPONENT_LIST& list, bool isEESchemaNetlist, BOOST_FOREACH( PIN& pin, component.m_Pins ) { - if( pin.m_Net.Len() > MAX_LEN_NETNAME ) - ChangePinNet( list, pin.m_Net, &netNumber, rightJustify ); - if( !pin.m_Net.IsEmpty() ) fprintf( file, " ( %s %s )\n", CONV_TO_UTF8( pin.m_Number ), @@ -161,42 +152,3 @@ void WriteFootprintFilterInfos( FILE* file, COMPONENT_LIST& list ) fprintf( file, "$endfootprintlist\n}\n" ); } - -/* ??? - * Change le NetName PinNet par un nom compose des 8 derniers codes de PinNet - * suivi de _Xnnnnn ou nnnnn est un nom de 0 a 99999 - */ -static void ChangePinNet( COMPONENT_LIST& list, wxString& PinNet, - int* netNumber, bool rightJustify ) -{ - wxASSERT( netNumber != NULL ); - - wxString OldName; - wxString NewName; - - OldName = PinNet; - - if( rightJustify ) /* Retain the last 8 letters of the name. */ - { - NewName = OldName.Right( 8 ); - NewName << *netNumber; - } - else /* Retain the first 8 letters of the name. */ - { - NewName = OldName.Left( 8 ); - NewName << *netNumber; - } - - *netNumber = *netNumber + 1; - - BOOST_FOREACH( COMPONENT& component, list ) - { - BOOST_FOREACH( PIN& pin, component.m_Pins ) - { - if( pin.m_Net != OldName ) - continue; - - pin.m_Net = NewName; - } - } -} diff --git a/eeschema/class_drawsheet.h b/eeschema/class_drawsheet.h index 2adf8e4d75..83c929a079 100644 --- a/eeschema/class_drawsheet.h +++ b/eeschema/class_drawsheet.h @@ -41,11 +41,6 @@ private: * orientation. */ -public: - - //int m_Shape; - //bool m_IsDangling; // TRUE non connected - public: SCH_SHEET_PIN( SCH_SHEET* parent, const wxPoint& pos = wxPoint( 0, 0 ), @@ -63,6 +58,19 @@ public: SCH_SHEET_PIN* GenCopy(); + virtual void Draw( WinEDA_DrawPanel* aPanel, + wxDC* aDC, + const wxPoint& aOffset, + int aDraw_mode, + int aColor = -1 ); + + /** function CreateGraphicShape (virual) + * Calculates the graphic shape (a polygon) associated to the text + * @param aCorner_list = a buffer to fill with polygon corners coordinates + * @param Pos = Position of the shape + */ + virtual void CreateGraphicShape( std::vector & aCorner_list, + const wxPoint& Pos ); SCH_SHEET_PIN* Next() { return (SCH_SHEET_PIN*) Pnext; diff --git a/eeschema/class_hierarchical_PIN_sheet.cpp b/eeschema/class_hierarchical_PIN_sheet.cpp index 22e952dc36..dabcf45dc2 100644 --- a/eeschema/class_hierarchical_PIN_sheet.cpp +++ b/eeschema/class_hierarchical_PIN_sheet.cpp @@ -60,6 +60,22 @@ SCH_SHEET_PIN* SCH_SHEET_PIN::GenCopy() return newitem; } +/** SCH_SHEET_PIN::Draw is the same as SCH_HIERLABEL::Draw + * but the graphic icon is slightly different + * for INPUT type the icon is the OUTPUT shape of SCH_HIERLABEL + * for OUTPUT type the icon is the INPUT shape of SCH_HIERLABEL + */ +void SCH_SHEET_PIN::Draw( WinEDA_DrawPanel* aPanel, + wxDC* aDC, + const wxPoint& aOffset, + int aDraw_mode, + int aColor ) +{ + // The icon selection is handle by the virtual method CreateGraphicShape + // called by ::Draw + SCH_HIERLABEL::Draw(aPanel, aDC, aOffset, aDraw_mode, aColor ); +} + void SCH_SHEET_PIN::SwapData( SCH_SHEET_PIN* copyitem ) { diff --git a/eeschema/class_text-label.cpp b/eeschema/class_text-label.cpp index 8001268dd4..af81cde20f 100644 --- a/eeschema/class_text-label.cpp +++ b/eeschema/class_text-label.cpp @@ -1010,11 +1010,12 @@ bool SCH_HIERLABEL::HitTest( const wxPoint& aPosRef ) } -/*********************************************************************************************/ +/** Function SCH_LABEL::Draw + * a label is drawn like a text. So just call SCH_TEXT::Draw + */ void SCH_LABEL::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int DrawMode, int Color ) { -/*********************************************************************************************/ SCH_TEXT::Draw( panel, DC, offset, DrawMode, Color ); } @@ -1028,8 +1029,8 @@ void SCH_HIERLABEL::Draw( WinEDA_DrawPanel* panel, { /*****************************************************************************/ -/* Texts type Global Label have 4 directions, and the Text origin is the - * graphic icon +/* Hierarchical Label have a text and a graphic icon. + * Texts type have 4 directions, and the text origin is the graphic icon */ static std::vector Poly; EDA_Colors color; @@ -1100,6 +1101,36 @@ void SCH_HIERLABEL::CreateGraphicShape( std::vector & aCorner_list, } } +/** Virtual Function SCH_SHEET_PIN::CreateGraphicShape + * calculates the graphic shape (a polygon) associated to the text + * @param aCorner_list = a buffer to fill with polygon corners coordinates + * @param aPos = Position of the shape + */ +void SCH_SHEET_PIN::CreateGraphicShape( std::vector & aCorner_list, + const wxPoint& aPos ) +{ + /* This is the same icon shapes as SCH_HIERLABEL + * but the graphic icon is slightly different in 2 cases: + * for INPUT type the icon is the OUTPUT shape of SCH_HIERLABEL + * for OUTPUT type the icon is the INPUT shape of SCH_HIERLABEL + */ + int tmp = m_Shape; + switch( m_Shape ) + { + case NET_INPUT: + m_Shape = NET_OUTPUT; + break; + + case NET_OUTPUT: + m_Shape = NET_INPUT; + break; + + default: + break; + } + SCH_HIERLABEL::CreateGraphicShape( aCorner_list, aPos ); + m_Shape = tmp; +} /****************************************/ EDA_Rect SCH_HIERLABEL::GetBoundingBox() diff --git a/eeschema/class_text-label.h b/eeschema/class_text-label.h index f8cc008de3..93a56b1145 100644 --- a/eeschema/class_text-label.h +++ b/eeschema/class_text-label.h @@ -93,6 +93,18 @@ public: int draw_mode, int Color = -1 ); + /** function CreateGraphicShape + * Calculates the graphic shape (a polygon) associated to the text + * @param aCorner_list = a buffer to fill with polygon corners coordinates + * @param Pos = Postion of the shape + * for texts and labels: do nothing + * Mainly for derived classes (SCH_SHEET_PIN and Hierarchical labels) + */ + virtual void CreateGraphicShape( std::vector & aCorner_list, + const wxPoint& Pos ) + { + aCorner_list.clear(); + } void SwapData( SCH_TEXT* copyitem ); void Place( WinEDA_SchematicFrame* frame, wxDC* DC ); @@ -291,13 +303,13 @@ public: */ EDA_Rect GetBoundingBox(); - /** function CreateGraphicShape + /** function CreateGraphicShape (virual) * Calculates the graphic shape (a polygon) associated to the text * @param aCorner_list = a buffer to fill with polygon corners coordinates - * @param Pos = Position of the shape + * @param aPos = Position of the shape */ - void CreateGraphicShape( std::vector & aCorner_list, - const wxPoint& Pos ); + virtual void CreateGraphicShape( std::vector & aCorner_list, + const wxPoint& aPos ); /** virtual function Mirror_Y * mirror item relative to an Y axis @@ -355,7 +367,7 @@ public: * @param aCorner_list = a buffer to fill with polygon corners coordinates * @param Pos = Postion of the shape */ - void CreateGraphicShape( std::vector & aCorner_list, + virtual void CreateGraphicShape( std::vector & aCorner_list, const wxPoint& Pos ); /** diff --git a/eeschema/dangling_ends.cpp b/eeschema/dangling_ends.cpp index fe817f72fa..cb0152a7ba 100644 --- a/eeschema/dangling_ends.cpp +++ b/eeschema/dangling_ends.cpp @@ -27,31 +27,30 @@ enum End_Type { SHEET_LABEL_END }; -class DanglingEndHandle +// A helper class to store a list of items that can be connected to something: +class DANGLING_END_ITEM { public: - const void* m_Item; - wxPoint m_Pos; - int m_Type; - DanglingEndHandle* m_Pnext; + const void* m_Item; // a pointer to the parent + wxPoint m_Pos; // the position of the connecting point + int m_Type; // type of parent - DanglingEndHandle( int type ) + DANGLING_END_ITEM( int type, const void* aItem ) { - m_Item = NULL; - m_Type = type; - m_Pnext = NULL; + m_Item = aItem; + m_Type = type; } }; -DanglingEndHandle* ItemList; - -static void TestWireForDangling( SCH_LINE* DrawRef, - WinEDA_SchematicFrame* frame, - wxDC* DC ); -void TestLabelForDangling( SCH_TEXT* label, - WinEDA_SchematicFrame* frame, - wxDC* DC ); -DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList ); +static void TestWireForDangling( std::vector & aItemList, + SCH_LINE* DrawRef, + WinEDA_SchematicFrame* frame, + wxDC* aDC ); +void TestLabelForDangling( std::vector & aItemList, + SCH_TEXT* aLabel, + WinEDA_SchematicFrame* aFrame, + wxDC* aDC ); +void RebuildEndPointsList( std::vector & aItemList, SCH_ITEM* aDrawList ); /* Returns true if the point P is on the segment S. */ @@ -74,21 +73,10 @@ bool SegmentIntersect( wxPoint aSegStart, wxPoint aSegEnd, wxPoint aTestPoint ) void WinEDA_SchematicFrame::TestDanglingEnds( SCH_ITEM* DrawList, wxDC* DC ) { - if( ItemList ) - { - const DanglingEndHandle* DanglingItem; - const DanglingEndHandle* nextitem; + // this list is static to avoid many useles memory allocation. + std::vector itemList; - for( DanglingItem = ItemList; - DanglingItem != NULL; - DanglingItem = nextitem ) - { - nextitem = DanglingItem->m_Pnext; - SAFE_DELETE( DanglingItem ); - } - } - - ItemList = RebuildEndList( DrawList ); + RebuildEndPointsList( itemList, DrawList ); for( SCH_ITEM* item = DrawList; item; item = item->Next() ) { @@ -97,15 +85,18 @@ void WinEDA_SchematicFrame::TestDanglingEnds( SCH_ITEM* DrawList, wxDC* DC ) case TYPE_SCH_GLOBALLABEL: case TYPE_SCH_HIERLABEL: case TYPE_SCH_LABEL: - TestLabelForDangling( (SCH_LABEL*) item, this, DC ); + TestLabelForDangling( itemList, (SCH_LABEL*) item, this, DC ); break; case DRAW_SHEET_STRUCT_TYPE: - - // Read the hierarchical pins list and teast for dangling pins: - BOOST_FOREACH( SCH_SHEET_PIN & sheetPin, ( (SCH_SHEET*) item )->GetSheetPins() ) { - TestLabelForDangling( &sheetPin, this, DC ); + { + SCH_SHEET* sheet = (SCH_SHEET*) item; + // Read the hierarchical pins list and teast for dangling pins: + BOOST_FOREACH( SCH_SHEET_PIN & pinsheet, sheet->GetSheetPins() ) + { + TestLabelForDangling( itemList, &pinsheet, this, DC ); } + } break; case DRAW_SEGMENT_STRUCT_TYPE: @@ -113,7 +104,7 @@ void WinEDA_SchematicFrame::TestDanglingEnds( SCH_ITEM* DrawList, wxDC* DC ) #define STRUCT ( (SCH_LINE*) item ) if( STRUCT->GetLayer() == LAYER_WIRE ) { - TestWireForDangling( STRUCT, this, DC ); + TestWireForDangling( itemList, STRUCT, this, DC ); break; } if( STRUCT->GetLayer() == LAYER_NOTES ) @@ -165,24 +156,22 @@ LIB_PIN* WinEDA_SchematicFrame::LocatePinEnd( SCH_ITEM* DrawList, } -void TestWireForDangling( SCH_LINE* DrawRef, WinEDA_SchematicFrame* frame, - wxDC* DC ) +void TestWireForDangling( std::vector & aItemList, + SCH_LINE* DrawRef, + WinEDA_SchematicFrame* frame, + wxDC* DC ) { - DanglingEndHandle* terminal_item; bool Sdangstate = true, Edangstate = true; - for( terminal_item = ItemList; terminal_item != NULL; - terminal_item = terminal_item->m_Pnext ) + BOOST_FOREACH( DANGLING_END_ITEM terminal_item, aItemList ) { - if( terminal_item->m_Item == DrawRef ) + if( terminal_item.m_Item == DrawRef ) continue; - if( (DrawRef->m_Start.x == terminal_item->m_Pos.x) - && (DrawRef->m_Start.y == terminal_item->m_Pos.y) ) + if( DrawRef->m_Start == terminal_item.m_Pos ) Sdangstate = false; - if( (DrawRef->m_End.x == terminal_item->m_Pos.x) - && (DrawRef->m_End.y == terminal_item->m_Pos.y) ) + if( DrawRef->m_End == terminal_item.m_Pos ) Edangstate = false; if( (Sdangstate == false) && (Edangstate == false) ) @@ -203,34 +192,40 @@ void TestWireForDangling( SCH_LINE* DrawRef, WinEDA_SchematicFrame* frame, } -void TestLabelForDangling( SCH_TEXT* label, WinEDA_SchematicFrame* frame, - wxDC* DC ) +void TestLabelForDangling( std::vector & aItemList, + SCH_TEXT* aLabel, + WinEDA_SchematicFrame* aFrame, + wxDC* aDC ) { - DanglingEndHandle* terminal_item; bool dangstate = true; - for( terminal_item = ItemList; terminal_item != NULL; - terminal_item = terminal_item->m_Pnext ) + for( unsigned ii = 0; ii < aItemList.size(); ii++ ) { - if( terminal_item->m_Item == label ) + DANGLING_END_ITEM & terminal_item = aItemList[ii]; + + if( terminal_item.m_Item == aLabel ) continue; - switch( terminal_item->m_Type ) + switch( terminal_item.m_Type ) { case PIN_END: case LABEL_END: case SHEET_LABEL_END: - if( ( label->m_Pos.x == terminal_item->m_Pos.x ) - && ( label->m_Pos.y == terminal_item->m_Pos.y ) ) + if( aLabel->m_Pos == terminal_item.m_Pos ) dangstate = false; break; case WIRE_START_END: case BUS_START_END: - dangstate = !SegmentIntersect( terminal_item->m_Pos, - terminal_item->m_Pnext->m_Pos, - label->m_Pos ); - terminal_item = terminal_item->m_Pnext; + { + // these schematic items have created 2 DANGLING_END_ITEM + // one per end. + ii++; + DANGLING_END_ITEM & next_terminal = aItemList[ii]; + dangstate = !SegmentIntersect( terminal_item.m_Pos, + next_terminal.m_Pos, + aLabel->m_Pos ); + } break; case UNKNOWN: @@ -245,13 +240,13 @@ void TestLabelForDangling( SCH_TEXT* label, WinEDA_SchematicFrame* frame, break; } - if( dangstate != label->m_IsDangling ) + if( dangstate != aLabel->m_IsDangling ) { - if( DC ) - RedrawOneStruct( frame->DrawPanel, DC, label, g_XorMode ); - label->m_IsDangling = dangstate; - if( DC ) - RedrawOneStruct( frame->DrawPanel, DC, label, GR_DEFAULT_DRAWMODE ); + if( aDC ) + RedrawOneStruct( aFrame->DrawPanel, aDC, aLabel, g_XorMode ); + aLabel->m_IsDangling = dangstate; + if( aDC ) + RedrawOneStruct( aFrame->DrawPanel, aDC, aLabel, GR_DEFAULT_DRAWMODE ); } } @@ -273,99 +268,76 @@ wxPoint ReturnPinPhysicalPosition( LIB_PIN* Pin, SCH_COMPONENT* DrawLibItem ) } -DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList ) +void RebuildEndPointsList( std::vector & aItemList, SCH_ITEM* aDrawList ) { - DanglingEndHandle* StartList = NULL, * item, * lastitem = NULL; - EDA_BaseStruct* DrawItem; + SCH_ITEM* schItem; - for( DrawItem = DrawList; DrawItem != NULL; DrawItem = DrawItem->Next() ) + aItemList.clear(); + + for( schItem = aDrawList; schItem != NULL; schItem = schItem->Next() ) { - switch( DrawItem->Type() ) + switch( schItem->Type() ) { case TYPE_SCH_LABEL: case TYPE_SCH_GLOBALLABEL: case TYPE_SCH_HIERLABEL: - #undef STRUCT - #define STRUCT ( (SCH_LABEL*) DrawItem ) - item = new DanglingEndHandle( LABEL_END ); - - item->m_Item = DrawItem; - item->m_Pos = STRUCT->m_Pos; - if( lastitem ) - lastitem->m_Pnext = item; - else - StartList = item; - lastitem = item; - break; + { + #undef STRUCT + #define STRUCT ( (SCH_LABEL*) schItem ) + DANGLING_END_ITEM item( LABEL_END, schItem ); + item.m_Pos = STRUCT->m_Pos; + aItemList.push_back( item ); + } + break; case DRAW_SEGMENT_STRUCT_TYPE: - #undef STRUCT - #define STRUCT ( (SCH_LINE*) DrawItem ) + #undef STRUCT + #define STRUCT ( (SCH_LINE*) schItem ) if( STRUCT->GetLayer() == LAYER_NOTES ) break; if( ( STRUCT->GetLayer() == LAYER_BUS ) || (STRUCT->GetLayer() == LAYER_WIRE ) ) { - item = new DanglingEndHandle( - (STRUCT->GetLayer() == LAYER_BUS) ? - BUS_START_END : WIRE_START_END ); + DANGLING_END_ITEM item( (STRUCT->GetLayer() == LAYER_BUS) ? + BUS_START_END : WIRE_START_END, schItem ); + item.m_Pos = STRUCT->m_Start; + DANGLING_END_ITEM item1( (STRUCT->GetLayer() == LAYER_BUS) ? + BUS_END_END : WIRE_END_END, schItem ); + item1.m_Pos = STRUCT->m_End; - item->m_Item = DrawItem; - item->m_Pos = STRUCT->m_Start; - if( lastitem ) - lastitem->m_Pnext = item; - else - StartList = item; - lastitem = item; - item = - new DanglingEndHandle( (STRUCT->GetLayer() == LAYER_BUS) ? - BUS_END_END : WIRE_END_END ); - - item->m_Item = DrawItem; - item->m_Pos = STRUCT->m_End; - lastitem->m_Pnext = item; - lastitem = item; + aItemList.push_back( item ); + aItemList.push_back( item1 ); } break; case DRAW_JUNCTION_STRUCT_TYPE: - #undef STRUCT - #define STRUCT ( (SCH_JUNCTION*) DrawItem ) - item = new DanglingEndHandle( JUNCTION_END ); - - item->m_Item = DrawItem; - item->m_Pos = STRUCT->m_Pos; - if( lastitem ) - lastitem->m_Pnext = item; - else - StartList = item; - lastitem = item; - break; + { + #undef STRUCT + #define STRUCT ( (SCH_JUNCTION*) schItem ) + DANGLING_END_ITEM item( JUNCTION_END, schItem ); + item.m_Pos = STRUCT->m_Pos; + aItemList.push_back( item ); + } + break; case DRAW_BUSENTRY_STRUCT_TYPE: - #undef STRUCT - #define STRUCT ( (SCH_BUS_ENTRY*) DrawItem ) - item = new DanglingEndHandle( ENTRY_END ); + { + #undef STRUCT + #define STRUCT ( (SCH_BUS_ENTRY*) schItem ) + DANGLING_END_ITEM item( ENTRY_END, schItem ); + item.m_Pos = STRUCT->m_Pos; - item->m_Item = DrawItem; - item->m_Pos = STRUCT->m_Pos; - if( lastitem ) - lastitem->m_Pnext = item; - else - StartList = item; - lastitem = item; - item = new DanglingEndHandle( ENTRY_END ); - - item->m_Item = DrawItem; - item->m_Pos = STRUCT->m_End(); - lastitem->m_Pnext = item; - lastitem = item; - break; + DANGLING_END_ITEM item1( ENTRY_END, schItem ); + item1.m_Pos = STRUCT->m_End(); + aItemList.push_back( item ); + aItemList.push_back( item1 ); + } + break; case TYPE_SCH_COMPONENT: { #undef STRUCT - #define STRUCT ( (SCH_COMPONENT*) DrawItem ) + #define STRUCT ( (SCH_COMPONENT*) schItem ) LIB_COMPONENT* Entry; Entry = CMP_LIBRARY::FindLibraryComponent( STRUCT->m_ChipName ); if( Entry == NULL ) @@ -384,15 +356,9 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList ) && ( STRUCT->m_Convert != Pin->m_Convert ) ) continue; - item = new DanglingEndHandle( PIN_END ); - - item->m_Item = Pin; - item->m_Pos = ReturnPinPhysicalPosition( Pin, STRUCT ); - if( lastitem ) - lastitem->m_Pnext = item; - else - StartList = item; - lastitem = item; + DANGLING_END_ITEM item( PIN_END, Pin ); + item.m_Pos = ReturnPinPhysicalPosition( Pin, STRUCT ); + aItemList.push_back( item ); } break; @@ -400,21 +366,18 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList ) case DRAW_SHEET_STRUCT_TYPE: { - SCH_SHEET* sheet = (SCH_SHEET*) DrawItem; + SCH_SHEET* sheet = (SCH_SHEET*) schItem; - BOOST_FOREACH( SCH_SHEET_PIN pinsheet, sheet->GetSheetPins() ) { + // Using BOOST_FOREACH here creates problems (bad pointer value to pinsheet). + // I do not know why. + for( unsigned ii = 0; ii < sheet->GetSheetPins().size(); ii++ ) + { + SCH_SHEET_PIN &pinsheet = sheet->GetSheetPins()[ii]; wxASSERT( pinsheet.Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE ); - item = new DanglingEndHandle( SHEET_LABEL_END ); - item->m_Item = &pinsheet; - item->m_Pos = pinsheet.m_Pos; - - if( lastitem ) - lastitem->m_Pnext = item; - else - StartList = item; - - lastitem = item; + DANGLING_END_ITEM item( SHEET_LABEL_END, &pinsheet ); + item.m_Pos = pinsheet.m_Pos; + aItemList.push_back( item ); } } break; @@ -423,6 +386,4 @@ DanglingEndHandle* RebuildEndList( EDA_BaseStruct* DrawList ) ; } } - - return StartList; } diff --git a/eeschema/dialog_edit_component_in_lib_base.cpp b/eeschema/dialog_edit_component_in_lib_base.cpp index 9a62be80b9..5877403740 100644 --- a/eeschema/dialog_edit_component_in_lib_base.cpp +++ b/eeschema/dialog_edit_component_in_lib_base.cpp @@ -107,7 +107,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx m_PanelBasic->SetSizer( bSizerBasicPanel ); m_PanelBasic->Layout(); bSizerBasicPanel->Fit( m_PanelBasic ); - m_NoteBook->AddPage( m_PanelBasic, _("Options"), false ); + m_NoteBook->AddPage( m_PanelBasic, _("Options"), true ); m_PanelDoc = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL ); wxBoxSizer* m_PanelDocBoxSizer; m_PanelDocBoxSizer = new wxBoxSizer( wxVERTICAL ); @@ -123,7 +123,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx m_staticTextKeywords = new wxStaticText( m_PanelDoc, wxID_ANY, _("Keywords:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextKeywords->Wrap( -1 ); - m_staticTextKeywords->SetToolTip( _("Enter keys words that can be used to select this composant.\nKey words cannot have spaces and are separated by a space.") ); + m_staticTextKeywords->SetToolTip( _("Enter key words that can be used to select this composant.\nKey words cannot have spaces and are separated by a space.") ); m_PanelDocBoxSizer->Add( m_staticTextKeywords, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); @@ -153,7 +153,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx m_PanelDoc->SetSizer( m_PanelDocBoxSizer ); m_PanelDoc->Layout(); m_PanelDocBoxSizer->Fit( m_PanelDoc ); - m_NoteBook->AddPage( m_PanelDoc, _("Description"), true ); + m_NoteBook->AddPage( m_PanelDoc, _("Description"), false ); m_PanelAlias = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER|wxTAB_TRAVERSAL ); wxBoxSizer* bSizerMainPanelAlias; bSizerMainPanelAlias = new wxBoxSizer( wxHORIZONTAL ); diff --git a/eeschema/dialog_edit_component_in_lib_base.fbp b/eeschema/dialog_edit_component_in_lib_base.fbp index 81ea31f148..8e8bf16b4b 100644 --- a/eeschema/dialog_edit_component_in_lib_base.fbp +++ b/eeschema/dialog_edit_component_in_lib_base.fbp @@ -128,7 +128,7 @@ Options - 0 + 1 @@ -851,7 +851,7 @@ Description - 1 + 0 @@ -1026,7 +1026,7 @@ - Enter keys words that can be used to select this composant. Key words cannot have spaces and are separated by a space. + Enter key words that can be used to select this composant. Key words cannot have spaces and are separated by a space. diff --git a/eeschema/plot.cpp b/eeschema/plot.cpp index 622401e980..7952045f7d 100644 --- a/eeschema/plot.cpp +++ b/eeschema/plot.cpp @@ -288,19 +288,9 @@ static void PlotTextStruct( PLOTTER* plotter, SCH_TEXT* aSchText ) aSchText->m_Bold ); /* Draw graphic symbol for global or hierarchical labels */ - if( aSchText->Type() == TYPE_SCH_GLOBALLABEL ) - { - ( (SCH_GLOBALLABEL*) aSchText )->CreateGraphicShape( Poly, - aSchText->m_Pos ); + aSchText->CreateGraphicShape( Poly, aSchText->m_Pos ); + if( Poly.size() ) plotter->poly( Poly.size(), &Poly[0].x, NO_FILL ); - } - if( ( aSchText->Type() == TYPE_SCH_HIERLABEL ) - || ( aSchText->Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE) ) - { - ( (SCH_HIERLABEL*) aSchText )->CreateGraphicShape( Poly, - aSchText->m_Pos ); - plotter->poly( Poly.size(), &Poly[0].x, NO_FILL ); - } } diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index e6fa2f0317..52edf78074 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -392,7 +392,7 @@ void WinEDA_SchematicFrame::Process_Special_Functions( wxCommandEvent& event ) return; } - if( !IsOK( this, _( "Do you wish to cleanup this sheet" ) ) ) + if( !IsOK( this, _( "Do you wish to cleanup this sheet?" ) ) ) return; /* Save sheet in undo list before cleaning up unreferenced hierarchical labels. */ diff --git a/pcbnew/class_module_transform_functions.cpp b/pcbnew/class_module_transform_functions.cpp index 6f9cf00b98..3efc6c3de4 100644 --- a/pcbnew/class_module_transform_functions.cpp +++ b/pcbnew/class_module_transform_functions.cpp @@ -71,11 +71,10 @@ int ChangeSideNumLayer( int oldlayer ) } -/* Change the mask layer during routing cu / cmp layers for - * Cu / CMP.. - * (Copper, mask, paste, solder) +/* Calculate the mask layer when flipping a footprint + * BACK and FRONT copper layers , mask, paste, solder layers are swapped */ -static int ChangeSideMaskLayer( int masque ) +int ChangeSideMaskLayer( int masque ) { int newmasque; diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 8eecf909d5..4b16269d97 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -3,6 +3,7 @@ /***********************************************/ #include "fctsys.h" +#include "PolyLine.h" #include "common.h" #include "confirm.h" #include "kicad_string.h" @@ -176,7 +177,7 @@ void D_PAD::Copy( D_PAD* source ) m_Pos = source->m_Pos; m_Masque_Layer = source->m_Masque_Layer; - memcpy( m_Padname, source->m_Padname, sizeof(m_Padname) ); + m_NumPadName = source->m_NumPadName; SetNet( source->GetNet() ); m_Drill = source->m_Drill; m_DrillShape = source->m_DrillShape; @@ -779,6 +780,23 @@ bool D_PAD::HitTest( const wxPoint& ref_pos ) return true; break; + case PAD_TRAPEZOID: + { + wxPoint poly[4]; + BuildPadPolygon( poly, wxSize(0,0), 0 ); + // Build the same polygon with CPolyPt corners, + // to use TestPointInsidePolygon + static std::vector polysList; // Is static to avoid memory reallocation + polysList.clear(); + for(int ii= 0; ii < 4; ii++ ) + { + CPolyPt corner(poly[ii].x, poly[ii].y); + polysList.push_back(corner); + } + RotatePoint( &deltaX, &deltaY, -m_Orient ); + return TestPointInsidePolygon( polysList, 0, 3, deltaX, deltaY ); + } + default: RotatePoint( &deltaX, &deltaY, -m_Orient ); if( (abs( deltaX ) <= dx ) && (abs( deltaY ) <= dy) ) diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index d599161c87..1a25802044 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -25,6 +25,28 @@ class Pcb3D_GLCanvas; #define PAD_HOLE_NOT_PLATED_DEFAULT_LAYERS LAYER_BACK | SILKSCREEN_LAYER_FRONT | \ SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT +// Helper class to staore parameters used to draw a pad +class PAD_DRAWINFO +{ +public: + WinEDA_DrawPanel * m_DrawPanel; // the WinEDA_DrawPanel used to draw a PAD ; can be null + int m_DrawMode; // the draw mode + int m_Color; // color used to draw the pad shape , from pad layers and visible layers + int m_HoleColor; // color used to draw the pad hole + int m_PadClearance; // clearance value, used to draw the pad area outlines + wxSize m_Mask_margin; // margin, used to draw solder paste when only one layer is shown + bool m_Display_padnum; // true to show pad number + bool m_Display_netname; // true to show net name + bool m_ShowPadFilled; // true to show pad as solid area, false to show pas in sketch mode + bool m_ShowNCMark; // true to show pad not connected mark + bool m_IsPrinting; // true to print, false to display on screen. + wxPoint m_Offset; // general draw offset +#ifndef USE_WX_ZOOM + double m_Scale; // Draw scaling factor +#endif + PAD_DRAWINFO( ); +}; + class D_PAD : public BOARD_CONNECTED_ITEM { @@ -210,6 +232,22 @@ public: void Draw3D( Pcb3D_GLCanvas* glcanvas ); + /** function DrawShape + * basic function to draw a pad. + * used by Draw after calculation of parameters (color, ) final orientation ... + */ + void DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ); + + /** function BuildPadPolygon + * Has meaning only for polygonal pads (trapeziod and rectangular) + * Build the Corner list of the polygonal shape, + * depending on shape, extra size (clearance ...) and orientation + * @param aCoord[4] = a buffer to fill. + * @param aInflateValue = wxSize: the clearance or margin value. value > 0: inflate, < 0 deflate + * @param aRotation = full rotation of the polygon + */ + void BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, int aRotation ); + // others void SetPadName( const wxString& name ); // Change pad name wxString ReturnStringPadName(); // Return pad name as string in a wxString diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp index 618a2fe3cb..458d170809 100644 --- a/pcbnew/class_pad_draw_functions.cpp +++ b/pcbnew/class_pad_draw_functions.cpp @@ -3,6 +3,7 @@ /*******************************/ #include "fctsys.h" + #include "gr_basic.h" #include "common.h" #include "trigo.h" @@ -20,94 +21,111 @@ * After testing this feature,I am not sure this is a good idea * but the code is left here. */ + //#define SHOW_PADMASK_REAL_SIZE_AND_COLOR -/** Draw a pad: - * @param DC = device context - * @param offset = draw offset - * @param draw_mode = mode: GR_OR, GR_XOR, GR_AND... - */ -void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, - const wxPoint& offset ) + +// Helper class to store parameters used to draw a pad +PAD_DRAWINFO::PAD_DRAWINFO( ) +{ + m_DrawPanel = NULL; + m_DrawMode = 0; + m_Color = BLACK; + m_HoleColor = BLACK; // could be DARKGRAY; + m_PadClearance = 0; + m_Display_padnum = true; + m_Display_netname = true; + m_ShowPadFilled = true; + m_ShowNCMark = true; +#ifndef USE_WX_ZOOM + m_Scale = 1.0; +#endif + m_IsPrinting = false; +} + + +/** Draw a pad: + * @param aDC = device context + * @param aDraw_mode = mode: GR_OR, GR_XOR, GR_AND... + * @param aOffset = draw offset + */ +void D_PAD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDraw_mode, + const wxPoint& aOffset ) { - int ii; int color = 0; - int ux0, uy0, - dx, dx0, dy, dy0, - rotdx, - delta_cx, delta_cy, - xc, yc; - int angle; - wxPoint coord[4]; - int fillpad = 0; - wxPoint shape_pos; wxSize mask_margin; // margin (clearance) used for some non copper layers - int showActualMaskSize = 0; /* == layer number if the actual pad size on mask layer can be displayed - * i.e. if only one layer is shown for this pad - * and this layer is a mask (solder mask or sloder paste - */ + int showActualMaskSize = 0; /* == layer number if the actual pad size on mask layer can be displayed + * i.e. if only one layer is shown for this pad + * and this layer is a mask (solder mask or sloder paste + */ if( m_Flags & DO_NOT_DRAW ) return; + PAD_DRAWINFO drawInfo; + + drawInfo.m_Offset = aOffset; + /* We can show/hide pads from the layer manager. - * options are show/hide pads on front and/or back side of the board - * For through pads, we hide them only if both sides are hidden. - * smd pads on back are hidden for all layers (copper and technical layers) - * on back side of the board - * smd pads on front are hidden for all layers (copper and technical layers) - * on front side of the board - * ECO, edge and Draw layers and not considered - */ + * options are show/hide pads on front and/or back side of the board + * For through pads, we hide them only if both sides are hidden. + * smd pads on back are hidden for all layers (copper and technical layers) + * on back side of the board + * smd pads on front are hidden for all layers (copper and technical layers) + * on front side of the board + * ECO, edge and Draw layers and not considered + */ // Mask layers for Back side of board #define BACK_SIDE_LAYERS \ - (LAYER_BACK | ADHESIVE_LAYER_BACK | SOLDERPASTE_LAYER_BACK\ - | SILKSCREEN_LAYER_BACK | SOLDERMASK_LAYER_BACK) + (LAYER_BACK | ADHESIVE_LAYER_BACK | SOLDERPASTE_LAYER_BACK \ + | SILKSCREEN_LAYER_BACK | SOLDERMASK_LAYER_BACK) // Mask layers for Front side of board #define FRONT_SIDE_LAYERS \ - (LAYER_FRONT | ADHESIVE_LAYER_FRONT | SOLDERPASTE_LAYER_FRONT\ - | SILKSCREEN_LAYER_FRONT | SOLDERMASK_LAYER_FRONT) + (LAYER_FRONT | ADHESIVE_LAYER_FRONT | SOLDERPASTE_LAYER_FRONT \ + | SILKSCREEN_LAYER_FRONT | SOLDERMASK_LAYER_FRONT) - BOARD * brd = GetBoard( ); - bool frontVisible = brd->IsElementVisible( PCB_VISIBLE(PAD_FR_VISIBLE) ); - bool backVisible = brd->IsElementVisible( PCB_VISIBLE(PAD_BK_VISIBLE) ); + BOARD* brd = GetBoard(); + bool frontVisible = brd->IsElementVisible( PCB_VISIBLE( PAD_FR_VISIBLE ) ); + bool backVisible = brd->IsElementVisible( PCB_VISIBLE( PAD_BK_VISIBLE ) ); if( !frontVisible && !backVisible ) return; /* If pad are only on front side (no layer on back side) * and if hide front side pads is enabled, do not draw - */ + */ if( !frontVisible && ( (m_Masque_Layer & BACK_SIDE_LAYERS) == 0 ) ) return; /* If pad are only on back side (no layer on front side) * and if hide back side pads is enabled, do not draw - */ + */ if( !backVisible && ( (m_Masque_Layer & FRONT_SIDE_LAYERS) == 0 ) ) return; - WinEDA_BasePcbFrame* frame = (WinEDA_BasePcbFrame*) panel->GetParent(); + WinEDA_BasePcbFrame* frame = (WinEDA_BasePcbFrame*) aPanel->GetParent(); PCB_SCREEN* screen = frame->GetScreen(); if( frame->m_DisplayPadFill == FILLED ) - fillpad = 1; + drawInfo.m_ShowPadFilled = true; + else + drawInfo.m_ShowPadFilled = false; #if defined(PCBNEW) || defined(__WXMAC__) if( m_Flags & IS_MOVED || !DisplayOpt.DisplayPadFill ) - fillpad = 0; + drawInfo.m_ShowPadFilled = false; #endif if( m_Masque_Layer & LAYER_FRONT ) { - color = brd->GetVisibleElementColor(PAD_FR_VISIBLE); + color = brd->GetVisibleElementColor( PAD_FR_VISIBLE ); } if( m_Masque_Layer & LAYER_BACK ) { - color |= brd->GetVisibleElementColor(PAD_BK_VISIBLE); + color |= brd->GetVisibleElementColor( PAD_BK_VISIBLE ); } if( color == 0 ) /* Not on copper layer */ @@ -124,59 +142,59 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, break; case ADHESIVE_LAYER_BACK: - color = brd->GetLayerColor(ADHESIVE_N_BACK); + color = brd->GetLayerColor( ADHESIVE_N_BACK ); break; case ADHESIVE_LAYER_FRONT: - color = brd->GetLayerColor(ADHESIVE_N_FRONT); + color = brd->GetLayerColor( ADHESIVE_N_FRONT ); break; case SOLDERPASTE_LAYER_BACK: - color = brd->GetLayerColor(SOLDERPASTE_N_BACK); + color = brd->GetLayerColor( SOLDERPASTE_N_BACK ); showActualMaskSize = SOLDERPASTE_N_BACK; break; case SOLDERPASTE_LAYER_FRONT: - color = brd->GetLayerColor(SOLDERPASTE_N_FRONT); + color = brd->GetLayerColor( SOLDERPASTE_N_FRONT ); showActualMaskSize = SOLDERPASTE_N_FRONT; break; case SILKSCREEN_LAYER_BACK: - color = brd->GetLayerColor(SILKSCREEN_N_BACK); + color = brd->GetLayerColor( SILKSCREEN_N_BACK ); break; case SILKSCREEN_LAYER_FRONT: - color = brd->GetLayerColor(SILKSCREEN_N_FRONT); + color = brd->GetLayerColor( SILKSCREEN_N_FRONT ); break; case SOLDERMASK_LAYER_BACK: - color = brd->GetLayerColor(SOLDERMASK_N_BACK); + color = brd->GetLayerColor( SOLDERMASK_N_BACK ); showActualMaskSize = SOLDERMASK_N_BACK; break; case SOLDERMASK_LAYER_FRONT: - color = brd->GetLayerColor(SOLDERMASK_N_FRONT); + color = brd->GetLayerColor( SOLDERMASK_N_FRONT ); showActualMaskSize = SOLDERMASK_N_FRONT; break; case DRAW_LAYER: - color = brd->GetLayerColor(DRAW_N); + color = brd->GetLayerColor( DRAW_N ); break; case COMMENT_LAYER: - color = brd->GetLayerColor(COMMENT_N); + color = brd->GetLayerColor( COMMENT_N ); break; case ECO1_LAYER: - color = brd->GetLayerColor(ECO1_N); + color = brd->GetLayerColor( ECO1_N ); break; case ECO2_LAYER: - color = brd->GetLayerColor(ECO2_N); + color = brd->GetLayerColor( ECO2_N ); break; case EDGE_LAYER: - color = brd->GetLayerColor(EDGE_N); + color = brd->GetLayerColor( EDGE_N ); break; default: @@ -260,7 +278,7 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, { if( IsOnLayer( screen->m_Active_Layer ) ) { - color = brd->GetLayerColor(screen->m_Active_Layer); + color = brd->GetLayerColor( screen->m_Active_Layer ); // In hight contrast mode, and if the active layer is the mask // layer shows the pad size with the mask clearance @@ -285,9 +303,9 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, } - if( draw_mode & GR_SURBRILL ) + if( aDraw_mode & GR_SURBRILL ) { - if( draw_mode & GR_AND ) + if( aDraw_mode & GR_AND ) color &= ~HIGHT_LIGHT_FLAG; else color |= HIGHT_LIGHT_FLAG; @@ -296,24 +314,20 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, if( color & HIGHT_LIGHT_FLAG ) color = ColorRefs[color & MASKCOLOR].m_LightColor; - GRSetDrawMode( DC, draw_mode ); /* mode de trace */ - - /* calcul du centre des pads en coordonnees Ecran : */ - shape_pos = ReturnShapePos(); - ux0 = shape_pos.x - offset.x; - uy0 = shape_pos.y - offset.y; - xc = ux0; - yc = uy0; - - dx = dx0 = m_Size.x >> 1; - dy = dy0 = m_Size.y >> 1; /* demi dim dx et dy */ - - angle = m_Orient; - bool DisplayIsol = DisplayOpt.DisplayPadIsol; if( ( m_Masque_Layer & ALL_CU_LAYERS ) == 0 ) DisplayIsol = FALSE; + + drawInfo.m_DrawMode = aDraw_mode; + drawInfo.m_Color = color; + drawInfo.m_DrawPanel = aPanel; + drawInfo.m_Mask_margin = mask_margin; + drawInfo.m_ShowNCMark = brd->IsElementVisible( PCB_VISIBLE( NO_CONNECTS_VISIBLE ) ); + drawInfo.m_IsPrinting = screen->m_IsPrinting; +#ifndef USE_WX_ZOOM + drawInfo.m_Scale = (double)screen->Scale(1000) / 1000; +#endif SetAlpha( &color, 170 ); /* Get the pad clearance. This has a meaning only for Pcbnew. @@ -321,128 +335,127 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, * there is no net classes so a call to GetClearance() is made only when * needed (never needed in Cvpcb nor in Gerbview) */ - int padClearance = DisplayIsol ? GetClearance() : 0; + drawInfo.m_PadClearance = DisplayIsol ? GetClearance() : 0; + /* Draw the pad number */ + if( frame && !frame->m_DisplayPadNum ) + drawInfo.m_Display_padnum = false; + if( ( DisplayOpt.DisplayNetNamesMode == 0 ) + || ( DisplayOpt.DisplayNetNamesMode == 2 ) ) + drawInfo.m_Display_netname = false; + + // Display net names is restricted to pads that are on the active layer + // in cotranst mode displae + if( !IsOnLayer( screen->m_Active_Layer ) && DisplayOpt.ContrastModeDisplay ) + drawInfo.m_Display_netname = false; + + DrawShape( &aPanel->m_ClipBox, aDC, drawInfo ); +} + + +/** function DrawShape + * basic function to draw a pad. + * used by D_PAD::Draw after calculation of parameters (color, final orientation ...) + * this function can be called to draw a pad on a panel + * even if this panel is not a WinEDA_DrawPanel (for instance on a wxPanel inside the pad editor) + */ +void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) +{ + wxPoint coord[4]; + int rotdx, + delta_cx, delta_cy; + int angle = m_Orient; + + GRSetDrawMode(aDC, aDrawInfo.m_DrawMode ); + + // calculate pad shape position : + wxPoint shape_pos = ReturnShapePos() - aDrawInfo.m_Offset; + + wxSize halfsize = m_Size; + halfsize.x >>= 1; + halfsize.y >>= 1; switch( GetShape() ) { case PAD_CIRCLE: - if( fillpad ) - GRFilledCircle( &panel->m_ClipBox, DC, xc, yc, - dx + mask_margin.x, 0, color, color ); + if( aDrawInfo.m_ShowPadFilled ) + GRFilledCircle( aClipBox, aDC, shape_pos.x, shape_pos.y, + halfsize.x + aDrawInfo.m_Mask_margin.x, 0, + aDrawInfo.m_Color, aDrawInfo.m_Color ); else - GRCircle( &panel->m_ClipBox, DC, xc, yc, dx + mask_margin.x, - m_PadSketchModePenSize, color ); + GRCircle( aClipBox, aDC, shape_pos.x, shape_pos.y, + halfsize.x + aDrawInfo.m_Mask_margin.x, + m_PadSketchModePenSize, aDrawInfo.m_Color ); - if( DisplayIsol ) + if( aDrawInfo.m_PadClearance ) { - GRCircle( &panel->m_ClipBox, - DC, - xc, - yc, - dx + padClearance, + GRCircle( aClipBox, + aDC, shape_pos.x, shape_pos.y, + halfsize.x + aDrawInfo.m_PadClearance, 0, - color ); + aDrawInfo.m_Color ); } break; case PAD_OVAL: - if( dx > dy ) /* horizontal */ + if( halfsize.x > halfsize.y ) /* horizontal */ { - delta_cx = dx - dy; + delta_cx = halfsize.x - halfsize.y; delta_cy = 0; - rotdx = m_Size.y + ( mask_margin.y * 2 ); + rotdx = m_Size.y + ( aDrawInfo.m_Mask_margin.y * 2 ); } else /* vertical */ { delta_cx = 0; - delta_cy = dy - dx; - rotdx = m_Size.x + ( mask_margin.x * 2 ); + delta_cy = halfsize.y - halfsize.x; + rotdx = m_Size.x + ( aDrawInfo.m_Mask_margin.x * 2 ); } RotatePoint( &delta_cx, &delta_cy, angle ); - if( fillpad ) + if( aDrawInfo.m_ShowPadFilled ) { - GRFillCSegm( &panel->m_ClipBox, DC, - ux0 + delta_cx, uy0 + delta_cy, - ux0 - delta_cx, uy0 - delta_cy, - rotdx, color ); + GRFillCSegm( aClipBox, aDC, + shape_pos.x + delta_cx, shape_pos.y + delta_cy, + shape_pos.x - delta_cx, shape_pos.y - delta_cy, + rotdx, aDrawInfo.m_Color ); } else { - GRCSegm( &panel->m_ClipBox, DC, - ux0 + delta_cx, uy0 + delta_cy, - ux0 - delta_cx, uy0 - delta_cy, - rotdx, m_PadSketchModePenSize, color ); + GRCSegm( aClipBox, aDC, + shape_pos.x + delta_cx, shape_pos.y + delta_cy, + shape_pos.x - delta_cx, shape_pos.y - delta_cy, + rotdx, m_PadSketchModePenSize, aDrawInfo.m_Color ); } /* Draw the isolation line. */ - if( DisplayIsol ) + if( aDrawInfo.m_PadClearance ) { - rotdx = rotdx + 2 * padClearance; + rotdx = rotdx + 2 * aDrawInfo.m_PadClearance; - GRCSegm( &panel->m_ClipBox, DC, ux0 + delta_cx, uy0 + delta_cy, - ux0 - delta_cx, uy0 - delta_cy, - rotdx, color ); + GRCSegm( aClipBox, aDC, shape_pos.x + delta_cx, shape_pos.y + delta_cy, + shape_pos.x - delta_cx, shape_pos.y - delta_cy, + rotdx, aDrawInfo.m_Color ); } break; case PAD_RECT: case PAD_TRAPEZOID: - { - int ddx, ddy; - ddx = ( m_DeltaSize.x >> 1 ); - ddy = ( m_DeltaSize.y >> 1 ); + BuildPadPolygon( coord, aDrawInfo.m_Mask_margin, angle ); + for( int ii = 0; ii < 4; ii++ ) + coord[ii] += shape_pos; - coord[0].x = -dx - ddy - mask_margin.x; // lower left - coord[0].y = +dy + ddx + mask_margin.y; + GRClosedPoly( aClipBox, aDC, 4, coord, aDrawInfo.m_ShowPadFilled, + aDrawInfo.m_ShowPadFilled ? 0 : m_PadSketchModePenSize, + aDrawInfo.m_Color, aDrawInfo.m_Color ); - coord[1].x = -dx + ddy - mask_margin.x; // upper left - coord[1].y = -dy - ddx - mask_margin.y; - - coord[2].x = +dx - ddy + mask_margin.x; // upper right - coord[2].y = -dy + ddx - mask_margin.y; - - coord[3].x = +dx + ddy + mask_margin.x; // lower right - coord[3].y = +dy - ddx + mask_margin.y; - - for( ii = 0; ii < 4; ii++ ) + if( aDrawInfo.m_PadClearance ) { - RotatePoint( &coord[ii].x, &coord[ii].y, angle ); - coord[ii].x = coord[ii].x + ux0; - coord[ii].y = coord[ii].y + uy0; + BuildPadPolygon( coord, wxSize(aDrawInfo.m_PadClearance,aDrawInfo.m_PadClearance), angle ); + for( int ii = 0; ii < 4; ii++ ) + coord[ii] += shape_pos; + + GRClosedPoly( aClipBox, aDC, 4, coord, 0, aDrawInfo.m_Color, aDrawInfo.m_Color ); } - - GRClosedPoly( &panel->m_ClipBox, DC, 4, coord, fillpad, - fillpad ? 0 : m_PadSketchModePenSize, color, color ); - - if( DisplayIsol ) - { - dx += padClearance; - dy += padClearance; - - coord[0].x = -dx - ddy; - coord[0].y = dy + ddx; - - coord[1].x = -dx + ddy; - coord[1].y = -dy - ddx; - - coord[2].x = dx - ddy; - coord[2].y = -dy + ddx; - - coord[3].x = dx + ddy; - coord[3].y = dy - ddx; - - for( ii = 0; ii < 4; ii++ ) - { - RotatePoint( &coord[ii].x, &coord[ii].y, angle ); - coord[ii].x = coord[ii].x + ux0; - coord[ii].y = coord[ii].y + uy0; - } - - GRClosedPoly( &panel->m_ClipBox, DC, 4, coord, 0, color, color ); - } - } - break; + break; default: @@ -450,26 +463,23 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, } /* Draw the pad hole */ - int cx0 = m_Pos.x - offset.x; - int cy0 = m_Pos.y - offset.y; + wxPoint holepos = m_Pos - aDrawInfo.m_Offset; int hole = m_Drill.x >> 1; - if( fillpad && hole ) + if( aDrawInfo.m_ShowPadFilled && hole ) { bool blackpenstate = false; - if( screen->m_IsPrinting ) + if( aDrawInfo.m_IsPrinting ) { blackpenstate = GetGRForceBlackPenState(); GRForceBlackPen( false ); - color = g_DrawBgColor; + aDrawInfo.m_HoleColor = g_DrawBgColor; } - else - color = BLACK; // or DARKGRAY; - if( draw_mode != GR_XOR ) - GRSetDrawMode( DC, GR_COPY ); + if( aDrawInfo.m_DrawMode != GR_XOR ) + GRSetDrawMode( aDC, GR_COPY ); else - GRSetDrawMode( DC, GR_XOR ); + GRSetDrawMode( aDC, GR_XOR ); switch( m_DrillShape ) { @@ -478,78 +488,71 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, #ifdef USE_WX_ZOOM if( DC->LogicalToDeviceXRel( hole ) > 1 ) #else - if( screen->Scale( hole ) > 1 ) /* draw hole if its size is enough */ + if( aDrawInfo.m_Scale*hole > 1 ) /* draw hole if its size is enough */ #endif - GRFilledCircle( &panel->m_ClipBox, DC, cx0, cy0, hole, 0, - color, color ); + + GRFilledCircle( aClipBox, aDC, holepos.x, holepos.y, hole, 0, + aDrawInfo.m_Color, aDrawInfo.m_HoleColor ); break; case PAD_OVAL: - dx = m_Drill.x >> 1; - dy = m_Drill.y >> 1; + halfsize.x = m_Drill.x >> 1; + halfsize.y = m_Drill.y >> 1; if( m_Drill.x > m_Drill.y ) /* horizontal */ { - delta_cx = dx - dy; + delta_cx = halfsize.x - halfsize.y; delta_cy = 0; rotdx = m_Drill.y; } else /* vertical */ { delta_cx = 0; - delta_cy = dy - dx; + delta_cy = halfsize.y - halfsize.x; rotdx = m_Drill.x; } RotatePoint( &delta_cx, &delta_cy, angle ); - GRFillCSegm( &panel->m_ClipBox, DC, cx0 + delta_cx, cy0 + delta_cy, - cx0 - delta_cx, cy0 - delta_cy, rotdx, color ); + GRFillCSegm( aClipBox, aDC, holepos.x + delta_cx, holepos.y + delta_cy, + holepos.x - delta_cx, holepos.y - delta_cy, rotdx, + aDrawInfo.m_HoleColor ); break; default: break; } - if( screen->m_IsPrinting ) + if( aDrawInfo.m_IsPrinting ) GRForceBlackPen( blackpenstate ); } - GRSetDrawMode( DC, draw_mode ); + GRSetDrawMode( aDC, aDrawInfo.m_DrawMode ); /* Draw "No connect" ( / or \ or cross X ) if necessary. : */ - if( m_Netname.IsEmpty() && brd->IsElementVisible( PCB_VISIBLE(NO_CONNECTS_VISIBLE) ) ) + if( m_Netname.IsEmpty() && aDrawInfo.m_ShowNCMark ) { - dx0 = MIN( dx0, dy0 ); + int dx0 = MIN( halfsize.x, halfsize.y ); int nc_color = BLUE; if( m_Masque_Layer & LAYER_FRONT ) /* Draw \ */ - GRLine( &panel->m_ClipBox, DC, cx0 - dx0, cy0 - dx0, - cx0 + dx0, cy0 + dx0, 0, nc_color ); + GRLine( aClipBox, aDC, holepos.x - dx0, holepos.y - dx0, + holepos.x + dx0, holepos.y + dx0, 0, nc_color ); if( m_Masque_Layer & LAYER_BACK ) /* Draw / */ - GRLine( &panel->m_ClipBox, DC, cx0 + dx0, cy0 - dx0, - cx0 - dx0, cy0 + dx0, 0, nc_color ); + GRLine( aClipBox, aDC, holepos.x + dx0, holepos.y - dx0, + holepos.x - dx0, holepos.y + dx0, 0, nc_color ); } /* Draw the pad number */ - bool display_padnum = true; - if( frame && !frame->m_DisplayPadNum ) - display_padnum = false; - - bool display_netname = true; - if( ( DisplayOpt.DisplayNetNamesMode == 0 ) - || ( DisplayOpt.DisplayNetNamesMode == 2 ) ) - display_netname = false; - - if( !display_padnum && !display_netname ) + if( !aDrawInfo.m_Display_padnum && !aDrawInfo.m_Display_netname ) return; - wxPoint tpos0 = wxPoint( ux0, uy0 ); // Position of the centre of text + wxPoint tpos0 = shape_pos; // Position of the centre of text wxPoint tpos = tpos0; wxSize AreaSize; // size of text area, normalized to // AreaSize.y < AreaSize.x int shortname_len = m_ShortNetname.Len(); - if( !display_netname ) + if( !aDrawInfo.m_Display_netname ) shortname_len = 0; if( GetShape() == PAD_CIRCLE ) angle = 0; @@ -567,12 +570,12 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, AreaSize.y /= 2; // Text used only the upper area of the // pad. The lower area displays the net // name - tpos.y -= AreaSize.y / 2; + tpos.y -= AreaSize.y / 2; } // Calculate the position of text, that is the middle point of the upper // area of the pad - RotatePoint( &tpos, wxPoint( ux0, uy0 ), angle ); + RotatePoint( &tpos, shape_pos, angle ); /* Draw text with an angle between -90 deg and + 90 deg */ int t_angle = angle; @@ -586,7 +589,7 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, wxString buffer; int tsize; - if( display_padnum ) + if( aDrawInfo.m_Display_padnum ) { ReturnStringPadName( buffer ); int numpad_len = buffer.Len(); @@ -598,14 +601,12 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, #ifdef USE_WX_ZOOM if( DC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable when size too small. #else - if( screen->Scale( tsize ) >= CHAR_SIZE_MIN ) // Not drawable when size too small. + if( aDrawInfo.m_Scale*tsize >= CHAR_SIZE_MIN ) // Not drawable when size too small. #endif { - tsize = (int) ( tsize * 0.8 ); // reserve room for - // marges and segments - // thickness - - DrawGraphicText( panel, DC, tpos, WHITE, buffer, t_angle, + // tsize reserve room for marges and segments thickness + tsize = (int) ( tsize * 0.8 ); + DrawGraphicText( aDrawInfo.m_DrawPanel, aDC, tpos, WHITE, buffer, t_angle, wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false, false ); @@ -620,24 +621,140 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, tsize = min( AreaSize.y, AreaSize.x / shortname_len ); #ifdef USE_WX_ZOOM - if( DC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable in size too small. + if( DC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable in size too small. #else - if( screen->Scale( tsize ) >= CHAR_SIZE_MIN ) // Not drawable in size too small. + if( aDrawInfo.m_Scale*tsize >= CHAR_SIZE_MIN ) // Not drawable in size too small. #endif { - if( !( !IsOnLayer( screen->m_Active_Layer ) - && DisplayOpt.ContrastModeDisplay ) ) - { - tpos = tpos0; - if( display_padnum ) - tpos.y += AreaSize.y / 2; - RotatePoint( &tpos, wxPoint( ux0, uy0 ), angle ); + tpos = tpos0; + if( aDrawInfo.m_Display_padnum ) + tpos.y += AreaSize.y / 2; + RotatePoint( &tpos, shape_pos, angle ); - tsize = (int) ( tsize * 0.8 ); // reserve room for marges and - // segments thickness - DrawGraphicText( panel, DC, tpos, WHITE, m_ShortNetname, t_angle, - wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER, - GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false ); - } + // tsize reserve room for marges and segments thickness + tsize = (int) ( tsize * 0.8 ); + DrawGraphicText( aDrawInfo.m_DrawPanel, aDC, tpos, WHITE, m_ShortNetname, t_angle, + wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER, + GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false ); + } +} + +/** function BuildPadPolygon + * Has meaning only for polygonal pads (trapeziod and rectangular) + * Build the Corner list of the polygonal shape, + * depending on shape, extra size (clearance ...) and orientation + * @param aCoord[4] = a buffer to fill. + * @param aInflateValue = wxSize: the clearance or margin value. value > 0: inflate, < 0 deflate + * @param aRotation = full rotation of the polygon, usually m_Orient + */ +void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, int aRotation ) +{ + if( (GetShape() != PAD_RECT) && (GetShape() != PAD_TRAPEZOID) ) + return; + + wxSize delta; + wxSize halfsize; + + halfsize.x = m_Size.x >> 1; + halfsize.y = m_Size.y >> 1; + + /* For rectangular shapes, inflate is easy + * Also if inflate values for X and Y directions are different + * the simplified inflate calculation is used for PAD_TRAPEZOID + * due to the complexity of offsetting a polygon with different values in X and Y + * (I even no be sure this has meaning) + */ + if( GetShape() == PAD_RECT ) + { + halfsize += aInflateValue; + // Verify if do not deflate more than than size + // Only possible for inflate negative values. + if( halfsize.x < 0 ) + halfsize.x = 0; + if( halfsize.y < 0 ) + halfsize.y = 0; + } + else + { + delta.x = ( m_DeltaSize.x >> 1 ); + delta.y = ( m_DeltaSize.y >> 1 ); + // be sure delta values are not to large + if( (delta.x < 0) && (delta.x <= -halfsize.y)) + delta.x = -halfsize.y+1; + if( (delta.x > 0) && (delta.x >= halfsize.y)) + delta.x = halfsize.y-1; + if( (delta.y < 0) && (delta.y <= -halfsize.x)) + delta.y = -halfsize.x+1; + if( (delta.y > 0) && (delta.y >= halfsize.x)) + delta.y = halfsize.x-1; + } + + // Build the basic rectangular or trapezoid shape + aCoord[0].x = -halfsize.x - delta.y; // lower left + aCoord[0].y = +halfsize.y + delta.x; + + aCoord[1].x = -halfsize.x + delta.y; // upper left + aCoord[1].y = -halfsize.y - delta.x; + + aCoord[2].x = +halfsize.x - delta.y; // upper right + aCoord[2].y = -halfsize.y + delta.x; + + aCoord[3].x = +halfsize.x + delta.y; // lower right + aCoord[3].y = +halfsize.y - delta.x; + + // Offsetting the trapezoid shape id needed + // It is assumed delta.x or/and delta.y == 0 + if( GetShape() == PAD_TRAPEZOID && (aInflateValue.x != 0 || aInflateValue.y != 0) ) + { + double angle; + wxSize corr; + if( delta.y ) // lower and upper segment is horizontal + { + // Calculate angle of left (or right) segment with vertical axis + angle = atan2( delta.y, halfsize.y ); + + // left and right sides are moved by aInflateValue.x in their perpendicular direction + // We must calculate the corresponding displacement on the horizontal axis + // that is delta.x +- corr.x depending on the corner + corr.x = wxRound(tan(angle) * aInflateValue.x); + delta.x = wxRound( aInflateValue.x/cos(angle)); + // Horizontal sides are moved up and down by aInflateValue.y + delta.y = aInflateValue.y; + // corr.y = 0 by the constructor + } + else if( delta.x ) // left and right segment is vertical + { + // Calculate angle of lower (or upper) segment with horizontal axis + angle = atan2( delta.x, halfsize.x); + // lower and upper sides are moved by aInflateValue.x in their perpendicular direction + // We must calculate the corresponding displacement on the vertical axis + // that is delta.y +- corr.y depending on the corner + corr.y = wxRound(tan(angle) * aInflateValue.y); + delta.y = wxRound( aInflateValue.y/cos(angle)); + // Vertical sides are moved left and right by aInflateValue.x + delta.x = aInflateValue.x; + // corr.x = 0 by the constructor + } + else // the trapezoid is a rectangle + { + delta = aInflateValue; // Do nothing. + } + aCoord[0].x += -delta.x - corr.x; // lower left + aCoord[0].y += delta.y + corr.y; + + aCoord[1].x += -delta.x + corr.x; // upper left + aCoord[1].y += -delta.y - corr.y; + + aCoord[2].x += delta.x - corr.x; // upper right + aCoord[2].y += -delta.y + corr.y; + + aCoord[3].x += delta.x + corr.x; // lower right + aCoord[3].y += delta.y - corr.y; + } + + if( aRotation ) + { + for( int ii = 0; ii < 4; ii++ ) + RotatePoint( &aCoord[ii], aRotation ); } } diff --git a/pcbnew/dialog_gendrill_base.cpp b/pcbnew/dialog_gendrill_base.cpp index bdf3678282..1e7ae02589 100644 --- a/pcbnew/dialog_gendrill_base.cpp +++ b/pcbnew/dialog_gendrill_base.cpp @@ -58,7 +58,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con int m_Choice_Drill_MapNChoices = sizeof( m_Choice_Drill_MapChoices ) / sizeof( wxString ); m_Choice_Drill_Map = new wxRadioBox( this, wxID_ANY, _("Drill Sheet:"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_MapNChoices, m_Choice_Drill_MapChoices, 1, wxRA_SPECIFY_COLS ); m_Choice_Drill_Map->SetSelection( 0 ); - m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PS, HPGL or others formats") ); + m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PS, HPGL or other formats") ); bMiddleBoxSizer->Add( m_Choice_Drill_Map, 0, wxALL|wxEXPAND, 5 ); diff --git a/pcbnew/dialog_gendrill_base.fbp b/pcbnew/dialog_gendrill_base.fbp index b291a58cb8..21201733c9 100644 --- a/pcbnew/dialog_gendrill_base.fbp +++ b/pcbnew/dialog_gendrill_base.fbp @@ -335,7 +335,7 @@ wxRA_SPECIFY_COLS - Creates a drill map in PS, HPGL or others formats + Creates a drill map in PS, HPGL or other formats diff --git a/pcbnew/dialog_pad_properties.cpp b/pcbnew/dialog_pad_properties.cpp index 4c14b49456..9fac671993 100644 --- a/pcbnew/dialog_pad_properties.cpp +++ b/pcbnew/dialog_pad_properties.cpp @@ -9,13 +9,10 @@ #include "confirm.h" #include "pcbnew.h" #include "trigo.h" - -/* Local variables */ -static wxString Current_PadNetName; - +#include #define NBSHAPES 4 -int CodeShape[NBSHAPES] = /* Pad shapes. */ +int CodeShape[NBSHAPES] = // list of pad shapes. { PAD_CIRCLE, PAD_OVAL, PAD_RECT, PAD_TRAPEZOID }; @@ -27,7 +24,7 @@ int CodeType[NBTYPES] = PAD_STANDARD, PAD_SMD, PAD_CONN, PAD_HOLE_NOT_PLATED }; -// Default mask layers for pads according to the pad type +// Default mask layers setup for pads according to the pad type static long Std_Pad_Layers[NBTYPES] = { // PAD_STANDARD: @@ -46,54 +43,135 @@ static long Std_Pad_Layers[NBTYPES] = #include "dialog_pad_properties_base.h" +extern int ChangeSideMaskLayer( int masque ); -/********************************************************************/ -/* class DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE, */ -/* created by wxFormBuilder */ -/********************************************************************/ + +/** + * class DIALOG_PAD_PROPERTIES, derived from DIALOG_PAD_PROPERTIES_BASE, + * created by wxFormBuilder + */ class DIALOG_PAD_PROPERTIES : public DIALOG_PAD_PROPERTIES_BASE { private: WinEDA_BasePcbFrame* m_Parent; - D_PAD* m_CurrentPad; - BOARD * m_Board; + D_PAD* m_CurrentPad; // Pad currently edited + D_PAD* m_dummyPad; // a working copy used to show changes + BOARD* m_Board; + bool m_isFlipped; /* true if the parent footprint (therefore pads) is flipped (mirrored) + * in this case, some Y coordinates values must be negated + */ + bool m_canUpdate; public: DIALOG_PAD_PROPERTIES( WinEDA_BasePcbFrame* parent, D_PAD* Pad ); + ~DIALOG_PAD_PROPERTIES() + { + delete m_dummyPad; + } + + private: - void InitDialog( ); + void initValues(); void OnPadShapeSelection( wxCommandEvent& event ); void OnDrillShapeSelected( wxCommandEvent& event ); void PadOrientEvent( wxCommandEvent& event ); void PadTypeSelected( wxCommandEvent& event ); void PadPropertiesAccept( wxCommandEvent& event ); void SetPadLayersList( long layer_mask ); - void OnCancelButtonClick( wxCommandEvent& event ); + void OnSetLayer( wxCommandEvent& event ); + void OnCancelButtonClick( wxCommandEvent& event ); + void OnPaintShowPanel( wxPaintEvent& event ); + bool TransfertDataToPad( D_PAD* aPad, bool aPromptOnError = false ); + void OnValuesChanged( wxCommandEvent& event ); }; +void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event ) +{ + wxPaintDC dc( m_panelShowPad ); + PAD_DRAWINFO drawInfo; + + int color = 0; + + if( m_dummyPad->m_Masque_Layer & LAYER_FRONT ) + { + color = m_Board->GetVisibleElementColor( PAD_FR_VISIBLE ); + } + + if( m_dummyPad->m_Masque_Layer & LAYER_BACK ) + { + color |= m_Board->GetVisibleElementColor( PAD_BK_VISIBLE ); + } + + if( color == 0 ) + color = LIGHTGRAY; + + drawInfo.m_Color = color; + drawInfo.m_HoleColor = DARKGRAY; + drawInfo.m_Offset = m_dummyPad->m_Pos; + drawInfo.m_Display_padnum = true; + drawInfo.m_Display_netname = true; + + // Shows the local pad clearance + drawInfo.m_PadClearance = m_dummyPad->m_LocalClearance; + + wxSize dc_size = dc.GetSize(); + dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 ); + + // Calculate a suitable scale to fit the available draw area + double scale = (double) dc_size.x / (m_dummyPad->m_Size.x + m_dummyPad->m_LocalClearance); + double altscale = (double) dc_size.y / (m_dummyPad->m_Size.y + m_dummyPad->m_LocalClearance); + scale = MIN( scale, altscale ); + + // Give a margin + scale *= 0.7; + dc.SetUserScale( scale, scale ); + drawInfo.m_Scale = scale; + +#ifndef USE_WX_ZOOM + wxPoint org = ActiveScreen->m_DrawOrg; + wxPoint strt = ActiveScreen->m_StartVisu; + int pzoom = ActiveScreen->GetZoom(); + ActiveScreen->m_DrawOrg = wxPoint( 0, 0 ); + ActiveScreen->m_StartVisu = wxPoint( 0, 0 ); + + // Actual scaling factor is 10/Zoom + // We need a scale 1 , and therefore zoom = 10 + ActiveScreen->SetZoom( 10 ); +#endif + + m_dummyPad->DrawShape( NULL, &dc, drawInfo ); + +#ifndef USE_WX_ZOOM + ActiveScreen->m_DrawOrg = org; + ActiveScreen->m_StartVisu = strt; + ActiveScreen->SetZoom( pzoom ); +#endif + event.Skip(); +} + + /*******************************************************************************************/ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( WinEDA_BasePcbFrame* parent, D_PAD* Pad ) : DIALOG_PAD_PROPERTIES_BASE( parent ) /*******************************************************************************************/ { - m_Parent = parent; + m_canUpdate = false; + m_Parent = parent; m_CurrentPad = Pad; - m_Board = m_Parent->GetBoard(); + m_Board = m_Parent->GetBoard(); + m_dummyPad = new D_PAD( (MODULE*) NULL ); if( m_CurrentPad ) - { - Current_PadNetName = m_CurrentPad->GetNetname(); - g_Current_PadName = m_CurrentPad->ReturnStringPadName(); - } + m_dummyPad->Copy( m_CurrentPad ); + else + m_dummyPad->Copy( &g_Pad_Master ); - InitDialog( ); - if( GetSizer() ) - { - GetSizer()->SetSizeHints( this ); - } + initValues(); + GetSizer()->SetSizeHints( this ); Center(); + m_canUpdate = true; } @@ -105,22 +183,38 @@ void WinEDA_BasePcbFrame::InstallPadOptionsFrame( D_PAD* Pad ) } -/**************************************************************/ -void DIALOG_PAD_PROPERTIES::InitDialog( ) -/**************************************************************/ +/***************************************/ +void DIALOG_PAD_PROPERTIES::initValues() +/***************************************/ { - int tmp; - wxCommandEvent cmd_event; - int internalUnits = m_Parent->m_InternalUnits; - wxString msg; - SetFocus(); // Required under wxGTK if we want to demiss the dialog with the ESC key - m_PadNumCtrl->SetValue( g_Current_PadName ); - m_PadNetNameCtrl->SetValue( Current_PadNetName ); - D_PAD* pad = m_CurrentPad; - if( pad == NULL ) - pad = &g_Pad_Master; + int tmp; + int internalUnits = m_Parent->m_InternalUnits; + wxString msg; + m_isFlipped = false; + if( m_CurrentPad ) + { + MODULE* Module = (MODULE*) m_CurrentPad->GetParent(); + if( Module->GetLayer() == LAYER_N_BACK ) + { + m_isFlipped = true; + m_staticModuleSideValue->SetLabel( _( "Back side (footprint is mirrored)" ) ); + } + msg.Printf( wxT( "%.1f" ), (double) Module->m_Orient / 10 ); + m_staticModuleRotValue->SetLabel( msg ); + } + + if( m_isFlipped ) + { + NEGATE( m_dummyPad->m_Offset.y ); + NEGATE( m_dummyPad->m_DeltaSize.y ); + /* flip pads layers*/ + m_dummyPad->m_Masque_Layer = ChangeSideMaskLayer( m_dummyPad->m_Masque_Layer ); + } + + m_PadNumCtrl->SetValue( m_dummyPad->ReturnStringPadName() ); + m_PadNetNameCtrl->SetValue( m_dummyPad->GetNetname() ); // Display current unit name in dialog: m_PadPosX_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) ); @@ -134,76 +228,83 @@ void DIALOG_PAD_PROPERTIES::InitDialog( ) m_PadShapeDeltaX_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) ); m_PadShapeDeltaY_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) ); m_NetClearanceUnits->SetLabel( GetUnitsLabel( g_UserUnit ) ); + // Display current pad masks clearances units m_NetClearanceUnits->SetLabel( GetUnitsLabel( g_UserUnit ) ); m_SolderMaskMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) ); m_SolderPasteMarginUnits->SetLabel( GetUnitsLabel( g_UserUnit ) ); // Display current pad parameters units: - PutValueInLocalUnits( *m_PadPosition_X_Ctrl, pad->m_Pos.x, internalUnits ); - PutValueInLocalUnits( *m_PadPosition_Y_Ctrl, pad->m_Pos.y, internalUnits ); + PutValueInLocalUnits( *m_PadPosition_X_Ctrl, m_dummyPad->m_Pos.x, internalUnits ); + PutValueInLocalUnits( *m_PadPosition_Y_Ctrl, m_dummyPad->m_Pos.y, internalUnits ); - PutValueInLocalUnits( *m_PadDrill_X_Ctrl, pad->m_Drill.x, internalUnits ); - PutValueInLocalUnits( *m_PadDrill_Y_Ctrl, pad->m_Drill.y, internalUnits ); + PutValueInLocalUnits( *m_PadDrill_X_Ctrl, m_dummyPad->m_Drill.x, internalUnits ); + PutValueInLocalUnits( *m_PadDrill_Y_Ctrl, m_dummyPad->m_Drill.y, internalUnits ); - PutValueInLocalUnits( *m_ShapeSize_X_Ctrl, pad->m_Size.x, internalUnits ); - PutValueInLocalUnits( *m_ShapeSize_Y_Ctrl, pad->m_Size.y, internalUnits ); + PutValueInLocalUnits( *m_ShapeSize_X_Ctrl, m_dummyPad->m_Size.x, internalUnits ); + PutValueInLocalUnits( *m_ShapeSize_Y_Ctrl, m_dummyPad->m_Size.y, internalUnits ); - PutValueInLocalUnits( *m_ShapeOffset_X_Ctrl, pad->m_Offset.x, internalUnits ); - PutValueInLocalUnits( *m_ShapeOffset_Y_Ctrl, pad->m_Offset.y, internalUnits ); + PutValueInLocalUnits( *m_ShapeOffset_X_Ctrl, m_dummyPad->m_Offset.x, internalUnits ); + PutValueInLocalUnits( *m_ShapeOffset_Y_Ctrl, m_dummyPad->m_Offset.y, internalUnits ); - PutValueInLocalUnits( *m_ShapeDelta_X_Ctrl, pad->m_DeltaSize.x, internalUnits ); - PutValueInLocalUnits( *m_ShapeDelta_Y_Ctrl, pad->m_DeltaSize.y, internalUnits ); + PutValueInLocalUnits( *m_ShapeDelta_X_Ctrl, m_dummyPad->m_DeltaSize.x, internalUnits ); + PutValueInLocalUnits( *m_ShapeDelta_Y_Ctrl, m_dummyPad->m_DeltaSize.y, internalUnits ); + + PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_dummyPad->m_LocalClearance, internalUnits ); + PutValueInLocalUnits( *m_SolderMaskMarginCtrl, + m_dummyPad->m_LocalSolderMaskMargin, + internalUnits ); - PutValueInLocalUnits( *m_NetClearanceValueCtrl, pad->m_LocalClearance, internalUnits ); - PutValueInLocalUnits( *m_SolderMaskMarginCtrl, pad->m_LocalSolderMaskMargin, internalUnits ); // These 2 parameters are usually < 0, so prepare entering a negative value, if current is 0 - PutValueInLocalUnits( *m_SolderPasteMarginCtrl, pad->m_LocalSolderPasteMargin, internalUnits ); - if( pad->m_LocalSolderPasteMargin == 0 ) - m_SolderPasteMarginCtrl->SetValue( wxT("-") + m_SolderPasteMarginCtrl->GetValue() ); - msg.Printf( wxT( "%.1f" ), pad->m_LocalSolderPasteMarginRatio * 100.0 ); - if( pad->m_LocalSolderPasteMarginRatio == 0.0 && - msg[0] == '0') // Sometimes Printf add a sign if the value is small - m_SolderPasteMarginRatioCtrl->SetValue( wxT("-") + msg ); + PutValueInLocalUnits( *m_SolderPasteMarginCtrl, + m_dummyPad->m_LocalSolderPasteMargin, + internalUnits ); + if( m_dummyPad->m_LocalSolderPasteMargin == 0 ) + m_SolderPasteMarginCtrl->SetValue( wxT( "-" ) + m_SolderPasteMarginCtrl->GetValue() ); + msg.Printf( wxT( "%.1f" ), m_dummyPad->m_LocalSolderPasteMarginRatio * 100.0 ); + + if( m_dummyPad->m_LocalSolderPasteMarginRatio == 0.0 + && msg[0] == '0' ) // Sometimes Printf add a sign if the value is small + m_SolderPasteMarginRatioCtrl->SetValue( wxT( "-" ) + msg ); else m_SolderPasteMarginRatioCtrl->SetValue( msg ); if( m_CurrentPad ) { MODULE* Module = (MODULE*) m_CurrentPad->GetParent(); - tmp = m_CurrentPad->m_Orient - Module->m_Orient; + m_dummyPad->m_Orient = m_CurrentPad->m_Orient - Module->m_Orient; + if( m_isFlipped ) + NEGATE( m_dummyPad->m_Orient ); } - else - tmp = g_Pad_Master.m_Orient; + + // adjust rotation agngle to -1800 to 1800 in internal units (0.1 deg) + NORMALIZE_ANGLE_180( m_dummyPad->m_Orient ); + + // Set layers used by this pad: : + SetPadLayersList( m_dummyPad->m_Masque_Layer ); + msg.Clear(); msg << tmp; m_PadOrientCtrl->SetValue( msg ); - // Pad Orient - switch( tmp ) + switch( m_dummyPad->m_Orient ) { case 0: m_PadOrient->SetSelection( 0 ); - m_PadOrientCtrl->Enable( false ); break; - case - 2700: case 900: m_PadOrient->SetSelection( 1 ); - m_PadOrientCtrl->Enable( false ); break; case - 900: - case 2700: m_PadOrient->SetSelection( 2 ); - m_PadOrientCtrl->Enable( false ); break; case 1800: case - 1800: m_PadOrient->SetSelection( 3 ); - m_PadOrientCtrl->Enable( false ); break; default: @@ -211,7 +312,7 @@ void DIALOG_PAD_PROPERTIES::InitDialog( ) break; } - switch( pad->m_PadShape ) + switch( m_dummyPad->m_PadShape ) { default: case PAD_CIRCLE: @@ -231,51 +332,48 @@ void DIALOG_PAD_PROPERTIES::InitDialog( ) break; } - cmd_event.SetId( m_PadShape->GetSelection() ); - OnPadShapeSelection( cmd_event ); + msg.Printf( wxT( "%d" ), m_dummyPad->m_Orient ); + m_PadOrientCtrl->SetValue( msg ); // Selection du type - tmp = pad->m_Attribut; + tmp = m_dummyPad->m_Attribut; m_PadType->SetSelection( 0 ); for( int ii = 0; ii < NBTYPES; ii++ ) { if( CodeType[ii] == tmp ) { - m_PadType->SetSelection( ii ); break; + m_PadType->SetSelection( ii ); + break; } } - if( pad->m_DrillShape != PAD_OVAL ) + if( m_dummyPad->m_DrillShape != PAD_OVAL ) m_DrillShapeCtrl->SetSelection( 0 ); else m_DrillShapeCtrl->SetSelection( 1 ); - cmd_event.SetId( m_DrillShapeCtrl->GetSelection() ); - OnDrillShapeSelected( cmd_event ); - - // Set layers used by this pad: : - if( m_CurrentPad ) - SetPadLayersList( m_CurrentPad->m_Masque_Layer ); - else - { - cmd_event.SetId( m_PadType->GetSelection() ); - PadTypeSelected( cmd_event ); - } // Setup layers names from board - m_PadLayerCu->SetLabel(m_Board->GetLayerName(LAYER_N_BACK)); - m_PadLayerCmp->SetLabel(m_Board->GetLayerName(LAYER_N_FRONT)); + m_PadLayerCu->SetLabel( m_Board->GetLayerName( LAYER_N_BACK ) ); + m_PadLayerCmp->SetLabel( m_Board->GetLayerName( LAYER_N_FRONT ) ); - m_PadLayerAdhCmp->SetLabel(m_Board->GetLayerName( ADHESIVE_N_FRONT )); - m_PadLayerAdhCu->SetLabel(m_Board->GetLayerName( ADHESIVE_N_BACK )); - m_PadLayerPateCmp->SetLabel(m_Board->GetLayerName( SOLDERPASTE_N_FRONT )); - m_PadLayerPateCu->SetLabel(m_Board->GetLayerName(SOLDERPASTE_N_BACK )); - m_PadLayerSilkCmp->SetLabel(m_Board->GetLayerName( SILKSCREEN_N_FRONT )); - m_PadLayerSilkCu->SetLabel(m_Board->GetLayerName( SILKSCREEN_N_BACK )); - m_PadLayerMaskCmp->SetLabel(m_Board->GetLayerName( SOLDERMASK_N_FRONT )); - m_PadLayerMaskCu->SetLabel(m_Board->GetLayerName( SOLDERMASK_N_BACK )); - m_PadLayerECO1->SetLabel(m_Board->GetLayerName( ECO1_N )); - m_PadLayerECO2->SetLabel(m_Board->GetLayerName( ECO2_N)); - m_PadLayerDraft->SetLabel(m_Board->GetLayerName( DRAW_N )); + m_PadLayerAdhCmp->SetLabel( m_Board->GetLayerName( ADHESIVE_N_FRONT ) ); + m_PadLayerAdhCu->SetLabel( m_Board->GetLayerName( ADHESIVE_N_BACK ) ); + m_PadLayerPateCmp->SetLabel( m_Board->GetLayerName( SOLDERPASTE_N_FRONT ) ); + m_PadLayerPateCu->SetLabel( m_Board->GetLayerName( SOLDERPASTE_N_BACK ) ); + m_PadLayerSilkCmp->SetLabel( m_Board->GetLayerName( SILKSCREEN_N_FRONT ) ); + m_PadLayerSilkCu->SetLabel( m_Board->GetLayerName( SILKSCREEN_N_BACK ) ); + m_PadLayerMaskCmp->SetLabel( m_Board->GetLayerName( SOLDERMASK_N_FRONT ) ); + m_PadLayerMaskCu->SetLabel( m_Board->GetLayerName( SOLDERMASK_N_BACK ) ); + m_PadLayerECO1->SetLabel( m_Board->GetLayerName( ECO1_N ) ); + m_PadLayerECO2->SetLabel( m_Board->GetLayerName( ECO2_N ) ); + m_PadLayerDraft->SetLabel( m_Board->GetLayerName( DRAW_N ) ); + + /* All init are done, + * Update some dialog widgets state (Enable/disable options): + */ + wxCommandEvent cmd_event; + OnPadShapeSelection( cmd_event ); + OnDrillShapeSelected( cmd_event ); } @@ -309,6 +407,9 @@ void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event ) m_ShapeSize_Y_Ctrl->Enable( true ); break; } + + TransfertDataToPad( m_dummyPad ); + m_panelShowPad->Refresh(); } @@ -316,24 +417,30 @@ void DIALOG_PAD_PROPERTIES::OnPadShapeSelection( wxCommandEvent& event ) void DIALOG_PAD_PROPERTIES::OnDrillShapeSelected( wxCommandEvent& event ) /**********************************************************************/ { - if ( (m_PadType->GetSelection() == 1) || (m_PadType->GetSelection() == 2) ) - { // pad type = SMD or CONN: no hole allowed + if( (m_PadType->GetSelection() == 1) || (m_PadType->GetSelection() == 2) ) + { + // pad type = SMD or CONN: no hole allowed m_PadDrill_X_Ctrl->Enable( false ); m_PadDrill_Y_Ctrl->Enable( false ); - return; } - switch( m_DrillShapeCtrl->GetSelection() ) + else { - case 0: //CIRCLE: - m_PadDrill_X_Ctrl->Enable( true ); - m_PadDrill_Y_Ctrl->Enable( false ); - break; + switch( m_DrillShapeCtrl->GetSelection() ) + { + case 0: //CIRCLE: + m_PadDrill_X_Ctrl->Enable( true ); + m_PadDrill_Y_Ctrl->Enable( false ); + break; - case 1: //OVALE: - m_PadDrill_X_Ctrl->Enable( true ); - m_PadDrill_Y_Ctrl->Enable( true ); - break; + case 1: //OVALE: + m_PadDrill_X_Ctrl->Enable( true ); + m_PadDrill_Y_Ctrl->Enable( true ); + break; + } } + + TransfertDataToPad( m_dummyPad ); + m_panelShowPad->Refresh(); } @@ -344,29 +451,31 @@ void DIALOG_PAD_PROPERTIES::PadOrientEvent( wxCommandEvent& event ) switch( m_PadOrient->GetSelection() ) { case 0: - m_PadOrientCtrl->SetValue( wxT( "0" ) ); - m_PadOrientCtrl->Enable( false ); + m_dummyPad->m_Orient = 0; break; case 1: - m_PadOrientCtrl->SetValue( wxT( "900" ) ); - m_PadOrientCtrl->Enable( false ); + m_dummyPad->m_Orient = 900; break; case 2: - m_PadOrientCtrl->SetValue( wxT( "2700" ) ); - m_PadOrientCtrl->Enable( false ); + m_dummyPad->m_Orient = -900; break; case 3: - m_PadOrientCtrl->SetValue( wxT( "1800" ) ); - m_PadOrientCtrl->Enable( false ); + m_dummyPad->m_Orient = 1800; break; default: - m_PadOrientCtrl->Enable( true ); break; } + + wxString msg; + msg.Printf( wxT( "%d" ), m_dummyPad->m_Orient ); + m_PadOrientCtrl->SetValue( msg ); + + TransfertDataToPad( m_dummyPad ); + m_panelShowPad->Refresh(); } @@ -388,7 +497,7 @@ void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event ) SetPadLayersList( layer_mask ); // Enable/disable drill dialog items: - event.SetId(m_DrillShapeCtrl->GetSelection()); + event.SetId( m_DrillShapeCtrl->GetSelection() ); OnDrillShapeSelected( event ); } @@ -424,6 +533,14 @@ void DIALOG_PAD_PROPERTIES::SetPadLayersList( long layer_mask ) } +// Called when select/deselect a layer. +void DIALOG_PAD_PROPERTIES::OnSetLayer( wxCommandEvent& event ) +{ + TransfertDataToPad( m_dummyPad ); + m_panelShowPad->Refresh(); +} + + /*************************************************************************/ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) /*************************************************************************/ @@ -431,99 +548,225 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) /* Updates the different parameters for the component being edited. */ { - long PadLayerMask; - bool RastnestIsChanged = false; - int internalUnits = m_Parent->m_InternalUnits; + bool rastnestIsChanged = false; + int isign = m_isFlipped ? -1 : 1; + + bool success = TransfertDataToPad( m_dummyPad, true ); + if( !success ) // An error on parameters has occured + return; + + TransfertDataToPad( &g_Pad_Master, false ); + g_Current_PadName = g_Pad_Master.ReturnStringPadName(); + + if( m_CurrentPad ) // Set current Pad parameters + { + MODULE* Module = (MODULE*) m_CurrentPad->GetParent(); + m_Parent->SaveCopyInUndoList( Module, UR_CHANGED ); + Module->m_LastEdit_Time = time( NULL ); + + // redraw the area where the pad was, without pad (delete pad on screen) + m_CurrentPad->m_Flags |= DO_NOT_DRAW; + m_Parent->DrawPanel->PostDirtyRect( m_CurrentPad->GetBoundingBox() ); + m_CurrentPad->m_Flags &= ~DO_NOT_DRAW; + + // Update values + m_CurrentPad->m_PadShape = g_Pad_Master.m_PadShape; + m_CurrentPad->m_Attribut = g_Pad_Master.m_Attribut; + if( m_CurrentPad->m_Pos != g_Pad_Master.m_Pos ) + { + m_CurrentPad->m_Pos = g_Pad_Master.m_Pos; + rastnestIsChanged = true; + } + + /* compute the pos 0 value, i.e. pad position for module orient = 0 i.e. + * refer to module origin (module position) */ + m_CurrentPad->m_Pos0 = m_CurrentPad->m_Pos; + m_CurrentPad->m_Pos0 -= Module->m_Pos; + m_CurrentPad->m_Orient = (g_Pad_Master.m_Orient * isign) + Module->m_Orient; + RotatePoint( &m_CurrentPad->m_Pos0.x, &m_CurrentPad->m_Pos0.y, -Module->m_Orient ); + + m_CurrentPad->m_Size = g_Pad_Master.m_Size; + m_CurrentPad->m_DeltaSize = g_Pad_Master.m_DeltaSize; + m_CurrentPad->m_DeltaSize.y *= isign; + m_CurrentPad->m_Drill = g_Pad_Master.m_Drill; + m_CurrentPad->m_DrillShape = g_Pad_Master.m_DrillShape; + m_CurrentPad->m_Offset = g_Pad_Master.m_Offset; + m_CurrentPad->m_Offset.y *= isign; + if( m_CurrentPad->m_Masque_Layer != g_Pad_Master.m_Masque_Layer ) + { + rastnestIsChanged = true; + m_CurrentPad->m_Masque_Layer = g_Pad_Master.m_Masque_Layer; + } + if( m_isFlipped ) + m_CurrentPad->m_Masque_Layer = ChangeSideMaskLayer( m_CurrentPad->m_Masque_Layer ); + + m_CurrentPad->SetPadName( g_Pad_Master.ReturnStringPadName() ); + + if( m_CurrentPad->GetNetname() != g_Pad_Master.GetNetname() ) + { + if( g_Pad_Master.GetNetname().IsEmpty() ) + { + rastnestIsChanged = true; + m_CurrentPad->SetNet( 0 ); + m_CurrentPad->SetNetname( wxEmptyString ); + } + else + { + const NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( g_Pad_Master.GetNetname() ); + if( net ) + { + rastnestIsChanged = true; + m_CurrentPad->SetNetname( g_Pad_Master.GetNetname() ); + m_CurrentPad->SetNet( net->GetNet() ); + } + else + DisplayError( NULL, _( "Unknown netname, netname not changed" ) ); + } + } + + m_CurrentPad->m_LocalClearance = g_Pad_Master.m_LocalClearance; + m_CurrentPad->m_LocalSolderMaskMargin = g_Pad_Master.m_LocalSolderMaskMargin; + m_CurrentPad->m_LocalSolderPasteMargin = g_Pad_Master.m_LocalSolderPasteMargin; + m_CurrentPad->m_LocalSolderPasteMarginRatio = g_Pad_Master.m_LocalSolderPasteMarginRatio; + + m_CurrentPad->ComputeRayon(); + + Module->Set_Rectangle_Encadrement(); + m_CurrentPad->DisplayInfo( m_Parent ); + + // redraw the area where the pad was + m_Parent->DrawPanel->PostDirtyRect( m_CurrentPad->GetBoundingBox() ); + m_Parent->OnModify(); + } + + EndModal( wxID_OK ); + + if( rastnestIsChanged ) // The net ratsnest must be recalculated + m_Parent->GetBoard()->m_Status_Pcb = 0; +} + + +bool DIALOG_PAD_PROPERTIES::TransfertDataToPad( D_PAD* aPad, bool aPromptOnError ) +{ + long PadLayerMask; + int internalUnits = m_Parent->m_InternalUnits; wxString msg; - g_Pad_Master.m_Attribut = CodeType[m_PadType->GetSelection()]; - g_Pad_Master.m_PadShape = CodeShape[m_PadShape->GetSelection()]; + aPad->m_Attribut = CodeType[m_PadType->GetSelection()]; + aPad->m_PadShape = CodeShape[m_PadShape->GetSelection()]; // Read pad clearances values: - g_Pad_Master.m_LocalClearance = ReturnValueFromTextCtrl( *m_NetClearanceValueCtrl, + aPad->m_LocalClearance = ReturnValueFromTextCtrl( *m_NetClearanceValueCtrl, + internalUnits ); + aPad->m_LocalSolderMaskMargin = ReturnValueFromTextCtrl( *m_SolderMaskMarginCtrl, internalUnits ); - g_Pad_Master.m_LocalSolderMaskMargin = ReturnValueFromTextCtrl( *m_SolderMaskMarginCtrl, - internalUnits ); - g_Pad_Master.m_LocalSolderPasteMargin = ReturnValueFromTextCtrl( *m_SolderPasteMarginCtrl, - internalUnits ); - double dtmp = 0.0; + aPad->m_LocalSolderPasteMargin = ReturnValueFromTextCtrl( *m_SolderPasteMarginCtrl, + internalUnits ); + double dtmp = 0.0; msg = m_SolderPasteMarginRatioCtrl->GetValue(); msg.ToDouble( &dtmp ); + // A margin ratio de -50% means no paste on a pad, the ratio must be >= 50 % if( dtmp < -50 ) dtmp = -50; if( dtmp > +100 ) dtmp = +100; - g_Pad_Master.m_LocalSolderPasteMarginRatio = dtmp / 100; + aPad->m_LocalSolderPasteMarginRatio = dtmp / 100; // Read pad position: - g_Pad_Master.m_Pos.x = ReturnValueFromTextCtrl( *m_PadPosition_X_Ctrl, internalUnits ); - g_Pad_Master.m_Pos.y = ReturnValueFromTextCtrl( *m_PadPosition_Y_Ctrl, internalUnits ); - g_Pad_Master.m_Pos0 = g_Pad_Master.m_Pos; + aPad->m_Pos.x = ReturnValueFromTextCtrl( *m_PadPosition_X_Ctrl, internalUnits ); + aPad->m_Pos.y = ReturnValueFromTextCtrl( *m_PadPosition_Y_Ctrl, internalUnits ); + aPad->m_Pos0 = aPad->m_Pos; // Read pad drill: - g_Pad_Master.m_Drill.x = ReturnValueFromTextCtrl( *m_PadDrill_X_Ctrl, internalUnits ); - g_Pad_Master.m_Drill.y = ReturnValueFromTextCtrl( *m_PadDrill_Y_Ctrl, internalUnits ); + aPad->m_Drill.x = ReturnValueFromTextCtrl( *m_PadDrill_X_Ctrl, internalUnits ); + aPad->m_Drill.y = ReturnValueFromTextCtrl( *m_PadDrill_Y_Ctrl, internalUnits ); if( m_DrillShapeCtrl->GetSelection() == 0 ) { - g_Pad_Master.m_DrillShape = PAD_CIRCLE; - g_Pad_Master.m_Drill.y = g_Pad_Master.m_Drill.x; + aPad->m_DrillShape = PAD_CIRCLE; + aPad->m_Drill.y = aPad->m_Drill.x; } else - g_Pad_Master.m_DrillShape = PAD_OVAL; + aPad->m_DrillShape = PAD_OVAL; // Read pad shape size: - g_Pad_Master.m_Size.x = ReturnValueFromTextCtrl( *m_ShapeSize_X_Ctrl, internalUnits ); - g_Pad_Master.m_Size.y = ReturnValueFromTextCtrl( *m_ShapeSize_Y_Ctrl, internalUnits ); - if( g_Pad_Master.m_PadShape == PAD_CIRCLE ) - g_Pad_Master.m_Size.y = g_Pad_Master.m_Size.x; + aPad->m_Size.x = ReturnValueFromTextCtrl( *m_ShapeSize_X_Ctrl, internalUnits ); + aPad->m_Size.y = ReturnValueFromTextCtrl( *m_ShapeSize_Y_Ctrl, internalUnits ); + if( aPad->m_PadShape == PAD_CIRCLE ) + aPad->m_Size.y = aPad->m_Size.x; // Read pad shape delta size: - g_Pad_Master.m_DeltaSize.x = ReturnValueFromTextCtrl( *m_ShapeDelta_X_Ctrl, internalUnits ); - g_Pad_Master.m_DeltaSize.y = ReturnValueFromTextCtrl( *m_ShapeDelta_Y_Ctrl, internalUnits ); + // m_DeltaSize.x or m_DeltaSize.y must be NULL. for a trapezoid. + aPad->m_DeltaSize.x = ReturnValueFromTextCtrl( *m_ShapeDelta_X_Ctrl, internalUnits ); + aPad->m_DeltaSize.y = ReturnValueFromTextCtrl( *m_ShapeDelta_Y_Ctrl, internalUnits ); + + // Test bad values (be sure delta values are not to large) + // rememver DeltaSize.x is the Y size variation + bool error = false; + if( (aPad->m_DeltaSize.x < 0) && (aPad->m_DeltaSize.x <= -aPad->m_Size.y) ) + { + aPad->m_DeltaSize.x = -aPad->m_Size.y + 2; + error = true; + } + if( (aPad->m_DeltaSize.x > 0) && (aPad->m_DeltaSize.x >= aPad->m_Size.y) ) + { + aPad->m_DeltaSize.x = aPad->m_Size.y - 2; + error = true; + } + if( (aPad->m_DeltaSize.y < 0) && (aPad->m_DeltaSize.y <= -aPad->m_Size.x) ) + { + aPad->m_DeltaSize.y = -aPad->m_Size.x + 2; + error = true; + } + if( (aPad->m_DeltaSize.y > 0) && (aPad->m_DeltaSize.y >= aPad->m_Size.x) ) + { + aPad->m_DeltaSize.y = aPad->m_Size.x - 2; + error = true; + } // Read pad shape offset: - g_Pad_Master.m_Offset.x = ReturnValueFromTextCtrl( *m_ShapeOffset_X_Ctrl, internalUnits ); - g_Pad_Master.m_Offset.y = ReturnValueFromTextCtrl( *m_ShapeOffset_Y_Ctrl, internalUnits ); + aPad->m_Offset.x = ReturnValueFromTextCtrl( *m_ShapeOffset_X_Ctrl, internalUnits ); + aPad->m_Offset.y = ReturnValueFromTextCtrl( *m_ShapeOffset_Y_Ctrl, internalUnits ); - long orient_value = 0; - msg = m_PadOrientCtrl->GetValue(); + long orient_value = 0; + msg = m_PadOrientCtrl->GetValue(); msg.ToLong( &orient_value ); - g_Pad_Master.m_Orient = orient_value; + aPad->m_Orient = orient_value; - g_Current_PadName = m_PadNumCtrl->GetValue().Left( 4 ); - Current_PadNetName = m_PadNetNameCtrl->GetValue(); + msg = m_PadNumCtrl->GetValue().Left( 4 ); + aPad->SetPadName( msg ); + aPad->SetNetname( m_PadNetNameCtrl->GetValue() ); // Clear some values, according to the pad type and shape - switch( g_Pad_Master.m_PadShape ) + switch( aPad->m_PadShape ) { case PAD_CIRCLE: - g_Pad_Master.m_Offset = wxSize( 0, 0 ); - g_Pad_Master.m_DeltaSize = wxSize( 0, 0 ); - g_Pad_Master.m_Size.y = g_Pad_Master.m_Size.x; + aPad->m_Offset = wxSize( 0, 0 ); + aPad->m_DeltaSize = wxSize( 0, 0 ); + aPad->m_Size.y = aPad->m_Size.x; break; case PAD_RECT: - g_Pad_Master.m_DeltaSize = wxSize( 0, 0 ); + aPad->m_DeltaSize = wxSize( 0, 0 ); break; case PAD_OVAL: - g_Pad_Master.m_DeltaSize = wxSize( 0, 0 ); + aPad->m_DeltaSize = wxSize( 0, 0 ); break; case PAD_TRAPEZOID: break; } - switch( g_Pad_Master.m_Attribut ) + switch( aPad->m_Attribut ) { case PAD_STANDARD: break; case PAD_CONN: case PAD_SMD: - g_Pad_Master.m_Offset = wxSize( 0, 0 ); - g_Pad_Master.m_Drill = wxSize( 0, 0 ); + aPad->m_Offset = wxSize( 0, 0 ); + aPad->m_Drill = wxSize( 0, 0 ); break; case PAD_HOLE_NOT_PLATED: @@ -564,118 +807,67 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event ) if( m_PadLayerDraft->GetValue() ) PadLayerMask |= DRAW_LAYER; + aPad->m_Masque_Layer = PadLayerMask; + /* Test for incorrect values */ - if( (g_Pad_Master.m_Size.x < g_Pad_Master.m_Drill.x) - || (g_Pad_Master.m_Size.y < g_Pad_Master.m_Drill.y) ) + if( aPromptOnError ) { - DisplayError( this, _( "Incorrect value for pad drill: pad drill bigger than pad size" ) ); - return; - } - - int padlayers_mask = PadLayerMask & (LAYER_BACK | LAYER_FRONT); - if( padlayers_mask == 0 ) - { - if( g_Pad_Master.m_Drill.x || g_Pad_Master.m_Drill.y ) + if( (aPad->m_Size.x < aPad->m_Drill.x) + || (aPad->m_Size.y < aPad->m_Drill.y) ) { - DisplayError( this, _( "Error: pad is not on a copper layer and has a hole" ) ); - return; - } - } - - if( ( g_Pad_Master.m_Size.x / 2 <= ABS( g_Pad_Master.m_Offset.x ) ) - || ( g_Pad_Master.m_Size.y / 2 <= ABS( g_Pad_Master.m_Offset.y ) ) ) - { - DisplayError( this, _( "Incorrect value for pad offset" ) ); - return; - } - - - g_Pad_Master.m_Masque_Layer = PadLayerMask; - - if( m_CurrentPad ) // Set current Pad parameters - { - MODULE* Module = (MODULE*) m_CurrentPad->GetParent(); - m_Parent->SaveCopyInUndoList( Module, UR_CHANGED ); - Module->m_LastEdit_Time = time( NULL ); - - // redraw the area where the pad was, without pad (delete pad on screen) - m_CurrentPad->m_Flags |= DO_NOT_DRAW; - m_Parent->DrawPanel->PostDirtyRect( m_CurrentPad->GetBoundingBox() ); - m_CurrentPad->m_Flags &= ~DO_NOT_DRAW; - - // Update values - m_CurrentPad->m_PadShape = g_Pad_Master.m_PadShape; - m_CurrentPad->m_Attribut = g_Pad_Master.m_Attribut; - if( m_CurrentPad->m_Pos != g_Pad_Master.m_Pos ) - { - m_CurrentPad->m_Pos = g_Pad_Master.m_Pos; - RastnestIsChanged = true; + DisplayError( this, _( "Incorrect value for pad drill: pad drill bigger than pad size" ) ); + return false; } - /* compute the pos 0 value, i.e. pad position for module orient = 0 i.e. - * refer to module origin (module position) */ - m_CurrentPad->m_Pos0 = m_CurrentPad->m_Pos; - m_CurrentPad->m_Pos0 -= Module->m_Pos; - m_CurrentPad->m_Orient = g_Pad_Master.m_Orient + Module->m_Orient; - RotatePoint( &m_CurrentPad->m_Pos0.x, &m_CurrentPad->m_Pos0.y, -Module->m_Orient ); - - m_CurrentPad->m_Size = g_Pad_Master.m_Size; - m_CurrentPad->m_DeltaSize = g_Pad_Master.m_DeltaSize; - m_CurrentPad->m_Drill = g_Pad_Master.m_Drill; - m_CurrentPad->m_DrillShape = g_Pad_Master.m_DrillShape; - m_CurrentPad->m_Offset = g_Pad_Master.m_Offset; - if( m_CurrentPad->m_Masque_Layer != g_Pad_Master.m_Masque_Layer ) + int padlayers_mask = PadLayerMask & (LAYER_BACK | LAYER_FRONT); + if( padlayers_mask == 0 ) { - RastnestIsChanged = true; - m_CurrentPad->m_Masque_Layer = g_Pad_Master.m_Masque_Layer; - } - m_CurrentPad->SetPadName( g_Current_PadName ); - - if( m_CurrentPad->GetNetname() != Current_PadNetName ) - { - if( Current_PadNetName.IsEmpty() ) + if( aPad->m_Drill.x || aPad->m_Drill.y ) { - m_CurrentPad->SetNet( 0 ); - m_CurrentPad->SetNetname( Current_PadNetName ); - } - else - { - const NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( Current_PadNetName ); - if( net ) - { - RastnestIsChanged = true; - m_CurrentPad->SetNetname( Current_PadNetName ); - m_CurrentPad->SetNet( net->GetNet() ); - } - else - DisplayError( NULL, _( "Unknown netname, no change" ) ); + DisplayError( this, _( "Error: pad is not on a copper layer and has a hole" ) ); + return false; } } - m_CurrentPad->m_LocalClearance = g_Pad_Master.m_LocalClearance; - m_CurrentPad->m_LocalSolderMaskMargin = g_Pad_Master.m_LocalSolderMaskMargin; - m_CurrentPad->m_LocalSolderPasteMargin = g_Pad_Master.m_LocalSolderPasteMargin; - m_CurrentPad->m_LocalSolderPasteMarginRatio = g_Pad_Master.m_LocalSolderPasteMarginRatio; + if( ( aPad->m_Size.x / 2 <= ABS( aPad->m_Offset.x ) ) + || ( aPad->m_Size.y / 2 <= ABS( aPad->m_Offset.y ) ) ) + { + DisplayError( this, _( "Incorrect value for pad offset" ) ); + return false; + } - m_CurrentPad->ComputeRayon(); + if( error ) + { + DisplayError( this, _( "Too large value for pad delta size" ) ); + return false; + } - Module->Set_Rectangle_Encadrement(); - m_CurrentPad->DisplayInfo( m_Parent ); - // redraw the area where the pad was - m_Parent->DrawPanel->PostDirtyRect( m_CurrentPad->GetBoundingBox() ); - m_Parent->OnModify(); + if( aPad->m_DeltaSize.x && aPad->m_DeltaSize.y ) + { + DisplayError( this, _( "Incorrect value for pad delta size: X or Y value must be NULL" ) ); + return false; + } } - EndModal( wxID_OK ); - - if( RastnestIsChanged ) // The net ratsnest must be recalculated - m_Parent->GetBoard()->m_Status_Pcb = 0; + return true; } + +// Called when a dimension has change. +// Update the pad dimensions shown in the panel. +void DIALOG_PAD_PROPERTIES::OnValuesChanged( wxCommandEvent& event ) +{ + if( m_canUpdate ) + { + TransfertDataToPad( m_dummyPad ); + m_panelShowPad->Refresh(); + } +} + + /*********************************************************************/ void DIALOG_PAD_PROPERTIES::OnCancelButtonClick( wxCommandEvent& event ) /*********************************************************************/ { EndModal( wxID_CANCEL ); } - diff --git a/pcbnew/dialog_pad_properties_base.cpp b/pcbnew/dialog_pad_properties_base.cpp index b83acafb79..cd905c5d2f 100644 --- a/pcbnew/dialog_pad_properties_base.cpp +++ b/pcbnew/dialog_pad_properties_base.cpp @@ -176,7 +176,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_LeftBoxSizer->Add( sbSizer2, 1, wxEXPAND, 5 ); - bGeneralSizer->Add( m_LeftBoxSizer, 0, wxBOTTOM|wxLEFT, 5 ); + bGeneralSizer->Add( m_LeftBoxSizer, 0, wxBOTTOM|wxLEFT|wxEXPAND, 5 ); wxBoxSizer* bMiddleSizer; bMiddleSizer = new wxBoxSizer( wxVERTICAL ); @@ -196,14 +196,14 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind int m_DrillShapeCtrlNChoices = sizeof( m_DrillShapeCtrlChoices ) / sizeof( wxString ); m_DrillShapeCtrl = new wxRadioBox( this, ID_RADIOBOX_DRILL_SHAPE, _("Drill Shape:"), wxDefaultPosition, wxDefaultSize, m_DrillShapeCtrlNChoices, m_DrillShapeCtrlChoices, 1, wxRA_SPECIFY_COLS ); m_DrillShapeCtrl->SetSelection( 0 ); - m_DrillShapeBoxSizer->Add( m_DrillShapeCtrl, 0, wxALL|wxEXPAND, 5 ); + m_DrillShapeBoxSizer->Add( m_DrillShapeCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - bMiddleUpperSizer->Add( m_DrillShapeBoxSizer, 1, wxBOTTOM, 5 ); + bMiddleUpperSizer->Add( m_DrillShapeBoxSizer, 0, wxBOTTOM, 5 ); wxBoxSizer* m_MiddleRightBoxSizer; m_MiddleRightBoxSizer = new wxBoxSizer( wxVERTICAL ); - wxString m_PadOrientChoices[] = { _("0"), _("90"), _("-90"), _("180"), _("User") }; + wxString m_PadOrientChoices[] = { _("0"), _("90"), _("-90"), _("180"), _("Custom") }; int m_PadOrientNChoices = sizeof( m_PadOrientChoices ) / sizeof( wxString ); m_PadOrient = new wxRadioBox( this, ID_LISTBOX_ORIENT_PAD, _("Pad Orient:"), wxDefaultPosition, wxDefaultSize, m_PadOrientNChoices, m_PadOrientChoices, 1, wxRA_SPECIFY_COLS ); m_PadOrient->SetSelection( 0 ); @@ -216,18 +216,52 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_PadOrientCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_MiddleRightBoxSizer->Add( m_PadOrientCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); - bMiddleUpperSizer->Add( m_MiddleRightBoxSizer, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + bMiddleUpperSizer->Add( m_MiddleRightBoxSizer, 0, wxBOTTOM, 5 ); - bMiddleSizer->Add( bMiddleUpperSizer, 0, wxEXPAND, 5 ); + m_panelShowPad = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE|wxSIMPLE_BORDER|wxTAB_TRAVERSAL ); + m_panelShowPad->SetBackgroundColour( wxColour( 0, 0, 0 ) ); + + bMiddleUpperSizer->Add( m_panelShowPad, 1, wxEXPAND | wxALL, 5 ); + + bMiddleSizer->Add( bMiddleUpperSizer, 1, wxEXPAND, 5 ); + + wxStaticBoxSizer* sbSizeModuleInfo; + sbSizeModuleInfo = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint orientation") ), wxVERTICAL ); + + wxFlexGridSizer* fgSizer4; + fgSizer4 = new wxFlexGridSizer( 2, 2, 0, 0 ); + fgSizer4->AddGrowableCol( 1 ); + fgSizer4->SetFlexibleDirection( wxBOTH ); + fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticTitleModuleRot = new wxStaticText( this, wxID_ANY, _("Rotation:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTitleModuleRot->Wrap( -1 ); + fgSizer4->Add( m_staticTitleModuleRot, 0, wxALIGN_RIGHT|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_staticModuleRotValue = new wxStaticText( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticModuleRotValue->Wrap( -1 ); + fgSizer4->Add( m_staticModuleRotValue, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_staticTitleModuleSide = new wxStaticText( this, wxID_ANY, _("Board side:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTitleModuleSide->Wrap( -1 ); + fgSizer4->Add( m_staticTitleModuleSide, 0, wxALL|wxALIGN_RIGHT, 5 ); + + m_staticModuleSideValue = new wxStaticText( this, wxID_ANY, _("Front side"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticModuleSideValue->Wrap( -1 ); + fgSizer4->Add( m_staticModuleSideValue, 0, wxALL, 5 ); + + sbSizeModuleInfo->Add( fgSizer4, 0, wxEXPAND, 5 ); + + bMiddleSizer->Add( sbSizeModuleInfo, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); wxStaticBoxSizer* sbClearancesSizer; sbClearancesSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Clearances:") ), wxVERTICAL ); - m_staticText20 = new wxStaticText( this, wxID_ANY, _("Set these values to 0\nto use Parent footprint or global values"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText20->Wrap( -1 ); - m_staticText20->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); + m_staticTextWarning = new wxStaticText( this, wxID_ANY, _("Set these values to 0\nto use Parent footprint or global values"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextWarning->Wrap( -1 ); + m_staticTextWarning->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); - sbClearancesSizer->Add( m_staticText20, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + sbClearancesSizer->Add( m_staticTextWarning, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); wxFlexGridSizer* fgClearancesGridSizer; fgClearancesGridSizer = new wxFlexGridSizer( 5, 3, 0, 0 ); @@ -248,13 +282,13 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind fgClearancesGridSizer->Add( m_NetClearanceUnits, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - fgClearancesGridSizer->Add( m_staticline1, 0, wxEXPAND|wxALL, 5 ); + fgClearancesGridSizer->Add( m_staticline1, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - fgClearancesGridSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 ); + fgClearancesGridSizer->Add( m_staticline2, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); m_staticline3 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - fgClearancesGridSizer->Add( m_staticline3, 0, wxEXPAND | wxALL, 5 ); + fgClearancesGridSizer->Add( m_staticline3, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); m_MaskClearanceTitle = new wxStaticText( this, wxID_ANY, _("Solder mask clearance:"), wxDefaultPosition, wxDefaultSize, 0 ); m_MaskClearanceTitle->Wrap( -1 ); @@ -297,7 +331,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind sbClearancesSizer->Add( fgClearancesGridSizer, 1, wxEXPAND, 5 ); - bMiddleSizer->Add( sbClearancesSizer, 0, wxEXPAND, 5 ); + bMiddleSizer->Add( sbClearancesSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); bGeneralSizer->Add( bMiddleSizer, 1, wxEXPAND, 5 ); @@ -370,7 +404,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_RightBoxSizer->Add( m_LayersSizer, 0, 0, 5 ); - bGeneralSizer->Add( m_RightBoxSizer, 0, wxBOTTOM|wxRIGHT, 5 ); + bGeneralSizer->Add( m_RightBoxSizer, 0, wxBOTTOM|wxRIGHT|wxEXPAND, 5 ); m_MainSizer->Add( bGeneralSizer, 1, wxEXPAND, 5 ); @@ -380,7 +414,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL ); m_sdbSizer1->AddButton( m_sdbSizer1Cancel ); m_sdbSizer1->Realize(); - m_MainSizer->Add( m_sdbSizer1, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 ); + m_MainSizer->Add( m_sdbSizer1, 0, wxTOP|wxBOTTOM|wxEXPAND, 5 ); this->SetSizer( m_MainSizer ); this->Layout(); @@ -388,10 +422,36 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind this->Centre( wxBOTH ); // Connect Events + m_PadNumCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_PadNetNameCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_PadDrill_X_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_PadDrill_Y_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeSize_X_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeSize_Y_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeOffset_X_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeOffset_Y_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeDelta_X_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeDelta_Y_Ctrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); m_PadShape->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPadShapeSelection ), NULL, this ); m_DrillShapeCtrl->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnDrillShapeSelected ), NULL, this ); m_PadOrient->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadOrientEvent ), NULL, this ); + m_PadOrientCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_panelShowPad->Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPaintShowPanel ), NULL, this ); + m_NetClearanceValueCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); m_PadType->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadTypeSelected ), NULL, this ); + m_PadLayerCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerAdhCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerAdhCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerPateCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerPateCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerSilkCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerSilkCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerMaskCmp->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerMaskCu->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerDraft->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerECO1->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerECO2->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnCancelButtonClick ), NULL, this ); m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadPropertiesAccept ), NULL, this ); } @@ -399,10 +459,36 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind DIALOG_PAD_PROPERTIES_BASE::~DIALOG_PAD_PROPERTIES_BASE() { // Disconnect Events + m_PadNumCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_PadNetNameCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_PadDrill_X_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_PadDrill_Y_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeSize_X_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeSize_Y_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeOffset_X_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeOffset_Y_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeDelta_X_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_ShapeDelta_Y_Ctrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); m_PadShape->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPadShapeSelection ), NULL, this ); m_DrillShapeCtrl->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnDrillShapeSelected ), NULL, this ); m_PadOrient->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadOrientEvent ), NULL, this ); + m_PadOrientCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); + m_panelShowPad->Disconnect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnPaintShowPanel ), NULL, this ); + m_NetClearanceValueCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnValuesChanged ), NULL, this ); m_PadType->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadTypeSelected ), NULL, this ); + m_PadLayerCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerAdhCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerAdhCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerPateCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerPateCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerSilkCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerSilkCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerMaskCmp->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerMaskCu->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerDraft->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerECO1->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); + m_PadLayerECO2->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnSetLayer ), NULL, this ); m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::OnCancelButtonClick ), NULL, this ); m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PAD_PROPERTIES_BASE::PadPropertiesAccept ), NULL, this ); } diff --git a/pcbnew/dialog_pad_properties_base.fbp b/pcbnew/dialog_pad_properties_base.fbp index d731832bd8..08885f443e 100644 --- a/pcbnew/dialog_pad_properties_base.fbp +++ b/pcbnew/dialog_pad_properties_base.fbp @@ -32,7 +32,7 @@ DIALOG_PAD_PROPERTIES_BASE - 673,488 + 733,486 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER Pad Properties @@ -86,7 +86,7 @@ none 5 - wxBOTTOM|wxLEFT + wxBOTTOM|wxLEFT|wxEXPAND 0 @@ -192,7 +192,7 @@ - + OnValuesChanged @@ -298,7 +298,7 @@ - + OnValuesChanged @@ -321,7 +321,7 @@ 5 wxEXPAND 1 - + 3 wxBOTH @@ -893,7 +893,7 @@ - + OnValuesChanged @@ -1050,7 +1050,7 @@ - + OnValuesChanged @@ -1354,7 +1354,7 @@ - + OnValuesChanged @@ -1511,7 +1511,7 @@ - + OnValuesChanged @@ -1668,7 +1668,7 @@ - + OnValuesChanged @@ -1825,7 +1825,7 @@ - + OnValuesChanged @@ -1982,7 +1982,7 @@ - + OnValuesChanged @@ -2139,7 +2139,7 @@ - + OnValuesChanged @@ -2215,7 +2215,7 @@ 5 wxEXPAND - 0 + 1 bMiddleUpperSizer @@ -2224,7 +2224,7 @@ 5 wxBOTTOM - 1 + 0 m_DrillShapeBoxSizer @@ -2286,7 +2286,7 @@ 5 - wxALL|wxEXPAND + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT 0 @@ -2342,7 +2342,7 @@ 5 - wxBOTTOM|wxRIGHT|wxLEFT + wxBOTTOM 0 @@ -2355,7 +2355,7 @@ 0 - "0" "90" "-90" "180" "User" + "0" "90" "-90" "180" "Custom" 1 @@ -2502,7 +2502,7 @@ - + OnValuesChanged @@ -2511,11 +2511,295 @@ + + 5 + wxEXPAND | wxALL + 1 + + 0,0,0 + + 1 + + + 0 + wxID_ANY + + + m_panelShowPad + protected + + + + + + + wxFULL_REPAINT_ON_RESIZE|wxSIMPLE_BORDER|wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + OnPaintShowPanel + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + wxID_ANY + Footprint orientation + + sbSizeModuleInfo + wxVERTICAL + none + + + 5 + wxEXPAND + 0 + + 2 + wxBOTH + 1 + + 0 + + fgSizer4 + wxFLEX_GROWMODE_SPECIFIED + none + 2 + 0 + + 5 + wxALIGN_RIGHT|wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Rotation: + + + m_staticTitleModuleRot + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + 0 + + + m_staticModuleRotValue + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_RIGHT + 0 + + + + 1 + + + 0 + wxID_ANY + Board side: + + + m_staticTitleModuleSide + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Front side + + + m_staticModuleSideValue + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 - wxEXPAND + wxEXPAND|wxRIGHT|wxLEFT 0 wxID_ANY @@ -2540,7 +2824,7 @@ Set these values to 0 to use Parent footprint or global values - m_staticText20 + m_staticTextWarning protected @@ -2691,7 +2975,7 @@ - + OnValuesChanged @@ -2751,7 +3035,7 @@ 5 - wxEXPAND|wxALL + wxEXPAND|wxRIGHT|wxLEFT 0 @@ -2800,7 +3084,7 @@ 5 - wxEXPAND | wxALL + wxEXPAND|wxRIGHT|wxLEFT 0 @@ -2849,7 +3133,7 @@ 5 - wxEXPAND | wxALL + wxEXPAND|wxRIGHT|wxLEFT 0 @@ -3375,7 +3659,7 @@ 5 - wxBOTTOM|wxRIGHT + wxBOTTOM|wxRIGHT|wxEXPAND 0 @@ -3475,7 +3759,7 @@ - + OnSetLayer @@ -3527,7 +3811,7 @@ - + OnSetLayer @@ -3589,7 +3873,7 @@ - + OnSetLayer @@ -3641,7 +3925,7 @@ - + OnSetLayer @@ -3693,7 +3977,7 @@ - + OnSetLayer @@ -3745,7 +4029,7 @@ - + OnSetLayer @@ -3797,7 +4081,7 @@ - + OnSetLayer @@ -3849,7 +4133,7 @@ - + OnSetLayer @@ -3901,7 +4185,7 @@ - + OnSetLayer @@ -3953,7 +4237,7 @@ - + OnSetLayer @@ -4005,7 +4289,7 @@ - + OnSetLayer @@ -4057,7 +4341,7 @@ - + OnSetLayer @@ -4109,7 +4393,7 @@ - + OnSetLayer @@ -4142,7 +4426,7 @@ 5 - wxEXPAND|wxTOP|wxBOTTOM + wxTOP|wxBOTTOM|wxEXPAND 0 0 diff --git a/pcbnew/dialog_pad_properties_base.h b/pcbnew/dialog_pad_properties_base.h index d2ffa79bc9..4ed29b7599 100644 --- a/pcbnew/dialog_pad_properties_base.h +++ b/pcbnew/dialog_pad_properties_base.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -92,7 +93,12 @@ class DIALOG_PAD_PROPERTIES_BASE : public wxDialog wxRadioBox* m_PadOrient; wxStaticText* m_PadOrientText; wxTextCtrl* m_PadOrientCtrl; - wxStaticText* m_staticText20; + wxPanel* m_panelShowPad; + wxStaticText* m_staticTitleModuleRot; + wxStaticText* m_staticModuleRotValue; + wxStaticText* m_staticTitleModuleSide; + wxStaticText* m_staticModuleSideValue; + wxStaticText* m_staticTextWarning; wxStaticText* m_staticTextNetClearance; wxTextCtrl* m_NetClearanceValueCtrl; wxStaticText* m_NetClearanceUnits; @@ -128,16 +134,19 @@ class DIALOG_PAD_PROPERTIES_BASE : public wxDialog wxButton* m_sdbSizer1Cancel; // Virtual event handlers, overide them in your derived class + virtual void OnValuesChanged( wxCommandEvent& event ){ event.Skip(); } virtual void OnPadShapeSelection( wxCommandEvent& event ){ event.Skip(); } virtual void OnDrillShapeSelected( wxCommandEvent& event ){ event.Skip(); } virtual void PadOrientEvent( wxCommandEvent& event ){ event.Skip(); } + virtual void OnPaintShowPanel( wxPaintEvent& event ){ event.Skip(); } virtual void PadTypeSelected( wxCommandEvent& event ){ event.Skip(); } + virtual void OnSetLayer( wxCommandEvent& event ){ event.Skip(); } virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); } virtual void PadPropertiesAccept( wxCommandEvent& event ){ event.Skip(); } public: - DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 673,488 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSUNKEN_BORDER ); + DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 733,486 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSUNKEN_BORDER ); ~DIALOG_PAD_PROPERTIES_BASE(); }; diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index 839c7c85cc..a0139db801 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -291,7 +291,7 @@ void WinEDA_PcbFrame::ReCreateMenuBar() /* Swap Layers */ item = new wxMenuItem( editMenu, ID_MENU_PCB_SWAP_LAYERS, _( "&Swap Layers" ), - _( "Swap tracks on copper layers or drawings on others layers" ) ); + _( "Swap tracks on copper layers or drawings on other layers" ) ); item->SetBitmap( swap_layer_xpm ); editMenu->Append( item ); @@ -309,7 +309,7 @@ void WinEDA_PcbFrame::ReCreateMenuBar() * From hotkeys, zooming is made around the mouse cursor position * (obviously not possible from the toolbar or menubar command) * - * in others words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators + * in other words HK_ZOOM_IN and HK_ZOOM_OUT *are NOT* accelerators * for Zoom in and Zoom out sub menus */ /* Zoom in */ From a989a2141783fc359767cfe69cf4176e1c69c252 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sat, 11 Sep 2010 21:15:24 +0200 Subject: [PATCH 2/2] added test of trapezoidal pads parameters before draw them --- pcbnew/class_pad_draw_functions.cpp | 134 +++++++++++++++----------- pcbnew/dialog_pad_properties.cpp | 11 ++- pcbnew/dialog_pad_properties_base.cpp | 16 ++- pcbnew/dialog_pad_properties_base.fbp | 61 +++++++++++- pcbnew/dialog_pad_properties_base.h | 1 + 5 files changed, 156 insertions(+), 67 deletions(-) diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp index 458d170809..87991c8982 100644 --- a/pcbnew/class_pad_draw_functions.cpp +++ b/pcbnew/class_pad_draw_functions.cpp @@ -26,17 +26,17 @@ // Helper class to store parameters used to draw a pad -PAD_DRAWINFO::PAD_DRAWINFO( ) +PAD_DRAWINFO::PAD_DRAWINFO() { - m_DrawPanel = NULL; - m_DrawMode = 0; - m_Color = BLACK; - m_HoleColor = BLACK; // could be DARKGRAY; - m_PadClearance = 0; - m_Display_padnum = true; + m_DrawPanel = NULL; + m_DrawMode = 0; + m_Color = BLACK; + m_HoleColor = BLACK; // could be DARKGRAY; + m_PadClearance = 0; + m_Display_padnum = true; m_Display_netname = true; - m_ShowPadFilled = true; - m_ShowNCMark = true; + m_ShowPadFilled = true; + m_ShowNCMark = true; #ifndef USE_WX_ZOOM m_Scale = 1.0; #endif @@ -52,9 +52,9 @@ PAD_DRAWINFO::PAD_DRAWINFO( ) void D_PAD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDraw_mode, const wxPoint& aOffset ) { - int color = 0; - wxSize mask_margin; // margin (clearance) used for some non copper layers - int showActualMaskSize = 0; /* == layer number if the actual pad size on mask layer can be displayed + int color = 0; + wxSize mask_margin; // margin (clearance) used for some non copper layers + int showActualMaskSize = 0; /* == layer number if the actual pad size on mask layer can be displayed * i.e. if only one layer is shown for this pad * and this layer is a mask (solder mask or sloder paste */ @@ -319,14 +319,14 @@ void D_PAD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDraw_mode, DisplayIsol = FALSE; - drawInfo.m_DrawMode = aDraw_mode; - drawInfo.m_Color = color; - drawInfo.m_DrawPanel = aPanel; + drawInfo.m_DrawMode = aDraw_mode; + drawInfo.m_Color = color; + drawInfo.m_DrawPanel = aPanel; drawInfo.m_Mask_margin = mask_margin; - drawInfo.m_ShowNCMark = brd->IsElementVisible( PCB_VISIBLE( NO_CONNECTS_VISIBLE ) ); - drawInfo.m_IsPrinting = screen->m_IsPrinting; + drawInfo.m_ShowNCMark = brd->IsElementVisible( PCB_VISIBLE( NO_CONNECTS_VISIBLE ) ); + drawInfo.m_IsPrinting = screen->m_IsPrinting; #ifndef USE_WX_ZOOM - drawInfo.m_Scale = (double)screen->Scale(1000) / 1000; + drawInfo.m_Scale = (double) screen->Scale( 1000 ) / 1000; #endif SetAlpha( &color, 170 ); @@ -362,16 +362,16 @@ void D_PAD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDraw_mode, void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) { wxPoint coord[4]; - int rotdx, - delta_cx, delta_cy; - int angle = m_Orient; + int rotdx, + delta_cx, delta_cy; + int angle = m_Orient; - GRSetDrawMode(aDC, aDrawInfo.m_DrawMode ); + GRSetDrawMode( aDC, aDrawInfo.m_DrawMode ); // calculate pad shape position : wxPoint shape_pos = ReturnShapePos() - aDrawInfo.m_Offset; - wxSize halfsize = m_Size; + wxSize halfsize = m_Size; halfsize.x >>= 1; halfsize.y >>= 1; switch( GetShape() ) @@ -449,7 +449,8 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) if( aDrawInfo.m_PadClearance ) { - BuildPadPolygon( coord, wxSize(aDrawInfo.m_PadClearance,aDrawInfo.m_PadClearance), angle ); + BuildPadPolygon( coord, wxSize( aDrawInfo.m_PadClearance, + aDrawInfo.m_PadClearance ), angle ); for( int ii = 0; ii < 4; ii++ ) coord[ii] += shape_pos; @@ -463,8 +464,8 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) } /* Draw the pad hole */ - wxPoint holepos = m_Pos - aDrawInfo.m_Offset; - int hole = m_Drill.x >> 1; + wxPoint holepos = m_Pos - aDrawInfo.m_Offset; + int hole = m_Drill.x >> 1; if( aDrawInfo.m_ShowPadFilled && hole ) { @@ -488,9 +489,11 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) #ifdef USE_WX_ZOOM if( DC->LogicalToDeviceXRel( hole ) > 1 ) #else - if( aDrawInfo.m_Scale*hole > 1 ) /* draw hole if its size is enough */ + if( aDrawInfo.m_Scale * hole > 1 ) /* draw hole if its size is enough */ #endif + + GRFilledCircle( aClipBox, aDC, holepos.x, holepos.y, hole, 0, aDrawInfo.m_Color, aDrawInfo.m_HoleColor ); break; @@ -547,7 +550,7 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) if( !aDrawInfo.m_Display_padnum && !aDrawInfo.m_Display_netname ) return; - wxPoint tpos0 = shape_pos; // Position of the centre of text + wxPoint tpos0 = shape_pos; // Position of the centre of text wxPoint tpos = tpos0; wxSize AreaSize; // size of text area, normalized to // AreaSize.y < AreaSize.x @@ -599,9 +602,9 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) #define CHAR_SIZE_MIN 5 #ifdef USE_WX_ZOOM - if( DC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable when size too small. + if( DC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable when size too small. #else - if( aDrawInfo.m_Scale*tsize >= CHAR_SIZE_MIN ) // Not drawable when size too small. + if( aDrawInfo.m_Scale * tsize >= CHAR_SIZE_MIN ) // Not drawable when size too small. #endif { // tsize reserve room for marges and segments thickness @@ -621,9 +624,9 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) tsize = min( AreaSize.y, AreaSize.x / shortname_len ); #ifdef USE_WX_ZOOM - if( DC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable in size too small. + if( DC->LogicalToDeviceXRel( tsize ) >= CHAR_SIZE_MIN ) // Not drawable in size too small. #else - if( aDrawInfo.m_Scale*tsize >= CHAR_SIZE_MIN ) // Not drawable in size too small. + if( aDrawInfo.m_Scale * tsize >= CHAR_SIZE_MIN ) // Not drawable in size too small. #endif { tpos = tpos0; @@ -639,6 +642,7 @@ void D_PAD::DrawShape( EDA_Rect* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) } } + /** function BuildPadPolygon * Has meaning only for polygonal pads (trapeziod and rectangular) * Build the Corner list of the polygonal shape, @@ -659,14 +663,11 @@ void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, int aRotat halfsize.y = m_Size.y >> 1; /* For rectangular shapes, inflate is easy - * Also if inflate values for X and Y directions are different - * the simplified inflate calculation is used for PAD_TRAPEZOID - * due to the complexity of offsetting a polygon with different values in X and Y - * (I even no be sure this has meaning) */ if( GetShape() == PAD_RECT ) { halfsize += aInflateValue; + // Verify if do not deflate more than than size // Only possible for inflate negative values. if( halfsize.x < 0 ) @@ -676,20 +677,23 @@ void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, int aRotat } else { + // Trapezoidal pad: verify delta values delta.x = ( m_DeltaSize.x >> 1 ); delta.y = ( m_DeltaSize.y >> 1 ); + // be sure delta values are not to large - if( (delta.x < 0) && (delta.x <= -halfsize.y)) - delta.x = -halfsize.y+1; - if( (delta.x > 0) && (delta.x >= halfsize.y)) - delta.x = halfsize.y-1; - if( (delta.y < 0) && (delta.y <= -halfsize.x)) - delta.y = -halfsize.x+1; - if( (delta.y > 0) && (delta.y >= halfsize.x)) - delta.y = halfsize.x-1; + if( (delta.x < 0) && (delta.x <= -halfsize.y) ) + delta.x = -halfsize.y + 1; + if( (delta.x > 0) && (delta.x >= halfsize.y) ) + delta.x = halfsize.y - 1; + if( (delta.y < 0) && (delta.y <= -halfsize.x) ) + delta.y = -halfsize.x + 1; + if( (delta.y > 0) && (delta.y >= halfsize.x) ) + delta.y = halfsize.x - 1; } // Build the basic rectangular or trapezoid shape + // delta is null for rectangular shapes aCoord[0].x = -halfsize.x - delta.y; // lower left aCoord[0].y = +halfsize.y + delta.x; @@ -711,35 +715,40 @@ void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, int aRotat if( delta.y ) // lower and upper segment is horizontal { // Calculate angle of left (or right) segment with vertical axis - angle = atan2( delta.y, halfsize.y ); + angle = atan2( m_DeltaSize.y, m_Size.y ); // left and right sides are moved by aInflateValue.x in their perpendicular direction // We must calculate the corresponding displacement on the horizontal axis // that is delta.x +- corr.x depending on the corner - corr.x = wxRound(tan(angle) * aInflateValue.x); - delta.x = wxRound( aInflateValue.x/cos(angle)); + corr.x = wxRound( tan( angle ) * aInflateValue.x ); + delta.x = wxRound( aInflateValue.x / cos( angle ) ); + // Horizontal sides are moved up and down by aInflateValue.y delta.y = aInflateValue.y; + // corr.y = 0 by the constructor } else if( delta.x ) // left and right segment is vertical { // Calculate angle of lower (or upper) segment with horizontal axis - angle = atan2( delta.x, halfsize.x); + angle = atan2( m_DeltaSize.x, m_Size.x ); + // lower and upper sides are moved by aInflateValue.x in their perpendicular direction // We must calculate the corresponding displacement on the vertical axis // that is delta.y +- corr.y depending on the corner - corr.y = wxRound(tan(angle) * aInflateValue.y); - delta.y = wxRound( aInflateValue.y/cos(angle)); + corr.y = wxRound( tan( angle ) * aInflateValue.y ); + delta.y = wxRound( aInflateValue.y / cos( angle ) ); + // Vertical sides are moved left and right by aInflateValue.x delta.x = aInflateValue.x; + // corr.x = 0 by the constructor - } - else // the trapezoid is a rectangle - { - delta = aInflateValue; // Do nothing. } - aCoord[0].x += -delta.x - corr.x; // lower left + else // the trapezoid is a rectangle + { + delta = aInflateValue; // this pad is rectangular (delta null). + } + aCoord[0].x += -delta.x - corr.x; // lower left aCoord[0].y += delta.y + corr.y; aCoord[1].x += -delta.x + corr.x; // upper left @@ -750,6 +759,21 @@ void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, int aRotat aCoord[3].x += delta.x + corr.x; // lower right aCoord[3].y += delta.y - corr.y; + + /* test coordinates and clamp them if the offset correction is too large: + * Note: if a coordinate is bad, the other "symmetric" coordinate is bad + * So when a bad coordinate is found, the 2 symmetric coordinates + * are set to the minimun value (0) + */ + + if( aCoord[0].x > 0 ) // lower left x coordinate must be <= 0 + aCoord[0].x = aCoord[3].x = 0; + if( aCoord[1].x > 0 ) // upper left x coordinate must be <= 0 + aCoord[1].x = aCoord[2].x = 0; + if( aCoord[0].y < 0 ) // lower left y coordinate must be >= 0 + aCoord[0].y = aCoord[1].y = 0; + if( aCoord[3].y < 0 ) // lower right y coordinate must be >= 0 + aCoord[3].y = aCoord[2].y = 0; } if( aRotation ) diff --git a/pcbnew/dialog_pad_properties.cpp b/pcbnew/dialog_pad_properties.cpp index 9fac671993..0d13a0edd0 100644 --- a/pcbnew/dialog_pad_properties.cpp +++ b/pcbnew/dialog_pad_properties.cpp @@ -119,8 +119,14 @@ void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event ) dc.SetDeviceOrigin( dc_size.x / 2, dc_size.y / 2 ); // Calculate a suitable scale to fit the available draw area - double scale = (double) dc_size.x / (m_dummyPad->m_Size.x + m_dummyPad->m_LocalClearance); - double altscale = (double) dc_size.y / (m_dummyPad->m_Size.y + m_dummyPad->m_LocalClearance); + int dim = m_dummyPad->m_Size.x + ABS( m_dummyPad->m_DeltaSize.y); + if( m_dummyPad->m_LocalClearance > 0 ) + dim += m_dummyPad->m_LocalClearance * 2; + double scale = (double) dc_size.x / dim; + dim = m_dummyPad->m_Size.y + ABS( m_dummyPad->m_DeltaSize.x); + if( m_dummyPad->m_LocalClearance > 0 ) + dim += m_dummyPad->m_LocalClearance * 2; + double altscale = (double) dc_size.y / dim; scale = MIN( scale, altscale ); // Give a margin @@ -212,6 +218,7 @@ void DIALOG_PAD_PROPERTIES::initValues() /* flip pads layers*/ m_dummyPad->m_Masque_Layer = ChangeSideMaskLayer( m_dummyPad->m_Masque_Layer ); } + m_staticTextWarningPadFlipped->Show(m_isFlipped); m_PadNumCtrl->SetValue( m_dummyPad->ReturnStringPadName() ); m_PadNetNameCtrl->SetValue( m_dummyPad->GetNetname() ); diff --git a/pcbnew/dialog_pad_properties_base.cpp b/pcbnew/dialog_pad_properties_base.cpp index cd905c5d2f..c8a429bc6e 100644 --- a/pcbnew/dialog_pad_properties_base.cpp +++ b/pcbnew/dialog_pad_properties_base.cpp @@ -221,12 +221,12 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_panelShowPad = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE|wxSIMPLE_BORDER|wxTAB_TRAVERSAL ); m_panelShowPad->SetBackgroundColour( wxColour( 0, 0, 0 ) ); - bMiddleUpperSizer->Add( m_panelShowPad, 1, wxEXPAND | wxALL, 5 ); + bMiddleUpperSizer->Add( m_panelShowPad, 1, wxEXPAND, 5 ); bMiddleSizer->Add( bMiddleUpperSizer, 1, wxEXPAND, 5 ); wxStaticBoxSizer* sbSizeModuleInfo; - sbSizeModuleInfo = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint orientation") ), wxVERTICAL ); + sbSizeModuleInfo = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Footprint orientation") ), wxHORIZONTAL ); wxFlexGridSizer* fgSizer4; fgSizer4 = new wxFlexGridSizer( 2, 2, 0, 0 ); @@ -240,7 +240,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_staticModuleRotValue = new wxStaticText( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticModuleRotValue->Wrap( -1 ); - fgSizer4->Add( m_staticModuleRotValue, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + fgSizer4->Add( m_staticModuleRotValue, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 ); m_staticTitleModuleSide = new wxStaticText( this, wxID_ANY, _("Board side:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTitleModuleSide->Wrap( -1 ); @@ -248,9 +248,15 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind m_staticModuleSideValue = new wxStaticText( this, wxID_ANY, _("Front side"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticModuleSideValue->Wrap( -1 ); - fgSizer4->Add( m_staticModuleSideValue, 0, wxALL, 5 ); + fgSizer4->Add( m_staticModuleSideValue, 0, wxALL|wxEXPAND, 5 ); - sbSizeModuleInfo->Add( fgSizer4, 0, wxEXPAND, 5 ); + sbSizeModuleInfo->Add( fgSizer4, 1, wxEXPAND, 5 ); + + m_staticTextWarningPadFlipped = new wxStaticText( this, wxID_ANY, _("Warning:\nThis pad is flipped on board.\nBack and front layers will be swapped."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextWarningPadFlipped->Wrap( -1 ); + m_staticTextWarningPadFlipped->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) ); + + sbSizeModuleInfo->Add( m_staticTextWarningPadFlipped, 0, wxALIGN_CENTER_VERTICAL, 5 ); bMiddleSizer->Add( sbSizeModuleInfo, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); diff --git a/pcbnew/dialog_pad_properties_base.fbp b/pcbnew/dialog_pad_properties_base.fbp index 08885f443e..27b1d242c7 100644 --- a/pcbnew/dialog_pad_properties_base.fbp +++ b/pcbnew/dialog_pad_properties_base.fbp @@ -2513,7 +2513,7 @@ 5 - wxEXPAND | wxALL + wxEXPAND 1 0,0,0 @@ -2570,13 +2570,13 @@ Footprint orientation sbSizeModuleInfo - wxVERTICAL + wxHORIZONTAL none 5 wxEXPAND - 0 + 1 2 wxBOTH @@ -2642,7 +2642,7 @@ 5 - wxTOP|wxRIGHT|wxLEFT + wxTOP|wxRIGHT|wxLEFT|wxEXPAND 0 @@ -2744,7 +2744,7 @@ 5 - wxALL + wxALL|wxEXPAND 0 @@ -2795,6 +2795,57 @@ + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + ,90,92,-1,70,0 + 0 + wxID_ANY + Warning: This pad is flipped on board. Back and front layers will be swapped. + + + m_staticTextWarningPadFlipped + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pcbnew/dialog_pad_properties_base.h b/pcbnew/dialog_pad_properties_base.h index 4ed29b7599..38d41b6992 100644 --- a/pcbnew/dialog_pad_properties_base.h +++ b/pcbnew/dialog_pad_properties_base.h @@ -98,6 +98,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public wxDialog wxStaticText* m_staticModuleRotValue; wxStaticText* m_staticTitleModuleSide; wxStaticText* m_staticModuleSideValue; + wxStaticText* m_staticTextWarningPadFlipped; wxStaticText* m_staticTextWarning; wxStaticText* m_staticTextNetClearance; wxTextCtrl* m_NetClearanceValueCtrl;