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 #ifndef _LIB_ITEM_H_
27 #define _LIB_ITEM_H_
28 
29 #include <eda_item.h>
30 #include <eda_rect.h>
31 #include <eda_shape.h>
32 #include <transform.h>
33 #include <render_settings.h>
34 
35 class LINE_READER;
36 class OUTPUTFORMATTER;
37 class LIB_SYMBOL;
38 class PLOTTER;
39 class LIB_PIN;
40 class MSG_PANEL_ITEM;
41 
42 using KIGFX::RENDER_SETTINGS;
43 
44 extern const int fill_tab[];
45 
46 
47 #define MINIMUM_SELECTION_DISTANCE 2 // Minimum selection distance in internal units
48 
49 
50 /**
51  * Helper for defining a list of pin object pointers.  The list does not
52  * use a Boost pointer class so the object pointers do not accidentally get
53  * deleted when the container is deleted.
54  */
55 typedef std::vector< LIB_PIN* > LIB_PINS;
56 
57 
58 /**
59  * The base class for drawable items used by schematic library symbols.
60  */
61 class LIB_ITEM : public EDA_ITEM
62 {
63 public:
64     LIB_ITEM( KICAD_T aType, LIB_SYMBOL* aSymbol = nullptr, int aUnit = 0, int aConvert = 0 );
65 
66     // Do not create a copy constructor.  The one generated by the compiler is adequate.
67 
~LIB_ITEM()68     virtual ~LIB_ITEM() { }
69 
70     // Define the enums for basic
71     enum LIB_CONVERT : int  { BASE = 1, DEMORGAN = 2 };
72 
73     /**
74      * The list of flags used by the #compare function.
75      *
76      * - NORMAL This compares everything between two #LIB_ITEM objects.
77      * - UNIT This compare flag ignores unit and convert and pin number information when
78      *        comparing #LIB_ITEM objects for unit comparison.
79      */
80     enum COMPARE_FLAGS : int { NORMAL = 0x00, UNIT = 0x01, EQUALITY = 0x02 };
81 
82     /**
83      * Provide a user-consumable name of the object type.  Perform localization when
84      * called so that run-time language selection works.
85      */
86     virtual wxString GetTypeName() const = 0;
87 
88     /**
89      * Begin drawing a symbol library draw item at \a aPosition.
90      *
91      * It typically would be called on a left click when a draw tool is selected in
92      * the symbol library editor and one of the graphics tools is selected.
93      *
94      * @param aPosition The position in drawing coordinates where the drawing was started.
95      *                  May or may not be required depending on the item being drawn.
96      */
BeginEdit(const wxPoint & aPosition)97     virtual void BeginEdit( const wxPoint& aPosition ) {}
98 
99     /**
100      * Continue an edit in progress at \a aPosition.
101      *
102      * This is used to perform the next action while drawing an item.  This would be
103      * called for each additional left click when the mouse is captured while the item
104      * is being drawn.
105      *
106      * @param aPosition The position of the mouse left click in drawing coordinates.
107      * @return True if additional mouse clicks are required to complete the edit in progress.
108      */
ContinueEdit(const wxPoint & aPosition)109     virtual bool ContinueEdit( const wxPoint& aPosition ) { return false; }
110 
111     /**
112      * End an object editing action.
113      *
114      * This is used to end or abort an edit action in progress initiated by BeginEdit().
115      */
EndEdit()116     virtual void EndEdit() {}
117 
118     /**
119      * Calculate the attributes of an item at \a aPosition when it is being edited.
120      *
121      * This method gets called by the Draw() method when the item is being edited.  This
122      * probably should be a pure virtual method but bezier curves are not yet editable in
123      * the symbol library editor.  Therefore, the default method does nothing.
124      *
125      * @param aPosition The current mouse position in drawing coordinates.
126      */
CalcEdit(const wxPoint & aPosition)127     virtual void CalcEdit( const wxPoint& aPosition ) {}
128 
129     /**
130      * Draw an item
131      *
132      * @param aDC Device Context (can be null)
133      * @param aOffset Offset to draw
134      * @param aData Value or pointer used to pass others parameters, depending on body items.
135      *              Used for some items to force to force no fill mode ( has meaning only for
136      *              items what can be filled ). used in printing or moving objects mode or to
137      *              pass reference to the lib symbol for pins.
138      * @param aTransform Transform Matrix (rotation, mirror ..)
139      */
140     virtual void Print( const RENDER_SETTINGS* aSettings, const wxPoint &aOffset,
141                         void* aData, const TRANSFORM& aTransform );
142 
143     virtual int GetPenWidth() const = 0;
144 
GetEffectivePenWidth(const RENDER_SETTINGS * aSettings)145     virtual int GetEffectivePenWidth( const RENDER_SETTINGS* aSettings ) const
146     {
147         // For historical reasons, a stored value of 0 means "default width" and negative
148         // numbers meant "don't stroke".
149 
150         if( GetPenWidth() <= 0 )
151             return aSettings->GetDefaultPenWidth();
152         else
153             return std::max( GetPenWidth(), aSettings->GetMinPenWidth() );
154     }
155 
GetParent()156     LIB_SYMBOL* GetParent() const
157     {
158         return (LIB_SYMBOL*) m_parent;
159     }
160 
161     void ViewGetLayers( int aLayers[], int& aCount ) const override;
162 
163     bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override
164     {
165         // This is just here to prevent annoying compiler warnings about hidden overloaded
166         // virtual functions
167         return EDA_ITEM::HitTest( aPosition, aAccuracy );
168     }
169 
170     bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
171 
172     /**
173      * @return the boundary box for this, in library coordinates
174      */
GetBoundingBox()175     const EDA_RECT GetBoundingBox() const override { return EDA_ITEM::GetBoundingBox(); }
176 
177     /**
178      * Display basic info (type, part and convert) about the current item in message panel.
179      * <p>
180      * This base function is used to display the information common to the
181      * all library items.  Call the base class from the derived class or the
182      * common information will not be updated in the message panel.
183      * </p>
184      * @param aList is the list to populate.
185      */
186     void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
187 
188     /**
189      * Test LIB_ITEM objects for equivalence.
190      *
191      * @param aOther Object to test against.
192      * @return True if object is identical to this object.
193      */
194     bool operator==( const LIB_ITEM& aOther ) const;
195     bool operator==( const LIB_ITEM* aOther ) const
196     {
197         return *this == *aOther;
198     }
199 
200     /**
201      * Test if another draw item is less than this draw object.
202      *
203      * @param aOther - Draw item to compare against.
204      * @return - True if object is less than this object.
205      */
206     bool operator<( const LIB_ITEM& aOther) const;
207 
208     /**
209      * Set the drawing object by \a aOffset from the current position.
210      *
211      * @param aOffset Coordinates to offset the item position.
212      */
213     virtual void Offset( const wxPoint& aOffset ) = 0;
214 
215     /**
216      * Move a draw object to \a aPosition.
217      *
218      * @param aPosition Position to move draw item to.
219      */
220     virtual void MoveTo( const wxPoint& aPosition ) = 0;
221 
SetPosition(const wxPoint & aPosition)222     void SetPosition( const wxPoint& aPosition ) override { MoveTo( aPosition ); }
223 
224     /**
225      * Mirror the draw object along the horizontal (X) axis about \a aCenter point.
226      *
227      * @param aCenter Point to mirror around.
228      */
229     virtual void MirrorHorizontal( const wxPoint& aCenter ) = 0;
230 
231     /**
232      * Mirror the draw object along the MirrorVertical (Y) axis about \a aCenter point.
233      *
234      * @param aCenter Point to mirror around.
235      */
236     virtual void MirrorVertical( const wxPoint& aCenter ) = 0;
237 
238     /**
239      * Rotate the object about \a aCenter point.
240      *
241      * @param aCenter Point to rotate around.
242      * @param aRotateCCW True to rotate counter clockwise.  False to rotate clockwise.
243      */
244     virtual void Rotate( const wxPoint& aCenter, bool aRotateCCW = true ) = 0;
245 
246     /**
247      * Plot the draw item using the plot object.
248      *
249      * @param aPlotter The plot object to plot to.
250      * @param aOffset Plot offset position.
251      * @param aFill Flag to indicate whether or not the object is filled.
252      * @param aTransform The plot transform.
253      */
254     virtual void Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
255                        const TRANSFORM& aTransform ) const = 0;
256 
SetUnit(int aUnit)257     void SetUnit( int aUnit ) { m_unit = aUnit; }
GetUnit()258     int GetUnit() const { return m_unit; }
259 
SetConvert(int aConvert)260     void SetConvert( int aConvert ) { m_convert = aConvert; }
GetConvert()261     int GetConvert() const { return m_convert; }
262 
263 #if defined(DEBUG)
Show(int nestLevel,std::ostream & os)264     void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
265 #endif
266 
267 protected:
268     /**
269      * Provide the draw object specific comparison called by the == and < operators.
270      *
271      * The base object sort order which always proceeds the derived object sort order
272      * is as follows:
273      *      - Symbol alternate part (DeMorgan) number.
274      *      - Symbol part number.
275      *      - KICAD_T enum value.
276      *      - Result of derived classes comparison.
277      *
278      * @note Make sure you call down to #LIB_ITEM::compare before doing any derived object
279      *       comparisons or you will break the sorting using the symbol library file format.
280      *
281      * @param aOther A reference to the other #LIB_ITEM to compare the arc against.
282      * @param aCompareFlags The flags used to perform the comparison.
283      *
284      * @return An integer value less than 0 if the object is less than \a aOther object,
285      *         zero if the object is equal to \a aOther object, or greater than 0 if the
286      *         object is greater than \a aOther object.
287      */
288     virtual int compare( const LIB_ITEM& aOther,
289             LIB_ITEM::COMPARE_FLAGS aCompareFlags = LIB_ITEM::COMPARE_FLAGS::NORMAL ) const;
290 
291     /**
292      * Print the item to \a aDC.
293      *
294      * @param aOffset A reference to a wxPoint object containing the offset where to draw
295      *                from the object's current position.
296      * @param aData A pointer to any object specific data required to perform the draw.
297      * @param aTransform A reference to a #TRANSFORM object containing drawing transform.
298      */
299     virtual void print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData,
300                         const TRANSFORM& aTransform ) = 0;
301 
302 private:
303     friend class LIB_SYMBOL;
304 
305 protected:
306     /**
307      * Unit identification for multiple parts per package.  Set to 0 if the item is common
308      * to all units.
309      */
310     int         m_unit;
311 
312     /**
313      * Shape identification for alternate body styles.  Set 0 if the item is common to all
314      * body styles.  This is typially used for representing DeMorgan variants in KiCad.
315      */
316     int         m_convert;
317 };
318 
319 
320 #endif  //  _LIB_ITEM_H_
321