KiCad PCB EDA Suite
symbdraw.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2006 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2009-2017 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 2004-2017 KiCad Developers, see change_log.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 
31 #include <fctsys.h>
32 #include <class_drawpanel.h>
33 #include <confirm.h>
34 #include <base_units.h>
35 #include <msgpanel.h>
36 
37 #include <eeschema_id.h>
38 #include <lib_edit_frame.h>
39 #include <class_libentry.h>
40 #include <lib_arc.h>
41 #include <lib_circle.h>
42 #include <lib_polyline.h>
43 #include <lib_rectangle.h>
44 #include <lib_text.h>
45 
47 
48 
49 static void SymbolDisplayDraw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
50  bool aErase );
51 static void RedrawWhileMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
52  bool aErase );
53 
54 
55 void LIB_EDIT_FRAME::EditGraphicSymbol( wxDC* DC, LIB_ITEM* DrawItem )
56 {
57  if( DrawItem == NULL )
58  return;
59 
60  LIB_PART* symbol = DrawItem->GetParent();
61 
62  DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem->GetTypeName() );
63 
65 
66  wxString val = StringFromValue( g_UserUnit, DrawItem->GetWidth() );
67  dialog.SetWidth( val );
68  dialog.SetApplyToAllUnits( DrawItem->GetUnit() == 0 );
69  dialog.EnableApplyToAllUnits( symbol && symbol->GetUnitCount() > 1 );
70  dialog.SetApplyToAllConversions( DrawItem->GetConvert() == 0 );
71  bool enblConvOptStyle = symbol && symbol->HasConversion();
72  // if a symbol contains no graphic items, symbol->HasConversion() returns false.
73  // but when creating a new symbol, with DeMorgan option set, the ApplyToAllConversions
74  // must be enabled even if symbol->HasConversion() returns false in order to be able
75  // to create graphic items shared by all body styles
76  if( GetShowDeMorgan() )
77  enblConvOptStyle = true;
78 
79  dialog.EnableApplyToAllConversions( enblConvOptStyle );
80  dialog.SetFillStyle( DrawItem->GetFillMode() );
81  dialog.EnableFillStyle( DrawItem->IsFillable() );
82 
83  if( dialog.ShowModal() == wxID_CANCEL )
84  return;
85 
86  // Init default values (used to create a new draw item)
87  val = dialog.GetWidth();
89  m_drawSpecificConvert = !dialog.GetApplyToAllConversions();
90  m_drawSpecificUnit = !dialog.GetApplyToAllUnits();
91 
92 #if 0
93  /* TODO: see if m_drawFillStyle must retain the last fill option or not.
94  * if the last is Filled, having next new graphic items created
95  * with filled body is often bad.
96  * currently m_drawFillStyle is left with the default value (not filled)
97  */
98  if( DrawItem->IsFillable() )
99  m_drawFillStyle = (FILL_T) dialog.GetFillStyle();
100 #endif
101 
102  // Save copy for undo if not in edit (edit command already handle the save copy)
103  if( !DrawItem->InEditMode() )
104  SaveCopyInUndoList( DrawItem->GetParent() );
105 
106  if( m_drawSpecificUnit )
107  DrawItem->SetUnit( GetUnit() );
108  else
109  DrawItem->SetUnit( 0 );
110 
112  DrawItem->SetConvert( GetConvert() );
113  else
114  DrawItem->SetConvert( 0 );
115 
116  if( DrawItem->IsFillable() )
117  DrawItem->SetFillMode( (FILL_T) dialog.GetFillStyle() );
118 
119  DrawItem->SetWidth( m_drawLineWidth );
120 
121  OnModify( );
122 
123  MSG_PANEL_ITEMS items;
124  DrawItem->GetMsgPanelInfo( items );
125  SetMsgPanel( items );
126  m_canvas->Refresh();
127 }
128 
129 
130 static void AbortSymbolTraceOn( EDA_DRAW_PANEL* Panel, wxDC* DC )
131 {
132  LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) Panel->GetParent();
133  LIB_ITEM* item = parent->GetDrawItem();
134 
135  if( item == NULL )
136  return;
137 
138  bool newItem = item->IsNew();
139  item->EndEdit( parent->GetCrossHairPosition( true ), true );
140 
141  if( newItem )
142  {
143  delete item;
144  }
145  else
146  parent->RestoreComponent();
147 
148  parent->SetDrawItem( NULL );
149  Panel->Refresh();
150 }
151 
152 
154 {
155  LIB_ITEM* item = GetDrawItem();
157  wxPoint drawPos = GetCrossHairPosition( true );
158 
159  // no temp copy -> the current version of symbol will be used for Undo
160  // This is normal when adding new items to the current symbol
162 
163  switch( GetToolId() )
164  {
166  item = new LIB_ARC( LibEntry );
167  break;
168 
170  item = new LIB_CIRCLE( LibEntry );
171  break;
172 
174  item = new LIB_RECTANGLE( LibEntry );
175  break;
176 
178  item = new LIB_POLYLINE( LibEntry );
179  break;
180 
182  {
183  LIB_TEXT* text = new LIB_TEXT( LibEntry );
184  text->SetTextSize( wxSize( m_textSize, m_textSize ) );
186 
187  // Enter the graphic text info
189  EditSymbolText( NULL, text );
190 
191  m_canvas->SetIgnoreMouseEvents( false );
193 
194  if( text->GetText().IsEmpty() )
195  {
196  delete text;
197  item = NULL;
198  }
199  else
200  {
201  item = text;
202  }
203  }
204  break;
205 
206  default:
207  DisplayError( this, wxT( "LIB_EDIT_FRAME::CreateGraphicItem() error" ) );
208  return NULL;
209  }
210 
211  if( item )
212  {
213  item->BeginEdit( IS_NEW, drawPos );
214 
215  // Don't set line parameters for text objects.
216  if( item->Type() != LIB_TEXT_T )
217  {
218  item->SetWidth( m_drawLineWidth );
219  item->SetFillMode( m_drawFillStyle );
220  }
221 
222  if( m_drawSpecificUnit )
223  item->SetUnit( m_unit );
224 
226  item->SetConvert( m_convert );
227 
228  // Draw initial symbol:
229  m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
230  }
231  else
232  {
234  return NULL;
235  }
236 
238  m_canvas->SetIgnoreMouseEvents( false );
239  SetDrawItem( item );
240 
241  return item;
242 }
243 
244 
246 {
247  if( GetDrawItem() == NULL )
248  return;
249 
250  wxPoint pos = GetCrossHairPosition( true );
251 
252  if( GetDrawItem()->ContinueEdit( pos ) )
253  {
254  GetDrawItem()->Draw( m_canvas, DC, pos, COLOR4D::UNSPECIFIED, g_XorMode, NULL,
256  return;
257  }
258 
259  EndDrawGraphicItem( DC );
260 }
261 
262 
263 /*
264  * Redraw the graphic shape while moving
265  */
266 static void RedrawWhileMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
267  bool aErase )
268 {
269  LIB_ITEM* item;
270 
271  item = ( (LIB_EDIT_FRAME*) aPanel->GetParent() )->GetDrawItem();
272 
273  if( item == NULL )
274  return;
275 
276  item->SetEraseLastDrawItem( aErase );
277 
278  // if item is the reference field, we must add the current unit id
279  if( item->Type() == LIB_FIELD_T )
280  {
281  int unit = ((LIB_EDIT_FRAME*)aPanel->GetParent())->GetUnit();
282  wxString text = ((LIB_FIELD*)item)->GetFullText( unit );
283 
284  item->Draw( aPanel, aDC, aPanel->GetParent()->GetCrossHairPosition( true ),
285  COLOR4D::UNSPECIFIED, g_XorMode, &text,
287  }
288  else
289  item->Draw( aPanel, aDC, aPanel->GetParent()->GetCrossHairPosition( true ),
290  COLOR4D::UNSPECIFIED, g_XorMode, NULL,
292 }
293 
294 
296 {
297  if( aItem == NULL )
298  return;
299 
300  SetCursor( wxCURSOR_HAND );
301 
303 
304  // For fields only, move the anchor point of the field
305  // to the cursor position to allow user to see the text justification
306  if( aItem->Type() == LIB_FIELD_T )
307  aItem->BeginEdit( IS_MOVED, aItem->GetPosition() );
308  else
309  aItem->BeginEdit( IS_MOVED, GetCrossHairPosition( true ) );
310 
312  m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
313 }
314 
315 
317 {
318  if( aItem == NULL )
319  return;
320 
322  aItem->BeginEdit( IS_RESIZED, GetCrossHairPosition( true ) );
324  m_canvas->CallMouseCapture( DC, wxDefaultPosition, true );
325 }
326 
327 
329 static void SymbolDisplayDraw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
330  bool aErase )
331 {
332  LIB_ITEM* item = ( (LIB_EDIT_FRAME*) aPanel->GetParent() )->GetDrawItem();
333 
334  if( item == NULL )
335  return;
336 
337  item->SetEraseLastDrawItem( aErase );
338  item->Draw( aPanel, aDC, aPanel->GetParent()->GetCrossHairPosition( true ),
339  COLOR4D::UNSPECIFIED, g_XorMode, NULL, DefaultTransform );
340 }
341 
342 
344 {
345  LIB_ITEM* item = GetDrawItem();
346 
347  if( item == NULL )
348  return;
349 
350  if( LIB_PART* part = GetCurPart() )
351  {
352  if( GetToolId() != ID_NO_TOOL_SELECTED )
353  SetCursor( wxCURSOR_PENCIL );
354  else
355  SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() );
356 
357  if( GetTempCopyComponent() ) // used when editing an existing item
359  else
360  {
361  // When creating a new item, there is still no change for the
362  // current symbol. So save it.
363  SaveCopyInUndoList( part );
364  }
365 
366  if( item->IsNew() )
367  part->AddDrawItem( item );
368 
369  item->EndEdit( GetCrossHairPosition( true ) );
370 
371  SetDrawItem( NULL );
372 
373  OnModify();
374 
375  m_canvas->SetMouseCapture( NULL, NULL );
376  m_canvas->Refresh();
377  }
378 }
void SetTextAngle(double aAngle)
Definition: eda_text.h:154
virtual wxPoint GetPosition() const =0
Return the current draw object position.
GR_DRAWMODE g_XorMode
Definition: gr_basic.cpp:73
KICAD_T Type() const
Function Type()
Definition: base_struct.h:209
static double m_current_text_angle
Current text angle setting.
static void RedrawWhileMovingCursor(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Definition: symbdraw.cpp:266
FILL_T GetFillMode() const
bool HasConversion() const
Test if part has more than one body conversion type (DeMorgan).
static int m_convert
void RestoreComponent()
Restore the current edited component from its temporary copy.
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Update the board display after modifying it bu a python script (note: it is automatically called by a...
Definition: draw_panel.cpp:338
void SetEraseLastDrawItem(bool aErase=true)
int GetUnit() const
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
bool IsNew() const
Definition: base_struct.h:227
Define a symbol library graphical text item.
Definition: lib_text.h:44
void ClearTempCopyComponent()
Delete temporary copy of the current component and clear pointer.
virtual void BeginEdit(STATUS_FLAGS aEditMode, const wxPoint aPosition=wxPoint(0, 0))
Begin an editing a component library draw item in aEditMode at aPosition.
wxString ReturnUnitSymbol(EDA_UNITS_T aUnit, const wxString &formatString)
Returns the units symbol.
Definition: base_units.cpp:426
virtual void SetWidth(int aWidth)=0
Set the width of the draw item to aWidth.
Subclass of DIALOG_LIB_EDIT_DRAW_ITEM_BASE, which is generated by wxFormBuilder.
wxString StringFromValue(EDA_UNITS_T aUnit, int aValue, bool aAddUnitSymbol)
Function StringFromValue returns the string from aValue according to units (inch, mm ...
Definition: base_units.cpp:205
Field object used in symbol libraries.
Definition: lib_field.h:59
virtual void EndEdit(const wxPoint &aPosition, bool aAbort=false)
End an object editing action.
void EndMouseCapture(int aId=-1, int aCursorId=-1, const wxString &aTitle=wxEmptyString, bool aCallEndFunc=true)
Function EndMouseCapture ends mouse a capture.
bool InEditMode() const
Return the draw item editing mode status.
void OnModify()
Must be called after a schematic change in order to set the "modify" flag of the current screen...
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:212
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:360
void StartMoveDrawSymbol(wxDC *DC, LIB_ITEM *aItem)
Definition: symbdraw.cpp:295
The base class for drawable items used by schematic library components.
Definition: lib_draw_item.h:66
#define IS_NEW
New item, just created.
Definition: base_struct.h:109
void StartModifyDrawSymbol(wxDC *DC, LIB_ITEM *aItem)
Definition: symbdraw.cpp:316
LIB_PART * GetParent() const
LIB_PART * GetCurPart() const
Return the current part being edited or NULL if none selected.
void SetDrawItem(LIB_ITEM *drawItem)
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
Definition: draw_frame.cpp:832
Class LIB_ITEM definition.
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:128
void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
void TempCopyComponent()
Create a temporary copy of the current edited component.
void GraphicItemBeginDraw(wxDC *DC)
Definition: symbdraw.cpp:245
int ValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application...
Definition: base_units.cpp:370
Define a library symbol object.
EDA_DRAW_FRAME * GetParent() const
Definition: draw_panel.cpp:180
static int m_textSize
The current text size setting.
static void AbortSymbolTraceOn(EDA_DRAW_PANEL *Panel, wxDC *DC)
Definition: symbdraw.cpp:130
void SetFillMode(FILL_T aFillMode)
void SetWidthUnits(const wxString &units)
LIB_PART * GetTempCopyComponent()
void SetConvert(int aConvert)
int GetUnitCount() const
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:57
void EditSymbolText(wxDC *DC, LIB_ITEM *DrawItem)
Dialog to edit library component graphic items.
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:98
virtual int GetWidth() const =0
Return the width of the draw item.
void SetUnit(int aUnit)
virtual void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
The symbol library editor main window.
LIB_ITEM * CreateGraphicItem(LIB_PART *LibEntry, wxDC *DC)
Definition: symbdraw.cpp:153
TRANSFORM DefaultTransform
Definition: eeschema.cpp:58
bool GetShowDeMorgan()
virtual void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aOffset, COLOR4D aColor, GR_DRAWMODE aDrawMode, void *aData, const TRANSFORM &aTransform)
Draw an item.
static int m_unit
int GetToolId() const
Definition: draw_frame.h:488
static FILL_T m_drawFillStyle
The current draw or edit graphic item fill style.
void SaveCopyInUndoList(EDA_ITEM *ItemToCopy, UNDO_REDO_T undoType=UR_LIBEDIT)
Create a copy of the current component, and save it in the undo list.
void EndDrawGraphicItem(wxDC *DC)
Definition: symbdraw.cpp:343
virtual wxString GetTypeName()=0
Provide a user-consumable name of the object type.
LIB_ITEM * GetDrawItem() const
void SetIgnoreMouseEvents(bool aIgnore)
static void SymbolDisplayDraw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, const wxPoint &aPosition, bool aErase)
Manage mouse events when creating new graphic object or modifying an graphic object.
Definition: symbdraw.cpp:329
void EditGraphicSymbol(wxDC *DC, LIB_ITEM *DrawItem)
Definition: symbdraw.cpp:55
#define IS_RESIZED
Item being resized.
Definition: base_struct.h:110
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
bool IsFillable() const
Check if draw object can be filled.
FILL_T
Enum FILL_T is the set of fill types used in plotting or drawing enclosed areas.
Definition: base_struct.h:52
Definition of class LIB_EDIT_FRAME.
static int m_drawLineWidth
Default line width for drawing or editing graphic items.
bool m_drawSpecificConvert
Convert of the item currently being drawn.
void SetMouseCapture(MOUSE_CAPTURE_CALLBACK aMouseCaptureCallback, END_MOUSE_CAPTURE_CALLBACK aEndMouseCaptureCallback)
Function SetMouseCapture sets the mouse capture and end mouse capture callbacks to aMouseCaptureCallb...
bool m_drawSpecificUnit
Specify which component parts the current draw item applies to.
Message panel definition file.
int GetDefaultCursor() const
Function GetDefaultCursor.
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:185
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
int GetConvert() const
#define IS_MOVED
Item being moved.
Definition: base_struct.h:108