1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras at wanadoo.fr
5  * Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24  */
25 
26 
27 #ifndef CLASS_PIN_H
28 #define CLASS_PIN_H
29 
30 #include <eda_rect.h>
31 #include <lib_item.h>
32 #include <pin_type.h>
33 #include <lib_symbol.h>
34 
35 // Circle diameter drawn at the active end of pins:
36 #define TARGET_PIN_RADIUS   Mils2iu( 15 )
37 
38 // Pin visibility flag bit:
39 #define PIN_INVISIBLE 1    // Set makes pin invisible
40 
41 
42 /**
43  *  The symbol library pin object orientations.
44  */
45 enum DrawPinOrient {
46     PIN_RIGHT = 'R',
47     PIN_LEFT  = 'L',
48     PIN_UP    = 'U',
49     PIN_DOWN  = 'D'
50 };
51 
52 
53 class LIB_PIN : public LIB_ITEM
54 {
55 public:
56     struct ALT
57     {
58         wxString            m_Name;
59         GRAPHIC_PINSHAPE    m_Shape;         // Shape drawn around pin
60         ELECTRICAL_PINTYPE  m_Type;          // Electrical type of the pin.
61     };
62 
~LIB_PIN()63     ~LIB_PIN() { }
64 
GetClass()65     wxString GetClass() const override
66     {
67         return wxT( "LIB_PIN" );
68     }
69 
GetTypeName()70     wxString GetTypeName() const override
71     {
72         return _( "Pin" );
73     }
74 
GetOrientation()75     int GetOrientation() const { return m_orientation; }
SetOrientation(int aOrientation)76     void SetOrientation( int aOrientation ) { m_orientation = aOrientation; }
77 
GetShape()78     GRAPHIC_PINSHAPE GetShape() const { return m_shape; }
SetShape(GRAPHIC_PINSHAPE aShape)79     void SetShape( GRAPHIC_PINSHAPE aShape ) { m_shape = aShape; }
80 
GetLength()81     int GetLength() const { return m_length; }
SetLength(int aLength)82     void SetLength( int aLength ) { m_length = aLength; }
83 
GetType()84     ELECTRICAL_PINTYPE GetType() const { return m_type; }
SetType(ELECTRICAL_PINTYPE aType)85     void SetType( ELECTRICAL_PINTYPE aType ) { m_type = aType; }
86 
GetCanonicalElectricalTypeName()87     wxString const GetCanonicalElectricalTypeName() const
88     {
89         return GetCanonicalElectricalTypeName( m_type );
90     }
91 
GetElectricalTypeName()92     wxString const GetElectricalTypeName() const
93     {
94         return ElectricalPinTypeGetText( m_type );
95     }
96 
IsVisible()97     bool IsVisible() const { return ( m_attributes & PIN_INVISIBLE ) == 0; }
SetVisible(bool aVisible)98     void SetVisible( bool aVisible )
99     {
100         if( aVisible )
101             m_attributes &= ~PIN_INVISIBLE;
102         else
103             m_attributes |= PIN_INVISIBLE;
104     }
105 
GetName()106     const wxString& GetName() const { return m_name; }
107     wxString GetShownName() const;
SetName(const wxString & aName)108     void SetName( const wxString& aName )
109     {
110         m_name = aName;
111 
112         // pin name string does not support spaces
113         m_name.Replace( wxT( " " ), wxT( "_" ) );
114     }
115 
GetNumber()116     const wxString& GetNumber() const { return m_number; }
GetShownNumber()117     wxString GetShownNumber() const { return m_number; }
SetNumber(const wxString & aNumber)118     void SetNumber( const wxString& aNumber )
119     {
120         m_number = aNumber;
121 
122         // pin number string does not support spaces
123         m_number.Replace( wxT( " " ), wxT( "_" ) );
124     }
125 
GetNameTextSize()126     int GetNameTextSize() const { return m_nameTextSize; }
SetNameTextSize(int aSize)127     void SetNameTextSize( int aSize ) { m_nameTextSize = aSize; }
128 
GetNumberTextSize()129     int GetNumberTextSize() const { return m_numTextSize; }
SetNumberTextSize(int aSize)130     void SetNumberTextSize( int aSize ) { m_numTextSize = aSize; }
131 
GetAlternates()132     std::map<wxString, ALT>& GetAlternates() { return m_alternates; }
133 
GetAlt(const wxString & aAlt)134     ALT GetAlt( const wxString& aAlt ) { return m_alternates[ aAlt ]; }
135 
136     /**
137      * Print a pin, with or without the pin texts
138      *
139      * @param aOffset Offset to draw
140      * @param aData = used here as a boolean indicating whether or not to draw the pin
141      *                electrical types
142      * @param aTransform Transform Matrix (rotation, mirror ..)
143      */
144     void print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData,
145                 const TRANSFORM& aTransform ) override;
146 
147     /**
148      * Return the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT),
149      * according to its orientation and the matrix transform (rot, mirror) \a aTransform.
150      *
151      * @param aTransform Transform matrix
152      */
153     int PinDrawOrient( const TRANSFORM& aTransform ) const;
154 
155     LIB_PIN( LIB_SYMBOL* aParent );
156 
157     LIB_PIN( LIB_SYMBOL* aParent, const wxString& aName, const wxString& aNumber, int aOrientation,
158              ELECTRICAL_PINTYPE aPinType, int aLength, int aNameTextSize, int aNumTextSize,
159              int aConvert, const wxPoint& aPos, int aUnit );
160 
161     // Do not create a copy constructor.  The one generated by the compiler is adequate.
162 
163 #if defined(DEBUG)
164     void Show( int nestLevel, std::ostream& os ) const override;
165 #endif
166 
167     bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
168 
169     bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
170 
171     void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
172 
173     /* Cannot use a default parameter here as it will not be compatible with the virtual. */
GetBoundingBox()174     const EDA_RECT GetBoundingBox() const override { return GetBoundingBox( false ); }
175 
176     /**
177      * @param aIncludeInvisibles - if false, do not include labels for invisible pins
178      *      in the calculation.
179      */
180     const EDA_RECT GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly = false ) const;
181 
182     /**
183      * Return whether this pin forms an implicit power connection: i.e., is hidden
184      * and of type POWER_IN.
185      */
IsPowerConnection()186     bool IsPowerConnection() const
187     {
188         return GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN
189                && ( !IsVisible() || (LIB_SYMBOL*) GetParent()->IsPower() );
190     }
191 
192     int GetPenWidth() const override;
193 
194     /**
195      * Plot the pin number and pin text info, given the pin line coordinates.
196      * Same as DrawPinTexts((), but output is the plotter
197      * The line must be vertical or horizontal.
198      * If TextInside then the text is been put inside (moving from x1, y1 in
199      * the opposite direction to x2,y2), otherwise all is drawn outside.
200      */
201     void PlotPinTexts( PLOTTER *aPlotter, const wxPoint& aPinPos, int aPinOrient,
202                        int aTextInside, bool aDrawPinNum, bool aDrawPinName ) const;
203 
204     void PlotSymbol( PLOTTER* aPlotter, const wxPoint& aPosition, int aOrientation ) const;
205 
206     void Offset( const wxPoint& aOffset ) override;
207 
208     void MoveTo( const wxPoint& aNewPosition ) override;
209 
GetPosition()210     wxPoint GetPosition() const override { return m_position; }
SetPosition(const wxPoint & aPos)211     void SetPosition( const wxPoint& aPos ) override { m_position = aPos; }
212 
213     wxPoint GetPinRoot() const;
214 
215     void MirrorHorizontal( const wxPoint& aCenter ) override;
216     void MirrorVertical( const wxPoint& aCenter ) override;
217     void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) override;
218 
219     void Plot( PLOTTER* aPlotter, const wxPoint& aPffset, bool aFill,
220                const TRANSFORM& aTransform ) const override;
221 
222     BITMAPS GetMenuImage() const override;
223 
224     wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
225 
226     EDA_ITEM* Clone() const override;
227 
228     void CalcEdit( const wxPoint& aPosition ) override;
229 
230     /**
231      * Return a string giving the electrical type of a pin.
232      *
233      * Can be used when a known, not translated name is needed (for instance in net lists)
234      *
235      * @param aType is the electrical type (see enum ELECTRICAL_PINTYPE )
236      * @return The electrical name for a pin type (see enun MsgPinElectricType for names).
237      */
238     static const wxString GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType );
239 
240 protected:
241     /**
242      * Print the pin symbol without text.
243      * If \a aColor != 0, draw with \a aColor, else with the normal pin color.
244      */
245     void printPinSymbol( const RENDER_SETTINGS* aSettings, const wxPoint& aPos, int aOrientation );
246 
247     /**
248      * Put the pin number and pin text info, given the pin line coordinates.
249      * The line must be vertical or horizontal.
250      * If aDrawPinName == false the pin name is not printed.
251      * If aDrawPinNum = false the pin number is not printed.
252      * If aTextInside then the text is been put inside,otherwise all is drawn outside.
253      * Pin Name:    substring between '~' is negated
254      */
255     void printPinTexts( const RENDER_SETTINGS* aSettings, wxPoint& aPinPos, int aPinOrient,
256                         int aTextInside, bool aDrawPinNum, bool aDrawPinName );
257 
258     /**
259      * Draw the electrical type text of the pin (only for the footprint editor)
260      */
261     void printPinElectricalTypeName( const RENDER_SETTINGS* aSettings, wxPoint& aPosition,
262                                      int aOrientation );
263 
264 private:
265     /**
266      * @copydoc LIB_ITEM::compare()
267      *
268      * The pin specific sort order is as follows:
269      *      - Pin number.
270      *      - Pin name, case insensitive compare.
271      *      - Pin horizontal (X) position.
272      *      - Pin vertical (Y) position.
273      */
274     int compare( const LIB_ITEM& aOther,
275             LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const override;
276 
277 protected:
278     wxPoint                 m_position;      // Position of the pin.
279     int                     m_length;        // Length of the pin.
280     int                     m_orientation;   // Pin orientation (Up, Down, Left, Right)
281     GRAPHIC_PINSHAPE        m_shape;         // Shape drawn around pin
282     ELECTRICAL_PINTYPE      m_type;          // Electrical type of the pin.
283     int                     m_attributes;    // Set bit 0 to indicate pin is invisible.
284     wxString                m_name;
285     wxString                m_number;
286     int                     m_numTextSize;   // Pin num and Pin name sizes
287     int                     m_nameTextSize;
288 
289     std::map<wxString, ALT> m_alternates;    // Map of alternate name to ALT structure
290 };
291 
292 
293 #endif  //  CLASS_PIN_H
294